diff --git a/.eslintignore b/.eslintignore
deleted file mode 100644
index ee0f302..0000000
--- a/.eslintignore
+++ /dev/null
@@ -1,6 +0,0 @@
-dist
-node_modules
-packages/github-action/*
-packages/worker/bin/*
-packages/worker/config/*
-packages/dashboard/quasar.config.js
diff --git a/.eslintrc b/.eslintrc
deleted file mode 100644
index d323a75..0000000
--- a/.eslintrc
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "root": true,
- "parserOptions": {
- "ecmaVersion": "latest",
- "sourceType": "module"
- },
- "env": {
- "browser": true,
- "es6": true,
- "node": true
- },
- "extends": [
- "typescript",
- "prettier"
- ],
- "ignorePatterns": [],
- "rules": {
- "@typescript-eslint/ban-ts-comment": "off",
- "@typescript-eslint/no-explicit-any": "off",
- "@typescript-eslint/no-var-requires": "off",
- "@typescript-eslint/no-unused-vars": "warn"
- }
-}
diff --git a/.npmrc b/.npmrc
deleted file mode 100644
index 13833b4..0000000
--- a/.npmrc
+++ /dev/null
@@ -1,3 +0,0 @@
-git-checks=false
-shamefully-hoist=true
-auto-install-peers=true
diff --git a/biome.json b/biome.json
new file mode 100644
index 0000000..96c7588
--- /dev/null
+++ b/biome.json
@@ -0,0 +1,45 @@
+{
+ "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
+ "vcs": {
+ "enabled": false,
+ "clientKind": "git",
+ "useIgnoreFile": false
+ },
+ "files": {
+ "ignoreUnknown": false,
+ "ignore": []
+ },
+ "formatter": {
+ "enabled": true,
+ "indentStyle": "tab"
+ },
+ "organizeImports": {
+ "enabled": true
+ },
+ "linter": {
+ "enabled": true,
+ "rules": {
+ "recommended": true,
+ "suspicious": {
+ "noExplicitAny": "off",
+ "noImplicitAnyLet": "off"
+ },
+ "style": {
+ "noParameterAssign": "off"
+ },
+ "complexity": {
+ "noForEach": "off",
+ "useLiteralKeys": "off"
+ },
+ "performance": {
+ "noAccumulatingSpread": "off",
+ "noDelete": "off"
+ }
+ }
+ },
+ "javascript": {
+ "formatter": {
+ "quoteStyle": "double"
+ }
+ }
+}
diff --git a/package.json b/package.json
index af4676a..50f1c43 100644
--- a/package.json
+++ b/package.json
@@ -1,25 +1,21 @@
{
- "name": "r2-explorer-root",
- "version": "0.0.0",
- "private": true,
- "scripts": {
- "prepare": "husky install",
- "lint": "(eslint . || (eslint . --fix; exit 1)) && (prettier --check '*.{json,js}' 'packages/*/src/**/*.{js,ts}' || (prettier -w '*.{json,js}' 'packages/*/src/**/*.{js,ts}'; exit 1))",
- "build-dashboard": "pnpm run --filter r2-explorer-dashboard build",
- "build-worker": "pnpm run --filter r2-explorer build",
- "build": "pnpm build-dashboard && pnpm build-worker",
- "deploy-dashboard": "pnpm run --filter r2-explorer-dashboard deploy",
- "deploy-dashboard-dev": "pnpm run --filter r2-explorer-dashboard deploy-dev",
- "deploy-dev-worker": "pnpm run --filter r2-explorer-dev-worker deploy",
- "publish-npm": "pnpm run --filter worker publish"
- },
- "devDependencies": {
- "esbuild": "0.17.19",
- "eslint": "^8.57.0",
- "eslint-config-prettier": "^9.1.0",
- "eslint-config-typescript": "^3.0.0",
- "husky": "^9.0.11",
- "prettier": "^3.2.5",
- "typescript": "^4.7.4"
- }
+ "name": "r2-explorer-root",
+ "version": "0.0.0",
+ "private": true,
+ "scripts": {
+ "prepare": "husky",
+ "workers-ci": "export WORKERS_CI=1 && node packages/github-action/prepareDeploy.js",
+ "lint": "npx @biomejs/biome check template/ packages/dashboard/src packages/worker/src || (npx @biomejs/biome check --write template/ packages/dashboard/src packages/worker/src/; exit 1)",
+ "build-dashboard": "pnpm run --filter r2-explorer-dashboard build",
+ "build-worker": "pnpm run --filter r2-explorer build",
+ "build": "pnpm build-dashboard && pnpm build-worker",
+ "deploy-dashboard": "pnpm run --filter r2-explorer-dashboard deploy",
+ "deploy-dashboard-dev": "pnpm run --filter r2-explorer-dashboard deploy-dev",
+ "deploy-dev-worker": "pnpm run --filter r2-explorer-dev-worker deploy",
+ "publish-npm": "pnpm run --filter worker publish"
+ },
+ "devDependencies": {
+ "@biomejs/biome": "1.9.4",
+ "husky": "^9.1.7"
+ }
}
diff --git a/packages/dashboard/jsconfig.json b/packages/dashboard/jsconfig.json
index 456944a..dfc5b6a 100644
--- a/packages/dashboard/jsconfig.json
+++ b/packages/dashboard/jsconfig.json
@@ -1,39 +1,17 @@
{
- "compilerOptions": {
- "baseUrl": ".",
- "paths": {
- "src/*": [
- "src/*"
- ],
- "app/*": [
- "*"
- ],
- "components/*": [
- "src/components/*"
- ],
- "layouts/*": [
- "src/layouts/*"
- ],
- "pages/*": [
- "src/pages/*"
- ],
- "assets/*": [
- "src/assets/*"
- ],
- "boot/*": [
- "src/boot/*"
- ],
- "stores/*": [
- "src/stores/*"
- ],
- "vue$": [
- "node_modules/vue/dist/vue.runtime.esm-bundler.js"
- ]
- }
- },
- "exclude": [
- "dist",
- ".quasar",
- "node_modules"
- ]
-}
\ No newline at end of file
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "src/*": ["src/*"],
+ "app/*": ["*"],
+ "components/*": ["src/components/*"],
+ "layouts/*": ["src/layouts/*"],
+ "pages/*": ["src/pages/*"],
+ "assets/*": ["src/assets/*"],
+ "boot/*": ["src/boot/*"],
+ "stores/*": ["src/stores/*"],
+ "vue$": ["node_modules/vue/dist/vue.runtime.esm-bundler.js"]
+ }
+ },
+ "exclude": ["dist", ".quasar", "node_modules"]
+}
diff --git a/packages/dashboard/package.json b/packages/dashboard/package.json
index 384af3b..67f3eb6 100644
--- a/packages/dashboard/package.json
+++ b/packages/dashboard/package.json
@@ -1,38 +1,38 @@
{
- "name": "r2-explorer-dashboard",
- "version": "0.0.1",
- "description": "R2-Explorer",
- "productName": "r2-explorer",
- "author": "Gabriel Massadas",
- "private": true,
- "scripts": {
- "test": "echo \"No test specified\" && exit 0",
- "dev": "quasar dev",
- "build": "quasar build",
- "deploy": "wrangler pages deploy --branch main --project-name r2-explorer-dashboard dist/spa/",
- "deploy-dev": "wrangler pages deploy --branch dev --project-name r2-explorer-dashboard dist/spa/"
- },
- "dependencies": {
- "@quasar/extras": "^1.16.9",
- "axios": "^1.2.1",
- "fflate": "^0.8.1",
- "html-to-text": "^9.0.5",
- "pdfvuer": "^2.0.1",
- "pinia": "^2.0.11",
- "postal-mime": "^2.0.1",
- "quasar": "^2.14.7",
- "vue": "^3.3.11",
- "vue-router": "^4.2.5"
- },
- "devDependencies": {
- "@quasar/app-vite": "^1.8.0",
- "autoprefixer": "^10.4.2",
- "dotenv": "^16.3.1",
- "postcss": "^8.4.14"
- },
- "engines": {
- "node": "^20 || ^18 || ^16 || ^14.19",
- "npm": ">= 6.13.4",
- "yarn": ">= 1.21.1"
- }
+ "name": "r2-explorer-dashboard",
+ "version": "0.0.1",
+ "description": "R2-Explorer",
+ "productName": "r2-explorer",
+ "author": "Gabriel Massadas",
+ "private": true,
+ "scripts": {
+ "test": "echo \"No test specified\" && exit 0",
+ "dev": "quasar dev",
+ "build": "quasar build",
+ "deploy": "wrangler pages deploy --branch main --project-name r2-explorer-dashboard dist/spa/",
+ "deploy-dev": "wrangler pages deploy --branch dev --project-name r2-explorer-dashboard dist/spa/"
+ },
+ "dependencies": {
+ "@quasar/extras": "^1.16.9",
+ "axios": "^1.2.1",
+ "fflate": "^0.8.1",
+ "html-to-text": "^9.0.5",
+ "pdfvuer": "^2.0.1",
+ "pinia": "^2.0.11",
+ "postal-mime": "^2.0.1",
+ "quasar": "^2.14.7",
+ "vue": "^3.3.11",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@quasar/app-vite": "^1.8.0",
+ "autoprefixer": "^10.4.2",
+ "dotenv": "^16.3.1",
+ "postcss": "^8.4.14"
+ },
+ "engines": {
+ "node": "^20 || ^18 || ^16 || ^14.19",
+ "npm": ">= 6.13.4",
+ "yarn": ">= 1.21.1"
+ }
}
diff --git a/packages/dashboard/postcss.config.cjs b/packages/dashboard/postcss.config.cjs
index 94b7b1c..5cd2f46 100644
--- a/packages/dashboard/postcss.config.cjs
+++ b/packages/dashboard/postcss.config.cjs
@@ -2,26 +2,26 @@
// https://github.com/michael-ciniawsky/postcss-load-config
module.exports = {
- plugins: [
- // https://github.com/postcss/autoprefixer
- require('autoprefixer')({
- overrideBrowserslist: [
- 'last 4 Chrome versions',
- 'last 4 Firefox versions',
- 'last 4 Edge versions',
- 'last 4 Safari versions',
- 'last 4 Android versions',
- 'last 4 ChromeAndroid versions',
- 'last 4 FirefoxAndroid versions',
- 'last 4 iOS versions'
- ]
- })
+ plugins: [
+ // https://github.com/postcss/autoprefixer
+ require("autoprefixer")({
+ overrideBrowserslist: [
+ "last 4 Chrome versions",
+ "last 4 Firefox versions",
+ "last 4 Edge versions",
+ "last 4 Safari versions",
+ "last 4 Android versions",
+ "last 4 ChromeAndroid versions",
+ "last 4 FirefoxAndroid versions",
+ "last 4 iOS versions",
+ ],
+ }),
- // https://github.com/elchininet/postcss-rtlcss
- // If you want to support RTL css, then
- // 1. yarn/npm install postcss-rtlcss
- // 2. optionally set quasar.config.js > framework > lang to an RTL language
- // 3. uncomment the following line:
- // require('postcss-rtlcss')
- ]
-}
+ // https://github.com/elchininet/postcss-rtlcss
+ // If you want to support RTL css, then
+ // 1. yarn/npm install postcss-rtlcss
+ // 2. optionally set quasar.config.js > framework > lang to an RTL language
+ // 3. uncomment the following line:
+ // require('postcss-rtlcss')
+ ],
+};
diff --git a/packages/dashboard/quasar.config.js b/packages/dashboard/quasar.config.js
index 20d88f4..6cc3194 100644
--- a/packages/dashboard/quasar.config.js
+++ b/packages/dashboard/quasar.config.js
@@ -8,210 +8,193 @@
// Configuration for your app
// https://v2.quasar.dev/quasar-cli-vite/quasar-config-js
+const { configure } = require("quasar/wrappers");
-const { configure } = require('quasar/wrappers');
+module.exports = configure((/* ctx */) => ({
+ // eslint: {
+ // fix: true,
+ // include: [],
+ // exclude: [],
+ // rawOptions: {},
+ // warnings: true,
+ // errors: true
+ // },
+ // https://v2.quasar.dev/quasar-cli-vite/prefetch-feature
+ // preFetch: true,
-module.exports = configure(function (/* ctx */) {
- return {
- // eslint: {
- // fix: true,
- // include: [],
- // exclude: [],
- // rawOptions: {},
- // warnings: true,
- // errors: true
- // },
+ // app boot file (/src/boot)
+ // --> boot files are part of "main.js"
+ // https://v2.quasar.dev/quasar-cli-vite/boot-files
+ boot: ["axios", "auth", "bus"],
- // https://v2.quasar.dev/quasar-cli-vite/prefetch-feature
- // preFetch: true,
+ // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#css
+ css: ["app.scss"],
- // app boot file (/src/boot)
- // --> boot files are part of "main.js"
- // https://v2.quasar.dev/quasar-cli-vite/boot-files
- boot: [
- 'axios',
- 'auth',
- 'bus',
- ],
+ // https://github.com/quasarframework/quasar/tree/dev/extras
+ extras: [
+ // 'ionicons-v4',
+ // 'mdi-v5',
+ // 'fontawesome-v6',
+ // 'eva-icons',
+ // 'themify',
+ // 'line-awesome',
+ // 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both!
- // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#css
- css: [
- 'app.scss'
- ],
+ "roboto-font", // optional, you are not bound to it
+ "material-icons", // optional, you are not bound to it
+ ],
- // https://github.com/quasarframework/quasar/tree/dev/extras
- extras: [
- // 'ionicons-v4',
- // 'mdi-v5',
- // 'fontawesome-v6',
- // 'eva-icons',
- // 'themify',
- // 'line-awesome',
- // 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both!
+ // Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#build
+ build: {
+ env: require("dotenv").config().parsed,
+ target: {
+ browser: ["es2019", "edge88", "firefox78", "chrome87", "safari13.1"],
+ node: "node16",
+ },
- 'roboto-font', // optional, you are not bound to it
- 'material-icons', // optional, you are not bound to it
- ],
+ vueRouterMode: "history", // available values: 'hash', 'history'
+ // vueRouterBase,
+ // vueDevtools,
+ // vueOptionsAPI: false,
- // Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#build
- build: {
- env: require('dotenv').config().parsed,
- target: {
- browser: [ 'es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1' ],
- node: 'node16'
- },
+ // rebuildCache: true, // rebuilds Vite/linter/etc cache on startup
- vueRouterMode: 'history', // available values: 'hash', 'history'
- // vueRouterBase,
- // vueDevtools,
- // vueOptionsAPI: false,
+ publicPath: "/",
+ // analyze: true,
+ // env: {},
+ // rawDefine: {}
+ // ignorePublicFolder: true,
+ // minify: false,
+ // polyfillModulePreload: true,
+ // distDir
- // rebuildCache: true, // rebuilds Vite/linter/etc cache on startup
+ // extendViteConf (viteConf) {},
+ // viteVuePluginOptions: {},
- publicPath: '/',
- // analyze: true,
- // env: {},
- // rawDefine: {}
- // ignorePublicFolder: true,
- // minify: false,
- // polyfillModulePreload: true,
- // distDir
+ // vitePlugins: [
+ // [ 'package-name', { ..options.. } ]
+ // ]
+ },
- // extendViteConf (viteConf) {},
- // viteVuePluginOptions: {},
+ // Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#devServer
+ devServer: {
+ // https: true
+ open: true, // opens browser window automatically
+ },
+ // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#framework
+ framework: {
+ config: {},
- // vitePlugins: [
- // [ 'package-name', { ..options.. } ]
- // ]
- },
+ // iconSet: 'material-icons', // Quasar icon set
+ // lang: 'en-US', // Quasar language pack
- // Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#devServer
- devServer: {
- // https: true
- open: true // opens browser window automatically
- },
+ // For special cases outside of where the auto-import strategy can have an impact
+ // (like functional components as one of the examples),
+ // you can manually specify Quasar components/directives to be available everywhere:
+ //
+ // components: [],
+ // directives: [],
- // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#framework
- framework: {
- config: {},
+ // Quasar plugins
+ plugins: ["Notify"],
+ },
- // iconSet: 'material-icons', // Quasar icon set
- // lang: 'en-US', // Quasar language pack
+ // animations: 'all', // --- includes all animations
+ // https://v2.quasar.dev/options/animations
+ animations: [],
- // For special cases outside of where the auto-import strategy can have an impact
- // (like functional components as one of the examples),
- // you can manually specify Quasar components/directives to be available everywhere:
- //
- // components: [],
- // directives: [],
+ // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#property-sourcefiles
+ // sourceFiles: {
+ // rootComponent: 'src/App.vue',
+ // router: 'src/router/index',
+ // store: 'src/store/index',
+ // registerServiceWorker: 'src-pwa/register-service-worker',
+ // serviceWorker: 'src-pwa/custom-service-worker',
+ // pwaManifestFile: 'src-pwa/manifest.json',
+ // electronMain: 'src-electron/electron-main',
+ // electronPreload: 'src-electron/electron-preload'
+ // },
- // Quasar plugins
- plugins: [
- 'Notify'
- ]
- },
+ // https://v2.quasar.dev/quasar-cli-vite/developing-ssr/configuring-ssr
+ ssr: {
+ // ssrPwaHtmlFilename: 'offline.html', // do NOT use index.html as name!
+ // will mess up SSR
- // animations: 'all', // --- includes all animations
- // https://v2.quasar.dev/options/animations
- animations: [],
+ // extendSSRWebserverConf (esbuildConf) {},
+ // extendPackageJson (json) {},
- // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#property-sourcefiles
- // sourceFiles: {
- // rootComponent: 'src/App.vue',
- // router: 'src/router/index',
- // store: 'src/store/index',
- // registerServiceWorker: 'src-pwa/register-service-worker',
- // serviceWorker: 'src-pwa/custom-service-worker',
- // pwaManifestFile: 'src-pwa/manifest.json',
- // electronMain: 'src-electron/electron-main',
- // electronPreload: 'src-electron/electron-preload'
- // },
+ pwa: false,
- // https://v2.quasar.dev/quasar-cli-vite/developing-ssr/configuring-ssr
- ssr: {
- // ssrPwaHtmlFilename: 'offline.html', // do NOT use index.html as name!
- // will mess up SSR
+ // manualStoreHydration: true,
+ // manualPostHydrationTrigger: true,
- // extendSSRWebserverConf (esbuildConf) {},
- // extendPackageJson (json) {},
+ prodPort: 3000, // The default port that the production server should use
+ // (gets superseded if process.env.PORT is specified at runtime)
- pwa: false,
+ middlewares: [
+ "render", // keep this as last one
+ ],
+ },
- // manualStoreHydration: true,
- // manualPostHydrationTrigger: true,
+ // https://v2.quasar.dev/quasar-cli-vite/developing-pwa/configuring-pwa
+ pwa: {
+ workboxMode: "generateSW", // or 'injectManifest'
+ injectPwaMetaTags: true,
+ swFilename: "sw.js",
+ manifestFilename: "manifest.json",
+ useCredentialsForManifestTag: false,
+ // useFilenameHashes: true,
+ // extendGenerateSWOptions (cfg) {}
+ // extendInjectManifestOptions (cfg) {},
+ // extendManifestJson (json) {}
+ // extendPWACustomSWConf (esbuildConf) {}
+ },
- prodPort: 3000, // The default port that the production server should use
- // (gets superseded if process.env.PORT is specified at runtime)
+ // Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-cordova-apps/configuring-cordova
+ cordova: {
+ // noIosLegacyBuildFlag: true, // uncomment only if you know what you are doing
+ },
- middlewares: [
- 'render' // keep this as last one
- ]
- },
+ // Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-capacitor-apps/configuring-capacitor
+ capacitor: {
+ hideSplashscreen: true,
+ },
- // https://v2.quasar.dev/quasar-cli-vite/developing-pwa/configuring-pwa
- pwa: {
- workboxMode: 'generateSW', // or 'injectManifest'
- injectPwaMetaTags: true,
- swFilename: 'sw.js',
- manifestFilename: 'manifest.json',
- useCredentialsForManifestTag: false,
- // useFilenameHashes: true,
- // extendGenerateSWOptions (cfg) {}
- // extendInjectManifestOptions (cfg) {},
- // extendManifestJson (json) {}
- // extendPWACustomSWConf (esbuildConf) {}
- },
+ // Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-electron-apps/configuring-electron
+ electron: {
+ // extendElectronMainConf (esbuildConf)
+ // extendElectronPreloadConf (esbuildConf)
- // Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-cordova-apps/configuring-cordova
- cordova: {
- // noIosLegacyBuildFlag: true, // uncomment only if you know what you are doing
- },
+ // specify the debugging port to use for the Electron app when running in development mode
+ inspectPort: 5858,
- // Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-capacitor-apps/configuring-capacitor
- capacitor: {
- hideSplashscreen: true
- },
+ bundler: "packager", // 'packager' or 'builder'
- // Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-electron-apps/configuring-electron
- electron: {
- // extendElectronMainConf (esbuildConf)
- // extendElectronPreloadConf (esbuildConf)
+ packager: {
+ // https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options
+ // OS X / Mac App Store
+ // appBundleId: '',
+ // appCategoryType: '',
+ // osxSign: '',
+ // protocol: 'myapp://path',
+ // Windows only
+ // win32metadata: { ... }
+ },
- // specify the debugging port to use for the Electron app when running in development mode
- inspectPort: 5858,
+ builder: {
+ // https://www.electron.build/configuration/configuration
- bundler: 'packager', // 'packager' or 'builder'
+ appId: "r2-explorer-dashboard",
+ },
+ },
- packager: {
- // https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options
+ // Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-browser-extensions/configuring-bex
+ bex: {
+ contentScripts: ["my-content-script"],
- // OS X / Mac App Store
- // appBundleId: '',
- // appCategoryType: '',
- // osxSign: '',
- // protocol: 'myapp://path',
-
- // Windows only
- // win32metadata: { ... }
- },
-
- builder: {
- // https://www.electron.build/configuration/configuration
-
- appId: 'r2-explorer-dashboard'
- }
- },
-
- // Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-browser-extensions/configuring-bex
- bex: {
- contentScripts: [
- 'my-content-script'
- ],
-
- // extendBexScriptsConf (esbuildConf) {}
- // extendBexManifestJson (json) {}
- }
- }
-});
+ // extendBexScriptsConf (esbuildConf) {}
+ // extendBexManifestJson (json) {}
+ },
+}));
diff --git a/packages/dashboard/src/App.vue b/packages/dashboard/src/App.vue
index 38442ee..fa3f196 100644
--- a/packages/dashboard/src/App.vue
+++ b/packages/dashboard/src/App.vue
@@ -3,9 +3,9 @@
diff --git a/packages/dashboard/src/appUtils.js b/packages/dashboard/src/appUtils.js
index 7c3e846..c692378 100644
--- a/packages/dashboard/src/appUtils.js
+++ b/packages/dashboard/src/appUtils.js
@@ -1,257 +1,278 @@
import { api } from "boot/axios";
import { useMainStore } from "stores/main-store";
-export const ROOT_FOLDER = "IA==" // IA== is a space
+export const ROOT_FOLDER = "IA=="; // IA== is a space
function mapFile(obj, prefix) {
- const date = new Date(obj.uploaded)
+ const date = new Date(obj.uploaded);
- return {
- ...obj,
- hash: encode(obj.key),
- nameHash: encode(obj.key.replace(prefix, '')),
- name: obj.key.replace(prefix, ''),
- lastModified: timeSince(date),
- timestamp: date.getTime(),
- size: bytesToSize(obj.size),
- sizeRaw: obj.size,
- type: 'file',
- icon: 'article',
- color: 'grey',
- }
+ return {
+ ...obj,
+ hash: encode(obj.key),
+ nameHash: encode(obj.key.replace(prefix, "")),
+ name: obj.key.replace(prefix, ""),
+ lastModified: timeSince(date),
+ timestamp: date.getTime(),
+ size: bytesToSize(obj.size),
+ sizeRaw: obj.size,
+ type: "file",
+ icon: "article",
+ color: "grey",
+ };
}
export const timeSince = (date) => {
- const seconds = Math.floor((new Date() - date) / 1000);
+ const seconds = Math.floor((new Date() - date) / 1000);
- let interval = seconds / 31536000;
- let calc;
+ let interval = seconds / 31536000;
+ let calc;
- if (interval > 1) {
- // calc = Math.floor(interval)
- // return calc + (calc === 1 ? ' year' : ' years')
- return date.toLocaleDateString();
- }
- interval = seconds / 2592000;
- if (interval > 1) {
- // calc = Math.floor(interval)
- // return calc + (calc === 1 ? ' month' : ' months')
- return date.toLocaleDateString();
- }
- interval = seconds / 86400;
- if (interval > 1) {
- // calc = Math.floor(interval)
- // return calc + (calc === 1 ? ' day' : ' days')
- return date.toLocaleDateString();
- }
- interval = seconds / 3600;
- if (interval > 1) {
- calc = Math.floor(interval);
- return calc + (calc === 1 ? " hour" : " hours");
- }
- interval = seconds / 60;
- if (interval > 1) {
- calc = Math.floor(interval);
- return calc + (calc === 1 ? " minute" : " minutes");
- }
+ if (interval > 1) {
+ // calc = Math.floor(interval)
+ // return calc + (calc === 1 ? ' year' : ' years')
+ return date.toLocaleDateString();
+ }
+ interval = seconds / 2592000;
+ if (interval > 1) {
+ // calc = Math.floor(interval)
+ // return calc + (calc === 1 ? ' month' : ' months')
+ return date.toLocaleDateString();
+ }
+ interval = seconds / 86400;
+ if (interval > 1) {
+ // calc = Math.floor(interval)
+ // return calc + (calc === 1 ? ' day' : ' days')
+ return date.toLocaleDateString();
+ }
+ interval = seconds / 3600;
+ if (interval > 1) {
+ calc = Math.floor(interval);
+ return calc + (calc === 1 ? " hour" : " hours");
+ }
+ interval = seconds / 60;
+ if (interval > 1) {
+ calc = Math.floor(interval);
+ return calc + (calc === 1 ? " minute" : " minutes");
+ }
- calc = Math.floor(interval);
- return calc + (calc === 1 ? " second" : " seconds");
+ calc = Math.floor(interval);
+ return calc + (calc === 1 ? " second" : " seconds");
};
export const bytesToSize = (bytes) => {
- const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
- if (bytes === 0) return "0 Byte";
- const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
- return Math.round(bytes / Math.pow(1024, i), 2) + " " + sizes[i];
+ const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
+ if (bytes === 0) return "0 Byte";
+ const i = Number.parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
+ return `${Math.round(bytes / 1024 ** i, 2)} ${sizes[i]}`;
};
export const bytesToMegabytes = (bytes) => {
- return Math.round(bytes / Math.pow(1024, 2));
+ return Math.round(bytes / 1024 ** 2);
};
export const encode = (key) => {
- if (key && key !== '/' && key.startsWith('/')) {
- // File keys should never start with /
- key = key.slice(1)
- }
- return btoa(unescape(encodeURIComponent(key)));
+ if (key && key !== "/" && key.startsWith("/")) {
+ // File keys should never start with /
+ key = key.slice(1);
+ }
+ return btoa(unescape(encodeURIComponent(key)));
};
export const decode = (key) => {
- return decodeURIComponent(escape(atob(key)));
+ return decodeURIComponent(escape(atob(key)));
};
export const apiHandler = {
- createFolder: (key, bucket) => {
- return api.post(`/buckets/${bucket}/folder`, {
- key: encode(key)
- })
- },
- deleteObject: (key, bucket) => {
- return api.post(`/buckets/${bucket}/delete`, {
- key: encode(key)
- })
- },
- downloadFile: (bucket, key, previewConfig, onDownloadProgress, abortControl) => {
- const extra = {};
- if (previewConfig.downloadType === "objectUrl" || previewConfig.downloadType === "blob") {
- extra.responseType = "arraybuffer";
- }
- if (abortControl) {
- extra.signal = abortControl.signal;
- }
- if (onDownloadProgress) {
- extra.onDownloadProgress = onDownloadProgress;
- }
+ createFolder: (key, bucket) => {
+ return api.post(`/buckets/${bucket}/folder`, {
+ key: encode(key),
+ });
+ },
+ deleteObject: (key, bucket) => {
+ return api.post(`/buckets/${bucket}/delete`, {
+ key: encode(key),
+ });
+ },
+ downloadFile: (
+ bucket,
+ key,
+ previewConfig,
+ onDownloadProgress,
+ abortControl,
+ ) => {
+ const extra = {};
+ if (
+ previewConfig.downloadType === "objectUrl" ||
+ previewConfig.downloadType === "blob"
+ ) {
+ extra.responseType = "arraybuffer";
+ }
+ if (abortControl) {
+ extra.signal = abortControl.signal;
+ }
+ if (onDownloadProgress) {
+ extra.onDownloadProgress = onDownloadProgress;
+ }
- return api.get(
- `/buckets/${bucket}/${encode(key)}`,
- extra
- );
- },
- headFile: async (bucket, key) => {
- let prefix = ''
- if (key.includes('/')) {
- prefix = key.replace(key.split('/').pop(), '')
- }
+ return api.get(`/buckets/${bucket}/${encode(key)}`, extra);
+ },
+ headFile: async (bucket, key) => {
+ let prefix = "";
+ if (key.includes("/")) {
+ prefix = key.replace(key.split("/").pop(), "");
+ }
- const resp = await api.get(`/buckets/${bucket}/${encode(key)}/head`);
+ const resp = await api.get(`/buckets/${bucket}/${encode(key)}/head`);
- if (resp.status === 200) {
- return mapFile(resp.data, prefix)
- }
- },
- renameObject: (bucket, oldKey, newKey) => {
- return api.post(`/buckets/${bucket}/move`, {
- oldKey: encode(oldKey),
- newKey: encode(newKey)
- })
- },
- updateMetadata: async (bucket, key, metadata) => {
- let prefix = ''
- if (key.includes('/')) {
- prefix = key.replace(key.split('/').pop(), '')
- }
+ if (resp.status === 200) {
+ return mapFile(resp.data, prefix);
+ }
+ },
+ renameObject: (bucket, oldKey, newKey) => {
+ return api.post(`/buckets/${bucket}/move`, {
+ oldKey: encode(oldKey),
+ newKey: encode(newKey),
+ });
+ },
+ updateMetadata: async (bucket, key, metadata) => {
+ let prefix = "";
+ if (key.includes("/")) {
+ prefix = key.replace(key.split("/").pop(), "");
+ }
- const resp = await api.post(
- `/buckets/${bucket}/${encode(key)}`,
- {
- customMetadata: metadata
- }
- )
+ const resp = await api.post(`/buckets/${bucket}/${encode(key)}`, {
+ customMetadata: metadata,
+ });
- if (resp.status === 200) {
- return mapFile(resp.data, prefix)
- }
- },
- multipartCreate: (file, key, bucket) => {
- return api.post(`/buckets/${bucket}/multipart/create`, null, {
- params: {
- key: encode(key),
- httpMetadata: encode(JSON.stringify({
- contentType: file.type
- }))
- }
- })
- },
- multipartComplete: (file, key, bucket, parts, uploadId) => {
- return api.post(`/buckets/${bucket}/multipart/complete`, {
- key: encode(key),
- uploadId,
- parts
- })
- },
- multipartUpload: (uploadId, partNumber, bucket, key, chunk, callback) => {
- return api.post(`/buckets/${bucket}/multipart/upload`, chunk, {
- params: {
- key: encode(key),
- uploadId,
- partNumber
- },
- onUploadProgress: callback,
- headers: {
- 'Content-Type': 'multipart/form-data'
- }
- })
- },
- uploadObjects: (file, key, bucket, callback) => {
- // console.log(key)
- return api.post(`/buckets/${bucket}/upload`, file, {
- params: {
- key: encode(key),
- httpMetadata: encode(JSON.stringify({
- contentType: file.type
- }))
- },
- headers: {
- 'Content-Type': 'multipart/form-data'
- },
- onUploadProgress: callback
- })
- },
- listObjects: async (bucket, prefix, delimiter = '/', cursor = null) => {
- return await api.get(`/buckets/${bucket}?include=customMetadata&include=httpMetadata`, {
- params: {
- delimiter: delimiter,
- prefix: prefix && prefix !== '/' ? encode(prefix) : '',
- cursor: cursor
- }
- })
- },
- fetchFile: async (bucket, prefix, delimiter = '/') => {
- const mainStore = useMainStore();
- let truncated = true
- let cursor = null
- let contentFiles = []
- let contentFolders = []
+ if (resp.status === 200) {
+ return mapFile(resp.data, prefix);
+ }
+ },
+ multipartCreate: (file, key, bucket) => {
+ return api.post(`/buckets/${bucket}/multipart/create`, null, {
+ params: {
+ key: encode(key),
+ httpMetadata: encode(
+ JSON.stringify({
+ contentType: file.type,
+ }),
+ ),
+ },
+ });
+ },
+ multipartComplete: (file, key, bucket, parts, uploadId) => {
+ return api.post(`/buckets/${bucket}/multipart/complete`, {
+ key: encode(key),
+ uploadId,
+ parts,
+ });
+ },
+ multipartUpload: (uploadId, partNumber, bucket, key, chunk, callback) => {
+ return api.post(`/buckets/${bucket}/multipart/upload`, chunk, {
+ params: {
+ key: encode(key),
+ uploadId,
+ partNumber,
+ },
+ onUploadProgress: callback,
+ headers: {
+ "Content-Type": "multipart/form-data",
+ },
+ });
+ },
+ uploadObjects: (file, key, bucket, callback) => {
+ // console.log(key)
+ return api.post(`/buckets/${bucket}/upload`, file, {
+ params: {
+ key: encode(key),
+ httpMetadata: encode(
+ JSON.stringify({
+ contentType: file.type,
+ }),
+ ),
+ },
+ headers: {
+ "Content-Type": "multipart/form-data",
+ },
+ onUploadProgress: callback,
+ });
+ },
+ listObjects: async (bucket, prefix, delimiter = "/", cursor = null) => {
+ return await api.get(
+ `/buckets/${bucket}?include=customMetadata&include=httpMetadata`,
+ {
+ params: {
+ delimiter: delimiter,
+ prefix: prefix && prefix !== "/" ? encode(prefix) : "",
+ cursor: cursor,
+ },
+ },
+ );
+ },
+ fetchFile: async (bucket, prefix, delimiter = "/") => {
+ const mainStore = useMainStore();
+ let truncated = true;
+ let cursor = null;
+ const contentFiles = [];
+ const contentFolders = [];
- while (truncated) {
- const response = await apiHandler.listObjects(bucket, prefix, delimiter, cursor)
+ while (truncated) {
+ const response = await apiHandler.listObjects(
+ bucket,
+ prefix,
+ delimiter,
+ cursor,
+ );
- truncated = response.data.truncated
- cursor = response.data.cursor
+ truncated = response.data.truncated;
+ cursor = response.data.cursor;
- if (response.data.objects) {
- const files = response.data.objects.filter(function(obj) {
- return !(obj.key.endsWith('/') && delimiter !== '') && obj.key !== prefix // Remove selected folder when delimiter is defined
- }).map((obj) => mapFile(obj, prefix)).filter(obj => {
- // Remove hidden files
- return !(mainStore.showHiddenFiles !== true && obj.name.startsWith('.'))
- })
+ if (response.data.objects) {
+ const files = response.data.objects
+ .filter((obj) => {
+ return (
+ !(obj.key.endsWith("/") && delimiter !== "") && obj.key !== prefix
+ ); // Remove selected folder when delimiter is defined
+ })
+ .map((obj) => mapFile(obj, prefix))
+ .filter((obj) => {
+ // Remove hidden files
+ return !(
+ mainStore.showHiddenFiles !== true && obj.name.startsWith(".")
+ );
+ });
- for (const f of files) {
- contentFiles.push(f)
- }
- }
+ for (const f of files) {
+ contentFiles.push(f);
+ }
+ }
- if (response.data.delimitedPrefixes) {
- const folders = response.data.delimitedPrefixes.map(function (obj) {
- return {
- name: obj.replace(prefix, ''),
- hash: encode(obj.key),
- key: obj,
- lastModified: '--',
- timestamp: 0,
- size: '--',
- sizeRaw: 0,
- type: 'folder',
- icon: 'folder',
- color: 'orange',
- }
- }).filter(obj => {
- // Remove hidden files
- return !(mainStore.showHiddenFiles !== true && obj.name.startsWith('.'))
- })
+ if (response.data.delimitedPrefixes) {
+ const folders = response.data.delimitedPrefixes
+ .map((obj) => ({
+ name: obj.replace(prefix, ""),
+ hash: encode(obj.key),
+ key: obj,
+ lastModified: "--",
+ timestamp: 0,
+ size: "--",
+ sizeRaw: 0,
+ type: "folder",
+ icon: "folder",
+ color: "orange",
+ }))
+ .filter((obj) => {
+ // Remove hidden files
+ return !(
+ mainStore.showHiddenFiles !== true && obj.name.startsWith(".")
+ );
+ });
- for (const f of folders) {
- contentFolders.push(f)
- }
- }
- }
+ for (const f of folders) {
+ contentFolders.push(f);
+ }
+ }
+ }
- return [
- ...contentFolders,
- ...contentFiles
- ]
- }
-}
+ return [...contentFolders, ...contentFiles];
+ },
+};
diff --git a/packages/dashboard/src/boot/auth.js b/packages/dashboard/src/boot/auth.js
index 6b9810c..7816136 100644
--- a/packages/dashboard/src/boot/auth.js
+++ b/packages/dashboard/src/boot/auth.js
@@ -1,14 +1,15 @@
-import { boot } from 'quasar/wrappers';
-import { useAuthStore } from 'stores/auth-store';
+import { boot } from "quasar/wrappers";
+import { useAuthStore } from "stores/auth-store";
import { useMainStore } from "stores/main-store";
-export default boot(async ({router, store}) => {
- // Check if theres any auth token stored, if there is, try to fetch or redirect
- const authStore = useAuthStore(store);
- const authResp = await authStore.CheckLoginInStorage(router);
+export default boot(async ({ router, store }) => {
+ // Check if theres any auth token stored, if there is, try to fetch or redirect
+ const authStore = useAuthStore(store);
+ const authResp = await authStore.CheckLoginInStorage(router);
- if (authResp === false) { // No auth token stored, try to fetch without auth or redirect
- const mainStore = useMainStore(store)
- await mainStore.loadServerConfigs(router, true)
- }
+ if (authResp === false) {
+ // No auth token stored, try to fetch without auth or redirect
+ const mainStore = useMainStore(store);
+ await mainStore.loadServerConfigs(router, true);
+ }
});
diff --git a/packages/dashboard/src/boot/axios.js b/packages/dashboard/src/boot/axios.js
index c9167d1..5f17374 100644
--- a/packages/dashboard/src/boot/axios.js
+++ b/packages/dashboard/src/boot/axios.js
@@ -1,5 +1,5 @@
-import { boot } from 'quasar/wrappers'
-import axios from 'axios'
+import axios from "axios";
+import { boot } from "quasar/wrappers";
// Be careful when using SSR for cross-request state pollution
// due to creating a Singleton instance here;
@@ -7,22 +7,22 @@ import axios from 'axios'
// good idea to move this instance creation inside of the
// "export default () => {}" function below (which runs individually
// for each client)
-let url = window.location.origin
-if (process.env.NODE_ENV === 'development') {
- url = process.env.VUE_APP_SERVER_URL || 'http://localhost:8787'
+let url = window.location.origin;
+if (process.env.NODE_ENV === "development") {
+ url = process.env.VUE_APP_SERVER_URL || "http://localhost:8787";
}
-const api = axios.create({ baseURL: `${url}/api` })
+const api = axios.create({ baseURL: `${url}/api` });
export default boot(({ app }) => {
- // for use inside Vue files (Options API) through this.$axios and this.$api
+ // for use inside Vue files (Options API) through this.$axios and this.$api
- app.config.globalProperties.$axios = axios
- // ^ ^ ^ this will allow you to use this.$axios (for Vue Options API form)
- // so you won't necessarily have to import axios in each vue file
+ app.config.globalProperties.$axios = axios;
+ // ^ ^ ^ this will allow you to use this.$axios (for Vue Options API form)
+ // so you won't necessarily have to import axios in each vue file
- app.config.globalProperties.$api = api
- // ^ ^ ^ this will allow you to use this.$api (for Vue Options API form)
- // so you can easily perform requests against your app's API
-})
+ app.config.globalProperties.$api = api;
+ // ^ ^ ^ this will allow you to use this.$api (for Vue Options API form)
+ // so you can easily perform requests against your app's API
+});
-export { api }
+export { api };
diff --git a/packages/dashboard/src/boot/bus.js b/packages/dashboard/src/boot/bus.js
index 5eb99c8..c202561 100644
--- a/packages/dashboard/src/boot/bus.js
+++ b/packages/dashboard/src/boot/bus.js
@@ -1,12 +1,12 @@
-import { EventBus } from 'quasar'
-import { boot } from 'quasar/wrappers'
+import { EventBus } from "quasar";
+import { boot } from "quasar/wrappers";
export default boot(({ app }) => {
- const bus = new EventBus()
+ const bus = new EventBus();
- // for Options API
- app.config.globalProperties.$bus = bus
+ // for Options API
+ app.config.globalProperties.$bus = bus;
- // for Composition API
- app.provide('bus', bus)
-})
+ // for Composition API
+ app.provide("bus", bus);
+});
diff --git a/packages/dashboard/src/components/files/CreateFile.vue b/packages/dashboard/src/components/files/CreateFile.vue
index 7855b3f..9a32653 100644
--- a/packages/dashboard/src/components/files/CreateFile.vue
+++ b/packages/dashboard/src/components/files/CreateFile.vue
@@ -24,68 +24,73 @@
diff --git a/packages/dashboard/src/components/files/CreateFolder.vue b/packages/dashboard/src/components/files/CreateFolder.vue
index 3624a59..c1080c0 100644
--- a/packages/dashboard/src/components/files/CreateFolder.vue
+++ b/packages/dashboard/src/components/files/CreateFolder.vue
@@ -24,54 +24,58 @@
diff --git a/packages/dashboard/src/components/files/FileOptions.vue b/packages/dashboard/src/components/files/FileOptions.vue
index c2029e6..dacb3fe 100644
--- a/packages/dashboard/src/components/files/FileOptions.vue
+++ b/packages/dashboard/src/components/files/FileOptions.vue
@@ -33,144 +33,156 @@
diff --git a/packages/dashboard/src/components/preview/logGz.vue b/packages/dashboard/src/components/preview/logGz.vue
index 4e16807..697c94c 100644
--- a/packages/dashboard/src/components/preview/logGz.vue
+++ b/packages/dashboard/src/components/preview/logGz.vue
@@ -8,25 +8,23 @@
import * as fflate from "fflate";
export default {
- props: ['filedata'],
- data: function () {
- return {
- data: null
- }
- },
- mounted() {
- const parsedData = new Uint8Array(this.filedata);
- const decompressed = fflate.decompressSync(parsedData);
+ props: ["filedata"],
+ data: () => ({
+ data: null,
+ }),
+ mounted() {
+ const parsedData = new Uint8Array(this.filedata);
+ const decompressed = fflate.decompressSync(parsedData);
- const origText = fflate.strFromU8(decompressed);
+ const origText = fflate.strFromU8(decompressed);
- this.data = origText.split('\n').map(val => {
- try {
- return JSON.stringify(JSON.parse(val), null, 2)
- } catch (e) {
- return val
- }
- })
- }
-}
+ this.data = origText.split("\n").map((val) => {
+ try {
+ return JSON.stringify(JSON.parse(val), null, 2);
+ } catch (e) {
+ return val;
+ }
+ });
+ },
+};
diff --git a/packages/dashboard/src/components/utils/DragAndDrop.vue b/packages/dashboard/src/components/utils/DragAndDrop.vue
index 920cdac..7f9fbc6 100644
--- a/packages/dashboard/src/components/utils/DragAndDrop.vue
+++ b/packages/dashboard/src/components/utils/DragAndDrop.vue
@@ -23,296 +23,320 @@