From c26cae625e7cfda38adef687539049b6e56364a0 Mon Sep 17 00:00:00 2001 From: Bruno Bernardino Date: Fri, 20 Feb 2026 10:54:31 +0000 Subject: [PATCH] Remove fresh This implements a huge change, where Fresh is removed as a framework and serving files, allowing more control over importing, bundling, and serving files and components. The biggest challenge was to continue making sure that there weren't too many places to look into for import versions, and `PasswordlessPasskeyLogin.tsx` became a prototype in migrating a component to fully SSR, no need for frontend parsing (via Babel) or bundling (via a custom-script, downloading frontend dependencies from esm.sh). Still, there are too many components to migrate like that, and it's all working, so I likely won't even attempt it unless there's some bug, new feature, or security vulnerability to address that warrants a rewrite of those. This also updates all dependencies (except `@libs/xml` because that still causes some breaking in DAV endpoints), including Deno! All other advantages can be seen in the related issues, and the breaking change this (v4.0.0) introduces is related simply to `config.email.tlsMode` (which had a deprecation warning throughout v3), and because, while I tested many things exhaustively, it's not impossible something broke that I didn't see. Closes #141 Closes #132 --- .dockerignore | 3 - .dvmrc | 2 +- .github/FUNDING.yml | 2 +- .gitignore | 3 - Dockerfile | 12 +- FAQ.md | 4 + Makefile | 26 +- README.md | 20 +- babel.config.js | 56 + bewcloud.config.sample.ts | 4 +- components/Header.tsx | 27 +- components/Loading.ts | 25 + components/Settings.ts | 295 ++ .../auth/MultiFactorAuthSettings.tsx | 37 +- components/auth/MultiFactorAuthVerifyForm.tsx | 4 +- components/auth/PasswordlessPasskeyLogin.tsx | 29 + components/calendar/AddEventModal.tsx | 4 +- components/calendar/CalendarViewDay.tsx | 2 +- components/calendar/CalendarViewMonth.tsx | 2 +- components/calendar/CalendarViewWeek.tsx | 2 +- .../calendar/Calendars.tsx | 22 +- components/calendar/ImportEventsModal.tsx | 4 +- components/calendar/MainCalendar.tsx | 23 +- components/calendar/SearchEvents.tsx | 7 +- .../calendar/ViewCalendarEvent.tsx | 28 +- components/calendar/ViewEventModal.tsx | 4 +- {islands => components}/contacts/Contacts.tsx | 22 +- .../contacts/ViewContact.tsx | 24 +- {islands => components}/dashboard/Links.tsx | 16 +- {islands => components}/dashboard/Notes.tsx | 6 +- components/expenses/BudgetModal.tsx | 4 +- components/expenses/ExpenseModal.tsx | 6 +- components/expenses/ListBudgets.tsx | 2 +- components/expenses/ListExpenses.tsx | 11 +- components/expenses/MainExpenses.tsx | 34 +- components/files/CreateDirectoryModal.tsx | 2 +- components/files/CreateShareModal.tsx | 2 +- components/files/ListFiles.tsx | 28 +- components/files/ListPhotos.tsx | 18 +- components/files/MainFiles.tsx | 34 +- components/files/ManageShareModal.tsx | 4 +- components/files/MoveDirectoryOrFileModal.tsx | 6 +- .../files/RenameDirectoryOrFileModal.tsx | 2 +- components/files/SearchFiles.tsx | 7 +- components/files/ShareVerifyForm.tsx | 2 +- {islands => components}/news/Articles.tsx | 18 +- {islands => components}/news/Feeds.tsx | 21 +- components/notes/CreateNoteModal.tsx | 2 +- components/notes/MainNotes.tsx | 14 +- {islands => components}/notes/Note.tsx | 6 +- components/photos/ListPhotos.tsx | 2 +- components/photos/MainPhotos.tsx | 10 +- crons/news.ts | 2 +- deno.json | 96 +- deno.lock | 2835 ++++++----------- dev.ts | 8 - docker-compose.yml | 6 +- download-frontend-imports.ts | 183 ++ fresh.config.ts | 30 - fresh.gen.ts | 227 -- islands/Settings.tsx | 290 -- islands/auth/PasswordlessPasskeyLogin.tsx | 116 - islands/calendar/CalendarWrapper.tsx | 30 - islands/expenses/ExpensesWrapper.tsx | 23 - islands/files/FilesWrapper.tsx | 37 - islands/notes/NotesWrapper.tsx | 21 - islands/photos/PhotosWrapper.tsx | 21 - lib/auth.ts | 8 +- lib/config.ts | 8 +- lib/feed.ts | 5 +- lib/form-utils.tsx | 186 -- lib/models/calendar.ts | 4 +- lib/models/contacts.ts | 2 +- lib/models/email.ts | 19 +- lib/models/files.ts | 4 +- lib/models/multi-factor-auth.ts | 4 +- lib/models/multi-factor-auth/totp.ts | 2 +- lib/models/oidc.ts | 2 +- lib/models/user.ts | 2 +- lib/page.ts | 93 + lib/types.ts | 19 +- lib/utils/layout.tsx | 91 + lib/utils/misc.ts | 310 +- main.ts | 144 +- main_test.ts | 60 +- pages/.well-known/caldav.ts | 10 + pages/.well-known/carddav.ts | 10 + pages/404.ts | 47 + pages/api/auth/multi-factor/disable.ts | 111 + pages/api/auth/multi-factor/email/setup.ts | 52 + pages/api/auth/multi-factor/enable.ts | 146 + pages/api/auth/multi-factor/passkey/begin.ts | 89 + .../auth/multi-factor/passkey/setup-begin.ts | 61 + .../multi-factor/passkey/setup-complete.ts | 98 + pages/api/auth/multi-factor/passkey/verify.ts | 101 + pages/api/auth/multi-factor/totp/setup.ts | 60 + pages/api/calendar/add-event.ts | 75 + pages/api/calendar/add.ts | 38 + pages/api/calendar/delete-event.ts | 65 + pages/api/calendar/delete.ts | 42 + pages/api/calendar/export-events.ts | 39 + pages/api/calendar/import.ts | 68 + pages/api/calendar/search-events.ts | 54 + pages/api/calendar/update.ts | 68 + pages/api/contacts/add-addressbook.ts | 40 + pages/api/contacts/add.ts | 47 + pages/api/contacts/delete-addressbook.ts | 40 + pages/api/contacts/delete.ts | 47 + pages/api/contacts/get-addressbooks.ts | 26 + pages/api/contacts/get.ts | 36 + pages/api/contacts/import.ts | 52 + pages/api/dashboard/save-links.ts | 42 + pages/api/dashboard/save-notes.ts | 41 + pages/api/expenses/add-budget.ts | 59 + pages/api/expenses/add-expense.ts | 82 + pages/api/expenses/auto-complete.ts | 39 + pages/api/expenses/delete-budget.ts | 53 + pages/api/expenses/delete-expense.ts | 56 + pages/api/expenses/export-expenses.ts | 32 + pages/api/expenses/import-expenses.ts | 76 + pages/api/expenses/update-budget.ts | 62 + pages/api/expenses/update-expense.ts | 84 + pages/api/files/create-directory.ts | 50 + pages/api/files/create-share.ts | 96 + pages/api/files/delete-directory.ts | 50 + pages/api/files/delete-share.ts | 57 + pages/api/files/delete.ts | 50 + pages/api/files/download-directory.ts | 81 + pages/api/files/get-directories.ts | 52 + pages/api/files/get-share.ts | 47 + pages/api/files/get.ts | 45 + pages/api/files/move-directory.ts | 55 + pages/api/files/move.ts | 55 + pages/api/files/rename-directory.ts | 54 + pages/api/files/rename.ts | 54 + pages/api/files/search.ts | 44 + pages/api/files/update-share.ts | 66 + pages/api/files/upload.ts | 50 + pages/api/news/add-feed.ts | 44 + pages/api/news/delete-feed.ts | 43 + pages/api/news/import-feeds.ts | 48 + pages/api/news/mark-read.ts | 45 + pages/api/news/refresh-articles.ts | 36 + pages/api/notes/save.ts | 67 + routes/caldav.tsx => pages/caldav.ts | 40 +- pages/calendar.ts | 121 + pages/calendar/[calendarEventId].ts | 218 ++ pages/calendars.ts | 72 + routes/carddav.tsx => pages/carddav.ts | 39 +- pages/contacts.ts | 131 + pages/contacts/[contactId].ts | 195 ++ pages/dashboard.ts | 81 + routes/dav.tsx => pages/dav.ts | 34 +- pages/expenses.ts | 104 + pages/file-share/[fileShareId].ts | 186 ++ .../[fileShareId]/open/[fileName].ts | 86 + pages/file-share/[fileShareId]/verify.tsx | 136 + pages/files.ts | 107 + pages/files/open/[fileName].ts | 50 + pages/index.ts | 20 + pages/login.tsx | 327 ++ pages/logout.ts | 12 + pages/mfa-verify.tsx | 193 ++ pages/news.ts | 67 + pages/news/feeds.ts | 68 + pages/notes.ts | 91 + pages/notes/open/[fileName].ts | 101 + pages/oidc/callback.ts | 67 + pages/photos.ts | 94 + pages/photos/thumbnail/[fileName].ts | 91 + pages/settings.ts | 300 ++ pages/signup.ts | 240 ++ public/components/Header.js | 118 + public/components/Loading.js | 24 + public/components/Settings.js | 229 ++ .../auth/MultiFactorAuthSettings.js | 390 +++ .../auth/MultiFactorAuthVerifyForm.js | 84 + .../auth/PasswordlessPasskeyLogin.js | 24 + public/components/calendar/AddEventModal.js | 148 + public/components/calendar/CalendarViewDay.js | 145 + .../components/calendar/CalendarViewMonth.js | 99 + .../components/calendar/CalendarViewWeek.js | 134 + public/components/calendar/CalendarWrapper.js | 20 + public/components/calendar/Calendars.js | 269 ++ .../components/calendar/ImportEventsModal.js | 60 + public/components/calendar/MainCalendar.js | 498 +++ public/components/calendar/SearchEvents.js | 118 + .../components/calendar/ViewCalendarEvent.js | 220 ++ public/components/calendar/ViewEventModal.js | 90 + public/components/contacts/Contacts.js | 453 +++ public/components/contacts/ViewContact.js | 171 + public/components/dashboard/Links.js | 150 + public/components/dashboard/Notes.js | 75 + public/components/expenses/BudgetModal.js | 99 + public/components/expenses/ExpenseModal.js | 198 ++ public/components/expenses/ExpensesWrapper.js | 14 + public/components/expenses/ListBudgets.js | 103 + public/components/expenses/ListExpenses.js | 46 + public/components/expenses/MainExpenses.js | 612 ++++ .../components/files/CreateDirectoryModal.js | 42 + public/components/files/CreateShareModal.js | 47 + public/components/files/FilesBreadcrumb.js | 55 + public/components/files/ListFiles.js | 265 ++ public/components/files/ListPhotos.js | 162 + public/components/files/MainFiles.js | 676 ++++ public/components/files/ManageShareModal.js | 90 + .../files/MoveDirectoryOrFileModal.js | 95 + .../files/RenameDirectoryOrFileModal.js | 48 + public/components/files/SearchFiles.js | 127 + public/components/files/ShareVerifyForm.js | 36 + public/components/news/Articles.js | 216 ++ public/components/news/Feeds.js | 294 ++ public/components/notes/CreateNoteModal.js | 42 + public/components/notes/MainNotes.js | 233 ++ public/components/notes/Note.js | 89 + public/components/notes/NotesWrapper.js | 12 + public/components/photos/ListPhotos.js | 38 + public/components/photos/MainPhotos.js | 167 + public/components/photos/PhotosWrapper.js | 12 + public/css/tailwind-input.css | 74 + public/css/tailwind.css | 2059 ++++++++++++ {static => public}/favicon.ico | Bin {static => public}/images/add.svg | 0 {static => public}/images/calendar.svg | 0 {static => public}/images/check-all.svg | 0 {static => public}/images/check.svg | 0 {static => public}/images/contacts.svg | 0 {static => public}/images/dashboard.svg | 0 {static => public}/images/default.png | Bin {static => public}/images/delete.svg | 0 {static => public}/images/directory.svg | 0 {static => public}/images/download.svg | 0 {static => public}/images/expenses.svg | 0 {static => public}/images/favicon-dark.png | Bin {static => public}/images/favicon-dark.svg | 0 {static => public}/images/favicon.png | Bin {static => public}/images/favicon.svg | 0 {static => public}/images/file.svg | 0 {static => public}/images/files.svg | 0 {static => public}/images/hide-options.svg | 0 {static => public}/images/left-circle.svg | 0 {static => public}/images/left.svg | 0 {static => public}/images/loading.svg | 0 {static => public}/images/logo-white.png | Bin {static => public}/images/logo-white.svg | 0 {static => public}/images/logo.png | Bin {static => public}/images/logo.svg | 0 {static => public}/images/logomark.svg | 0 {static => public}/images/logout.svg | 0 {static => public}/images/move.svg | 0 {static => public}/images/news.svg | 0 {static => public}/images/notes.svg | 0 {static => public}/images/photos.svg | 0 {static => public}/images/refresh.svg | 0 {static => public}/images/rename.svg | 0 {static => public}/images/right-circle.svg | 0 {static => public}/images/right.svg | 0 {static => public}/images/save.svg | 0 {static => public}/images/settings.svg | 0 {static => public}/images/share.svg | 0 {static => public}/images/show-options.svg | 0 {static => public}/images/tasks.svg | 0 {static => public}/images/trash.svg | 0 public/js/*@preact/signals-core@1.13.0.mjs | 2 + .../denonext/signals-core.mjs | 3 + public/js/*@preact/signals@2.8.1.mjs | 2 + .../denonext/signals.mjs | 3 + .../@jsr/std__internal@1.0.12/denonext/os.mjs | 3 + public/js/@jsr/std__internal@^1.0.12/os | 2 + .../@jsr/std__path@1.1.4/_common/basename.mjs | 3 + .../_common/strip_trailing_separators.mjs | 2 + .../denonext/_common/assert_path.mjs | 3 + .../denonext/_common/basename.mjs | 3 + .../denonext/_common/common.mjs | 3 + .../denonext/_common/constants.mjs | 3 + .../denonext/_common/dirname.mjs | 3 + .../denonext/_common/format.mjs | 3 + .../denonext/_common/from_file_url.mjs | 3 + .../denonext/_common/glob_to_reg_exp.mjs | 3 + .../denonext/_common/glob_to_regexp.mjs | 1 + .../denonext/_common/normalize.mjs | 3 + .../denonext/_common/normalize_string.mjs | 3 + .../denonext/_common/relative.mjs | 3 + .../_common/strip_trailing_separators.mjs | 3 + .../denonext/_common/to_file_url.mjs | 3 + .../std__path@1.1.4/denonext/basename.mjs | 3 + .../@jsr/std__path@1.1.4/denonext/common.mjs | 3 + .../std__path@1.1.4/denonext/constants.mjs | 3 + .../@jsr/std__path@1.1.4/denonext/dirname.mjs | 3 + .../@jsr/std__path@1.1.4/denonext/extname.mjs | 3 + .../@jsr/std__path@1.1.4/denonext/format.mjs | 3 + .../denonext/from-file-url.mjs | 3 + .../denonext/glob-to-regexp.mjs | 3 + .../std__path@1.1.4/denonext/is-absolute.mjs | 3 + .../@jsr/std__path@1.1.4/denonext/is-glob.mjs | 3 + .../std__path@1.1.4/denonext/join-globs.mjs | 3 + .../js/@jsr/std__path@1.1.4/denonext/join.mjs | 3 + .../denonext/normalize-glob.mjs | 3 + .../std__path@1.1.4/denonext/normalize.mjs | 3 + .../@jsr/std__path@1.1.4/denonext/parse.mjs | 3 + .../std__path@1.1.4/denonext/posix/_util.mjs | 3 + .../denonext/posix/basename.mjs | 3 + .../denonext/posix/constants.mjs | 3 + .../denonext/posix/dirname.mjs | 3 + .../denonext/posix/extname.mjs | 3 + .../std__path@1.1.4/denonext/posix/format.mjs | 3 + .../denonext/posix/from-file-url.mjs | 3 + .../denonext/posix/glob-to-regexp.mjs | 3 + .../denonext/posix/is-absolute.mjs | 3 + .../denonext/posix/join-globs.mjs | 3 + .../std__path@1.1.4/denonext/posix/join.mjs | 3 + .../denonext/posix/normalize-glob.mjs | 3 + .../denonext/posix/normalize.mjs | 3 + .../std__path@1.1.4/denonext/posix/parse.mjs | 3 + .../denonext/posix/relative.mjs | 3 + .../denonext/posix/resolve.mjs | 3 + .../denonext/posix/to-file-url.mjs | 3 + .../denonext/posix/to-namespaced-path.mjs | 3 + .../std__path@1.1.4/denonext/relative.mjs | 3 + .../@jsr/std__path@1.1.4/denonext/resolve.mjs | 3 + .../std__path@1.1.4/denonext/std__path.mjs | 3 + .../std__path@1.1.4/denonext/to-file-url.mjs | 3 + .../denonext/to-namespaced-path.mjs | 3 + .../@jsr/std__path@1.1.4/denonext/types.mjs | 3 + .../denonext/windows/_util.mjs | 3 + .../denonext/windows/basename.mjs | 3 + .../denonext/windows/constants.mjs | 3 + .../denonext/windows/dirname.mjs | 3 + .../denonext/windows/extname.mjs | 3 + .../denonext/windows/format.mjs | 3 + .../denonext/windows/from-file-url.mjs | 3 + .../denonext/windows/glob-to-regexp.mjs | 3 + .../denonext/windows/is-absolute.mjs | 3 + .../denonext/windows/join-globs.mjs | 3 + .../std__path@1.1.4/denonext/windows/join.mjs | 3 + .../denonext/windows/normalize-glob.mjs | 3 + .../denonext/windows/normalize.mjs | 3 + .../denonext/windows/parse.mjs | 3 + .../denonext/windows/relative.mjs | 3 + .../denonext/windows/resolve.mjs | 3 + .../denonext/windows/to-file-url.mjs | 3 + .../denonext/windows/to-namespaced-path.mjs | 3 + .../js/@kurkle/color@0.3.4/denonext/color.mjs | 13 + public/js/@kurkle/color@^0.3.0 | 3 + public/js/@simplewebauthn/browser@13.2.2.mjs | 2 + .../browser@13.2.2/denonext/browser.mjs | 4 + public/js/chart.js@4.5.1.mjs | 4 + public/js/chart.js@4.5.1/auto.mjs | 4 + public/js/chart.js@4.5.1/denonext/auto.mjs | 3 + public/js/chart.js@4.5.1/denonext/chart.mjs | 15 + .../denonext/dist/chunks/helpers.dataset.mjs | 13 + public/js/jsr/@std/path@1.1.4.mjs | 22 + public/js/preact@10.28.4.mjs | 2 + public/js/preact@10.28.4/denonext/hooks.mjs | 3 + public/js/preact@10.28.4/denonext/preact.mjs | 3 + public/js/preact@10.28.4/hooks.mjs | 3 + public/js/simplewebauthn.js | 3 + {static => public}/manifest.json | 4 +- {static => public}/robots.txt | 0 public/scss/style.scss | 36 + public/ts/passwordless-passkey-login.ts | 110 + {lib => public/ts}/utils/calendar.ts | 0 {lib => public/ts}/utils/calendar_test.ts | 0 {lib => public/ts}/utils/contacts.ts | 0 {lib => public/ts}/utils/contacts_test.ts | 0 {lib => public/ts}/utils/files.ts | 0 {lib => public/ts}/utils/files_test.ts | 0 public/ts/utils/form.ts | 238 ++ public/ts/utils/misc.ts | 280 ++ {lib => public/ts}/utils/misc_test.ts | 0 {lib => public/ts}/utils/multi-factor-auth.ts | 2 +- {lib => public/ts}/utils/photos.ts | 0 routes.ts | 460 +++ routes/.well-known/caldav.tsx | 9 - routes/.well-known/carddav.tsx | 9 - routes/_404.tsx | 19 - routes/_app.tsx | 37 - routes/_middleware.tsx | 88 - routes/api/auth/multi-factor/disable.ts | 115 - routes/api/auth/multi-factor/email/setup.ts | 58 - routes/api/auth/multi-factor/enable.ts | 150 - routes/api/auth/multi-factor/passkey/begin.ts | 87 - .../auth/multi-factor/passkey/setup-begin.ts | 67 - .../multi-factor/passkey/setup-complete.ts | 102 - .../api/auth/multi-factor/passkey/verify.ts | 99 - routes/api/auth/multi-factor/totp/setup.ts | 66 - routes/api/calendar/add-event.tsx | 79 - routes/api/calendar/add.tsx | 42 - routes/api/calendar/delete-event.tsx | 69 - routes/api/calendar/delete.tsx | 46 - routes/api/calendar/export-events.tsx | 43 - routes/api/calendar/import.tsx | 72 - routes/api/calendar/search-events.tsx | 58 - routes/api/calendar/update.tsx | 70 - routes/api/contacts/add-addressbook.tsx | 44 - routes/api/contacts/add.tsx | 51 - routes/api/contacts/delete-addressbook.tsx | 44 - routes/api/contacts/delete.tsx | 51 - routes/api/contacts/get-addressbooks.tsx | 32 - routes/api/contacts/get.tsx | 40 - routes/api/contacts/import.tsx | 56 - routes/api/dashboard/save-links.tsx | 45 - routes/api/dashboard/save-notes.tsx | 45 - routes/api/expenses/add-budget.tsx | 62 - routes/api/expenses/add-expense.tsx | 85 - routes/api/expenses/auto-complete.tsx | 43 - routes/api/expenses/delete-budget.tsx | 56 - routes/api/expenses/delete-expense.tsx | 59 - routes/api/expenses/export-expenses.tsx | 37 - routes/api/expenses/import-expenses.tsx | 81 - routes/api/expenses/update-budget.tsx | 65 - routes/api/expenses/update-expense.tsx | 87 - routes/api/files/create-directory.tsx | 53 - routes/api/files/create-share.tsx | 99 - routes/api/files/delete-directory.tsx | 53 - routes/api/files/delete-share.tsx | 60 - routes/api/files/delete.tsx | 53 - routes/api/files/download-directory.tsx | 85 - routes/api/files/get-directories.tsx | 55 - routes/api/files/get-share.tsx | 50 - routes/api/files/get.tsx | 48 - routes/api/files/move-directory.tsx | 58 - routes/api/files/move.tsx | 58 - routes/api/files/rename-directory.tsx | 57 - routes/api/files/rename.tsx | 57 - routes/api/files/search.tsx | 47 - routes/api/files/update-share.tsx | 69 - routes/api/files/upload.tsx | 53 - routes/api/news/add-feed.tsx | 47 - routes/api/news/delete-feed.tsx | 46 - routes/api/news/import-feeds.tsx | 51 - routes/api/news/mark-read.tsx | 49 - routes/api/news/refresh-articles.tsx | 41 - routes/api/notes/save.tsx | 71 - routes/calendar.tsx | 87 - routes/calendar/[calendarEventId].tsx | 168 - routes/calendars.tsx | 40 - routes/contacts.tsx | 99 - routes/contacts/[contactId].tsx | 136 - routes/dashboard.tsx | 43 - routes/expenses.tsx | 73 - routes/file-share/[fileShareId].tsx | 138 - .../[fileShareId]/open/[fileName].tsx | 86 - routes/file-share/[fileShareId]/verify.tsx | 115 - routes/files.tsx | 74 - routes/files/open/[fileName].tsx | 54 - routes/index.tsx | 20 - routes/login.tsx | 284 -- routes/logout.tsx | 16 - routes/mfa-verify.tsx | 162 - routes/news.tsx | 34 - routes/news/feeds.tsx | 34 - routes/notes.tsx | 58 - routes/notes/open/[fileName].tsx | 61 - routes/oidc/callback.tsx | 62 - routes/photos.tsx | 63 - routes/photos/thumbnail/[fileName].tsx | 95 - routes/settings.tsx | 268 -- routes/signup.tsx | 225 -- static/styles.css | 98 - tailwind.config.ts | 19 +- 461 files changed, 19813 insertions(+), 9801 deletions(-) create mode 100644 babel.config.js create mode 100644 components/Loading.ts create mode 100644 components/Settings.ts rename {islands => components}/auth/MultiFactorAuthSettings.tsx (95%) create mode 100644 components/auth/PasswordlessPasskeyLogin.tsx rename {islands => components}/calendar/Calendars.tsx (93%) rename {islands => components}/calendar/ViewCalendarEvent.tsx (88%) rename {islands => components}/contacts/Contacts.tsx (96%) rename {islands => components}/contacts/ViewContact.tsx (86%) rename {islands => components}/dashboard/Links.tsx (91%) rename {islands => components}/dashboard/Notes.tsx (89%) rename {islands => components}/news/Articles.tsx (94%) rename {islands => components}/news/Feeds.tsx (94%) rename {islands => components}/notes/Note.tsx (91%) delete mode 100755 dev.ts create mode 100644 download-frontend-imports.ts delete mode 100644 fresh.config.ts delete mode 100644 fresh.gen.ts delete mode 100644 islands/Settings.tsx delete mode 100644 islands/auth/PasswordlessPasskeyLogin.tsx delete mode 100644 islands/calendar/CalendarWrapper.tsx delete mode 100644 islands/expenses/ExpensesWrapper.tsx delete mode 100644 islands/files/FilesWrapper.tsx delete mode 100644 islands/notes/NotesWrapper.tsx delete mode 100644 islands/photos/PhotosWrapper.tsx delete mode 100644 lib/form-utils.tsx create mode 100644 lib/page.ts create mode 100644 lib/utils/layout.tsx create mode 100644 pages/.well-known/caldav.ts create mode 100644 pages/.well-known/carddav.ts create mode 100644 pages/404.ts create mode 100644 pages/api/auth/multi-factor/disable.ts create mode 100644 pages/api/auth/multi-factor/email/setup.ts create mode 100644 pages/api/auth/multi-factor/enable.ts create mode 100644 pages/api/auth/multi-factor/passkey/begin.ts create mode 100644 pages/api/auth/multi-factor/passkey/setup-begin.ts create mode 100644 pages/api/auth/multi-factor/passkey/setup-complete.ts create mode 100644 pages/api/auth/multi-factor/passkey/verify.ts create mode 100644 pages/api/auth/multi-factor/totp/setup.ts create mode 100644 pages/api/calendar/add-event.ts create mode 100644 pages/api/calendar/add.ts create mode 100644 pages/api/calendar/delete-event.ts create mode 100644 pages/api/calendar/delete.ts create mode 100644 pages/api/calendar/export-events.ts create mode 100644 pages/api/calendar/import.ts create mode 100644 pages/api/calendar/search-events.ts create mode 100644 pages/api/calendar/update.ts create mode 100644 pages/api/contacts/add-addressbook.ts create mode 100644 pages/api/contacts/add.ts create mode 100644 pages/api/contacts/delete-addressbook.ts create mode 100644 pages/api/contacts/delete.ts create mode 100644 pages/api/contacts/get-addressbooks.ts create mode 100644 pages/api/contacts/get.ts create mode 100644 pages/api/contacts/import.ts create mode 100644 pages/api/dashboard/save-links.ts create mode 100644 pages/api/dashboard/save-notes.ts create mode 100644 pages/api/expenses/add-budget.ts create mode 100644 pages/api/expenses/add-expense.ts create mode 100644 pages/api/expenses/auto-complete.ts create mode 100644 pages/api/expenses/delete-budget.ts create mode 100644 pages/api/expenses/delete-expense.ts create mode 100644 pages/api/expenses/export-expenses.ts create mode 100644 pages/api/expenses/import-expenses.ts create mode 100644 pages/api/expenses/update-budget.ts create mode 100644 pages/api/expenses/update-expense.ts create mode 100644 pages/api/files/create-directory.ts create mode 100644 pages/api/files/create-share.ts create mode 100644 pages/api/files/delete-directory.ts create mode 100644 pages/api/files/delete-share.ts create mode 100644 pages/api/files/delete.ts create mode 100644 pages/api/files/download-directory.ts create mode 100644 pages/api/files/get-directories.ts create mode 100644 pages/api/files/get-share.ts create mode 100644 pages/api/files/get.ts create mode 100644 pages/api/files/move-directory.ts create mode 100644 pages/api/files/move.ts create mode 100644 pages/api/files/rename-directory.ts create mode 100644 pages/api/files/rename.ts create mode 100644 pages/api/files/search.ts create mode 100644 pages/api/files/update-share.ts create mode 100644 pages/api/files/upload.ts create mode 100644 pages/api/news/add-feed.ts create mode 100644 pages/api/news/delete-feed.ts create mode 100644 pages/api/news/import-feeds.ts create mode 100644 pages/api/news/mark-read.ts create mode 100644 pages/api/news/refresh-articles.ts create mode 100644 pages/api/notes/save.ts rename routes/caldav.tsx => pages/caldav.ts (78%) create mode 100644 pages/calendar.ts create mode 100644 pages/calendar/[calendarEventId].ts create mode 100644 pages/calendars.ts rename routes/carddav.tsx => pages/carddav.ts (78%) create mode 100644 pages/contacts.ts create mode 100644 pages/contacts/[contactId].ts create mode 100644 pages/dashboard.ts rename routes/dav.tsx => pages/dav.ts (93%) create mode 100644 pages/expenses.ts create mode 100644 pages/file-share/[fileShareId].ts create mode 100644 pages/file-share/[fileShareId]/open/[fileName].ts create mode 100644 pages/file-share/[fileShareId]/verify.tsx create mode 100644 pages/files.ts create mode 100644 pages/files/open/[fileName].ts create mode 100644 pages/index.ts create mode 100644 pages/login.tsx create mode 100644 pages/logout.ts create mode 100644 pages/mfa-verify.tsx create mode 100644 pages/news.ts create mode 100644 pages/news/feeds.ts create mode 100644 pages/notes.ts create mode 100644 pages/notes/open/[fileName].ts create mode 100644 pages/oidc/callback.ts create mode 100644 pages/photos.ts create mode 100644 pages/photos/thumbnail/[fileName].ts create mode 100644 pages/settings.ts create mode 100644 pages/signup.ts create mode 100644 public/components/Header.js create mode 100644 public/components/Loading.js create mode 100644 public/components/Settings.js create mode 100644 public/components/auth/MultiFactorAuthSettings.js create mode 100644 public/components/auth/MultiFactorAuthVerifyForm.js create mode 100644 public/components/auth/PasswordlessPasskeyLogin.js create mode 100644 public/components/calendar/AddEventModal.js create mode 100644 public/components/calendar/CalendarViewDay.js create mode 100644 public/components/calendar/CalendarViewMonth.js create mode 100644 public/components/calendar/CalendarViewWeek.js create mode 100644 public/components/calendar/CalendarWrapper.js create mode 100644 public/components/calendar/Calendars.js create mode 100644 public/components/calendar/ImportEventsModal.js create mode 100644 public/components/calendar/MainCalendar.js create mode 100644 public/components/calendar/SearchEvents.js create mode 100644 public/components/calendar/ViewCalendarEvent.js create mode 100644 public/components/calendar/ViewEventModal.js create mode 100644 public/components/contacts/Contacts.js create mode 100644 public/components/contacts/ViewContact.js create mode 100644 public/components/dashboard/Links.js create mode 100644 public/components/dashboard/Notes.js create mode 100644 public/components/expenses/BudgetModal.js create mode 100644 public/components/expenses/ExpenseModal.js create mode 100644 public/components/expenses/ExpensesWrapper.js create mode 100644 public/components/expenses/ListBudgets.js create mode 100644 public/components/expenses/ListExpenses.js create mode 100644 public/components/expenses/MainExpenses.js create mode 100644 public/components/files/CreateDirectoryModal.js create mode 100644 public/components/files/CreateShareModal.js create mode 100644 public/components/files/FilesBreadcrumb.js create mode 100644 public/components/files/ListFiles.js create mode 100644 public/components/files/ListPhotos.js create mode 100644 public/components/files/MainFiles.js create mode 100644 public/components/files/ManageShareModal.js create mode 100644 public/components/files/MoveDirectoryOrFileModal.js create mode 100644 public/components/files/RenameDirectoryOrFileModal.js create mode 100644 public/components/files/SearchFiles.js create mode 100644 public/components/files/ShareVerifyForm.js create mode 100644 public/components/news/Articles.js create mode 100644 public/components/news/Feeds.js create mode 100644 public/components/notes/CreateNoteModal.js create mode 100644 public/components/notes/MainNotes.js create mode 100644 public/components/notes/Note.js create mode 100644 public/components/notes/NotesWrapper.js create mode 100644 public/components/photos/ListPhotos.js create mode 100644 public/components/photos/MainPhotos.js create mode 100644 public/components/photos/PhotosWrapper.js create mode 100644 public/css/tailwind-input.css create mode 100644 public/css/tailwind.css rename {static => public}/favicon.ico (100%) rename {static => public}/images/add.svg (100%) rename {static => public}/images/calendar.svg (100%) rename {static => public}/images/check-all.svg (100%) rename {static => public}/images/check.svg (100%) rename {static => public}/images/contacts.svg (100%) rename {static => public}/images/dashboard.svg (100%) rename {static => public}/images/default.png (100%) rename {static => public}/images/delete.svg (100%) rename {static => public}/images/directory.svg (100%) rename {static => public}/images/download.svg (100%) rename {static => public}/images/expenses.svg (100%) rename {static => public}/images/favicon-dark.png (100%) rename {static => public}/images/favicon-dark.svg (100%) rename {static => public}/images/favicon.png (100%) rename {static => public}/images/favicon.svg (100%) rename {static => public}/images/file.svg (100%) rename {static => public}/images/files.svg (100%) rename {static => public}/images/hide-options.svg (100%) rename {static => public}/images/left-circle.svg (100%) rename {static => public}/images/left.svg (100%) rename {static => public}/images/loading.svg (100%) rename {static => public}/images/logo-white.png (100%) rename {static => public}/images/logo-white.svg (100%) rename {static => public}/images/logo.png (100%) rename {static => public}/images/logo.svg (100%) rename {static => public}/images/logomark.svg (100%) rename {static => public}/images/logout.svg (100%) rename {static => public}/images/move.svg (100%) rename {static => public}/images/news.svg (100%) rename {static => public}/images/notes.svg (100%) rename {static => public}/images/photos.svg (100%) rename {static => public}/images/refresh.svg (100%) rename {static => public}/images/rename.svg (100%) rename {static => public}/images/right-circle.svg (100%) rename {static => public}/images/right.svg (100%) rename {static => public}/images/save.svg (100%) rename {static => public}/images/settings.svg (100%) rename {static => public}/images/share.svg (100%) rename {static => public}/images/show-options.svg (100%) rename {static => public}/images/tasks.svg (100%) rename {static => public}/images/trash.svg (100%) create mode 100644 public/js/*@preact/signals-core@1.13.0.mjs create mode 100644 public/js/*@preact/signals-core@1.13.0/X-ZHByZWFjdEAxMC4yOC40/denonext/signals-core.mjs create mode 100644 public/js/*@preact/signals@2.8.1.mjs create mode 100644 public/js/*@preact/signals@2.8.1/X-ZHByZWFjdEAxMC4yOC40/denonext/signals.mjs create mode 100644 public/js/@jsr/std__internal@1.0.12/denonext/os.mjs create mode 100644 public/js/@jsr/std__internal@^1.0.12/os create mode 100644 public/js/@jsr/std__path@1.1.4/_common/basename.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/_common/strip_trailing_separators.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/_common/assert_path.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/_common/basename.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/_common/common.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/_common/constants.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/_common/dirname.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/_common/format.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/_common/from_file_url.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/_common/glob_to_reg_exp.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/_common/glob_to_regexp.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/_common/normalize.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/_common/normalize_string.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/_common/relative.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/_common/strip_trailing_separators.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/_common/to_file_url.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/basename.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/common.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/constants.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/dirname.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/extname.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/format.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/from-file-url.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/glob-to-regexp.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/is-absolute.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/is-glob.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/join-globs.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/join.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/normalize-glob.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/normalize.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/parse.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/posix/_util.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/posix/basename.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/posix/constants.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/posix/dirname.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/posix/extname.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/posix/format.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/posix/from-file-url.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/posix/glob-to-regexp.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/posix/is-absolute.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/posix/join-globs.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/posix/join.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/posix/normalize-glob.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/posix/normalize.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/posix/parse.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/posix/relative.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/posix/resolve.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/posix/to-file-url.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/posix/to-namespaced-path.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/relative.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/resolve.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/std__path.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/to-file-url.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/to-namespaced-path.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/types.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/windows/_util.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/windows/basename.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/windows/constants.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/windows/dirname.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/windows/extname.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/windows/format.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/windows/from-file-url.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/windows/glob-to-regexp.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/windows/is-absolute.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/windows/join-globs.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/windows/join.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/windows/normalize-glob.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/windows/normalize.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/windows/parse.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/windows/relative.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/windows/resolve.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/windows/to-file-url.mjs create mode 100644 public/js/@jsr/std__path@1.1.4/denonext/windows/to-namespaced-path.mjs create mode 100644 public/js/@kurkle/color@0.3.4/denonext/color.mjs create mode 100644 public/js/@kurkle/color@^0.3.0 create mode 100644 public/js/@simplewebauthn/browser@13.2.2.mjs create mode 100644 public/js/@simplewebauthn/browser@13.2.2/denonext/browser.mjs create mode 100644 public/js/chart.js@4.5.1.mjs create mode 100644 public/js/chart.js@4.5.1/auto.mjs create mode 100644 public/js/chart.js@4.5.1/denonext/auto.mjs create mode 100644 public/js/chart.js@4.5.1/denonext/chart.mjs create mode 100644 public/js/chart.js@4.5.1/denonext/dist/chunks/helpers.dataset.mjs create mode 100644 public/js/jsr/@std/path@1.1.4.mjs create mode 100644 public/js/preact@10.28.4.mjs create mode 100644 public/js/preact@10.28.4/denonext/hooks.mjs create mode 100644 public/js/preact@10.28.4/denonext/preact.mjs create mode 100644 public/js/preact@10.28.4/hooks.mjs create mode 100644 public/js/simplewebauthn.js rename {static => public}/manifest.json (85%) rename {static => public}/robots.txt (100%) create mode 100644 public/scss/style.scss create mode 100644 public/ts/passwordless-passkey-login.ts rename {lib => public/ts}/utils/calendar.ts (100%) rename {lib => public/ts}/utils/calendar_test.ts (100%) rename {lib => public/ts}/utils/contacts.ts (100%) rename {lib => public/ts}/utils/contacts_test.ts (100%) rename {lib => public/ts}/utils/files.ts (100%) rename {lib => public/ts}/utils/files_test.ts (100%) create mode 100644 public/ts/utils/form.ts create mode 100644 public/ts/utils/misc.ts rename {lib => public/ts}/utils/misc_test.ts (100%) rename {lib => public/ts}/utils/multi-factor-auth.ts (91%) rename {lib => public/ts}/utils/photos.ts (100%) create mode 100644 routes.ts delete mode 100644 routes/.well-known/caldav.tsx delete mode 100644 routes/.well-known/carddav.tsx delete mode 100644 routes/_404.tsx delete mode 100644 routes/_app.tsx delete mode 100644 routes/_middleware.tsx delete mode 100644 routes/api/auth/multi-factor/disable.ts delete mode 100644 routes/api/auth/multi-factor/email/setup.ts delete mode 100644 routes/api/auth/multi-factor/enable.ts delete mode 100644 routes/api/auth/multi-factor/passkey/begin.ts delete mode 100644 routes/api/auth/multi-factor/passkey/setup-begin.ts delete mode 100644 routes/api/auth/multi-factor/passkey/setup-complete.ts delete mode 100644 routes/api/auth/multi-factor/passkey/verify.ts delete mode 100644 routes/api/auth/multi-factor/totp/setup.ts delete mode 100644 routes/api/calendar/add-event.tsx delete mode 100644 routes/api/calendar/add.tsx delete mode 100644 routes/api/calendar/delete-event.tsx delete mode 100644 routes/api/calendar/delete.tsx delete mode 100644 routes/api/calendar/export-events.tsx delete mode 100644 routes/api/calendar/import.tsx delete mode 100644 routes/api/calendar/search-events.tsx delete mode 100644 routes/api/calendar/update.tsx delete mode 100644 routes/api/contacts/add-addressbook.tsx delete mode 100644 routes/api/contacts/add.tsx delete mode 100644 routes/api/contacts/delete-addressbook.tsx delete mode 100644 routes/api/contacts/delete.tsx delete mode 100644 routes/api/contacts/get-addressbooks.tsx delete mode 100644 routes/api/contacts/get.tsx delete mode 100644 routes/api/contacts/import.tsx delete mode 100644 routes/api/dashboard/save-links.tsx delete mode 100644 routes/api/dashboard/save-notes.tsx delete mode 100644 routes/api/expenses/add-budget.tsx delete mode 100644 routes/api/expenses/add-expense.tsx delete mode 100644 routes/api/expenses/auto-complete.tsx delete mode 100644 routes/api/expenses/delete-budget.tsx delete mode 100644 routes/api/expenses/delete-expense.tsx delete mode 100644 routes/api/expenses/export-expenses.tsx delete mode 100644 routes/api/expenses/import-expenses.tsx delete mode 100644 routes/api/expenses/update-budget.tsx delete mode 100644 routes/api/expenses/update-expense.tsx delete mode 100644 routes/api/files/create-directory.tsx delete mode 100644 routes/api/files/create-share.tsx delete mode 100644 routes/api/files/delete-directory.tsx delete mode 100644 routes/api/files/delete-share.tsx delete mode 100644 routes/api/files/delete.tsx delete mode 100644 routes/api/files/download-directory.tsx delete mode 100644 routes/api/files/get-directories.tsx delete mode 100644 routes/api/files/get-share.tsx delete mode 100644 routes/api/files/get.tsx delete mode 100644 routes/api/files/move-directory.tsx delete mode 100644 routes/api/files/move.tsx delete mode 100644 routes/api/files/rename-directory.tsx delete mode 100644 routes/api/files/rename.tsx delete mode 100644 routes/api/files/search.tsx delete mode 100644 routes/api/files/update-share.tsx delete mode 100644 routes/api/files/upload.tsx delete mode 100644 routes/api/news/add-feed.tsx delete mode 100644 routes/api/news/delete-feed.tsx delete mode 100644 routes/api/news/import-feeds.tsx delete mode 100644 routes/api/news/mark-read.tsx delete mode 100644 routes/api/news/refresh-articles.tsx delete mode 100644 routes/api/notes/save.tsx delete mode 100644 routes/calendar.tsx delete mode 100644 routes/calendar/[calendarEventId].tsx delete mode 100644 routes/calendars.tsx delete mode 100644 routes/contacts.tsx delete mode 100644 routes/contacts/[contactId].tsx delete mode 100644 routes/dashboard.tsx delete mode 100644 routes/expenses.tsx delete mode 100644 routes/file-share/[fileShareId].tsx delete mode 100644 routes/file-share/[fileShareId]/open/[fileName].tsx delete mode 100644 routes/file-share/[fileShareId]/verify.tsx delete mode 100644 routes/files.tsx delete mode 100644 routes/files/open/[fileName].tsx delete mode 100644 routes/index.tsx delete mode 100644 routes/login.tsx delete mode 100644 routes/logout.tsx delete mode 100644 routes/mfa-verify.tsx delete mode 100644 routes/news.tsx delete mode 100644 routes/news/feeds.tsx delete mode 100644 routes/notes.tsx delete mode 100644 routes/notes/open/[fileName].tsx delete mode 100644 routes/oidc/callback.tsx delete mode 100644 routes/photos.tsx delete mode 100644 routes/photos/thumbnail/[fileName].tsx delete mode 100644 routes/settings.tsx delete mode 100644 routes/signup.tsx delete mode 100644 static/styles.css diff --git a/.dockerignore b/.dockerignore index 1454c63..91ecaf4 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,14 +1,11 @@ -.do .github .git .gitignore docker-compose* Dockerfile -render.yaml LICENSE README.md .env.sample node_modules -_fresh data-files bewcloud.config.sample.ts diff --git a/.dvmrc b/.dvmrc index da6b0a8..a04abec 100644 --- a/.dvmrc +++ b/.dvmrc @@ -1 +1 @@ -2.5.6 +2.6.10 diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 539b66b..84ab1b5 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,7 +1,7 @@ github: [bewcloud, BrunoBernardino] custom: [ - 'https://donate.stripe.com/bIYeWBbw00Ape5iaFi', + 'https://payment-links.mollie.com/payment/wUS9dvewvjEPvseZVHEi5', 'https://paypal.me/brunobernardino', 'https://gist.github.com/BrunoBernardino/ff5b54c13dd96ac7f9fee6fbfd825b09', ] diff --git a/.gitignore b/.gitignore index 1b9cac0..c33d7a7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,3 @@ -# Fresh build directory -_fresh/ - # npm dependencies node_modules/ diff --git a/Dockerfile b/Dockerfile index 9498af7..af1a0e6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM denoland/deno:ubuntu-2.5.6 +FROM denoland/deno:ubuntu-2.6.10 EXPOSE 8000 @@ -6,17 +6,19 @@ RUN apt-get update && apt-get install -y make zip coreutils WORKDIR /app -# These steps will be re-run upon each file change in your working directory: ADD . /app -# Build fresh -RUN deno task build +# Prepare for any npm modules required "on the fly" +RUN mkdir -p /app/node_modules/.deno -RUN chown -R deno:deno /app /deno-dir +RUN chown -R deno:deno /app # Prefer not to run as root. USER deno +# Build frontend components and CSS +RUN deno task build + # Compile the main app so that it doesn't need to be compiled each startup/entry. RUN deno cache --reload main.ts diff --git a/FAQ.md b/FAQ.md index f06d204..d5dec5e 100644 --- a/FAQ.md +++ b/FAQ.md @@ -215,3 +215,7 @@ BEWCLOUD_CALENDAR_CALDAV_URL=http://127.0.0.1:5232 ``` + +## Wasn't this made with Fresh? + +Up until [v4.0.0](https://github.com/bewcloud/bewcloud/releases/tag/v4.0.0), bewCloud was made with [Fresh](https://fresh.deno.dev/), but as per [#141](https://github.com/bewcloud/bewcloud/issues/141) it has since been rewritten in standard Deno to use a more web-standards-based backend, easier to maintain and extend, without requiring breaking updates. diff --git a/Makefile b/Makefile index 665a55b..888d5c3 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,21 @@ test: .PHONY: build build: - deno task build + make download-frontend-imports + make build-babel + make build-tailwind + +.PHONY: download-frontend-imports +download-frontend-imports: + deno task download-frontend-imports + +.PHONY: build-babel +build-babel: + deno run --allow-env --allow-ffi --allow-sys --allow-read --allow-write=public/components npm:@babel/cli@7.28.6/babel ./components --out-dir ./public/components --extensions ".ts,.tsx" + +.PHONY: watch-babel +watch-babel: + deno run --allow-env --allow-ffi --allow-sys --allow-read --allow-write=public/components npm:@babel/cli@7.28.6/babel ./components --out-dir ./public/components --extensions ".ts,.tsx" --watch .PHONY: migrate-db migrate-db: @@ -25,6 +39,16 @@ migrate-db: exec-db: docker exec -it -u postgres $(shell basename $(CURDIR))-postgresql-1 psql +.PHONY: build-tailwind +build-tailwind: + deno install --allow-scripts npm:tailwindcss@4.2.0 npm:@tailwindcss/cli@4.2.0 + deno run --allow-env --allow-read --allow-sys --allow-ffi --vendor --unstable-detect-cjs --allow-write=public/css,/var/folders --allow-scripts npm:@tailwindcss/cli@4.2.0 -i ./public/css/tailwind-input.css -o ./public/css/tailwind.css + +.PHONY: watch-tailwind +watch-tailwind: + deno install --allow-scripts npm:tailwindcss@4.2.0 npm:@tailwindcss/cli@4.2.0 + deno run --allow-env --allow-read --allow-sys --allow-ffi --vendor --unstable-detect-cjs --allow-write=public/css,/var/folders --allow-scripts npm:@tailwindcss/cli@4.2.0 -w -i ./public/css/tailwind-input.css -o ./public/css/tailwind.css + .PHONY: preview preview: deno task preview diff --git a/README.md b/README.md index 13c6c85..cc4dcc7 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![](https://github.com/bewcloud/bewcloud/workflows/Run%20Tests/badge.svg)](https://github.com/bewcloud/bewcloud/actions?workflow=Run+Tests) -This is the [bewCloud app](https://bewcloud.com) built using [Fresh](https://fresh.deno.dev) and deployed using [docker compose](https://docs.docker.com/compose/). +This is the [bewCloud app](https://bewcloud.com) built with [Deno](https://deno.land/) and deployed using [docker compose](https://docs.docker.com/compose/). If you're looking for the desktop sync app, it's at [`bewcloud-desktop`](https://github.com/bewcloud/bewcloud-desktop). @@ -10,9 +10,7 @@ If you're looking for the mobile app, it's at [`bewcloud-mobile`](https://github ## Self-host it! -[![Buy managed cloud (1 year)](https://img.shields.io/badge/Buy%20managed%20cloud%20(1%20year)-51a4fb?style=for-the-badge)](https://buy.stripe.com/eVa01HgQk0Ap0eseVz) - -[![Buy managed cloud (1 month)](https://img.shields.io/badge/Buy%20managed%20cloud%20(1%20month)-51a4fb?style=for-the-badge)](https://buy.stripe.com/fZu8wOb5RfIydj56FA1gs0J) +[![Buy managed cloud (1 year)](https://img.shields.io/badge/Buy%20managed%20cloud%20(1%20year)-51a4fb?style=for-the-badge)](https://payment-links.mollie.com/payment/zeLCmenLMLQwTcvqPJMyb) Or, to run on your own machine, start with these commands: @@ -48,7 +46,7 @@ See the [Community Links](#community-links) section for alternative ways of runn ## Sponsors -These are the amazing entities or individuals who are sponsoring this project for this current month. If you'd like to show up here, [check the GitHub Sponsors page](https://github.com/sponsors/bewcloud) or [make a donation](https://donate.stripe.com/bIYeWBbw00Ape5iaFi) above $50 ($100 to show up on the website)! +These are the amazing entities or individuals who are sponsoring this project for this current month. If you'd like to show up here, [check the GitHub Sponsors page](https://github.com/sponsors/bewcloud) or [make a donation](https://payment-links.mollie.com/payment/wUS9dvewvjEPvseZVHEi5) above $50 ($100 to show up on the website)!

@@ -72,9 +70,10 @@ These are the amazing entities or individuals who are sponsoring this project fo ```sh docker compose -f docker-compose.dev.yml up # (optional) runs docker with postgres, locally make migrate-db # runs any missing database migrations -make start # runs the app in development mode (watches for file changes and recompiles the app) +make start # runs the app in development mode (watches for CSS file changes and recompiles the CSS) make format # (optional) formats the code (if you're interested in contributing) make test # (optional) runs tests (if you're interested in contributing) +make build # (optional) generates CSS for production, if you've made changes ``` ### Other less-used commands (mostly for development) @@ -82,15 +81,14 @@ make test # (optional) runs tests (if you're interested in contributing) ```sh make preview # runs the app in production mode (serves the app from the built files) make exec-db # runs psql inside the postgres container, useful for running direct development queries like `DROP DATABASE "bewcloud"; CREATE DATABASE "bewcloud";` -make build # generates all static files for production deploy ``` ## File/Directory Structure -- Routes are defined at `routes/`. -- Static files are defined at `static/`. -- Frontend-only components are defined at `components/`. -- Isomorphic components are defined at `islands/`. +- Backend routes are defined at `routes.ts` +- Publicly-available files are defined at `public/` +- Pages are defined at `pages/`. +- JSX/TSX components are defined at `components/`. - Cron jobs are defined at `crons/`. - Reusable bits of code are defined at `lib/`. - Database migrations are defined at `db-migrations/`. diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 0000000..64923b9 --- /dev/null +++ b/babel.config.js @@ -0,0 +1,56 @@ +// Converts local TSX imports to JS imports, used in the components +const rewriteLocalTsxImports = () => { + const isLocal = (value) => typeof value === 'string' && (value.startsWith('./') || value.startsWith('../')); + const isComponent = (value) => typeof value === 'string' && value.startsWith('/components/'); + + const rewrite = (source) => { + if (source && isLocal(source.value) && source.value.endsWith('.tsx')) { + source.value = source.value.replace('.tsx', '.js'); + } + + if (source && isComponent(source.value) && source.value.endsWith('.tsx')) { + source.value = source.value.replace('/components/', '/public/components/').replace('.tsx', '.js'); + } + }; + + return { + visitor: { + ImportDeclaration(path) { + rewrite(path.node.source); + }, + ExportAllDeclaration(path) { + rewrite(path.node.source); + }, + ExportNamedDeclaration(path) { + if (path.node.source) rewrite(path.node.source); + }, + }, + }; +}; + +const presets = [ + ['@babel/preset-react'], + ['@babel/preset-typescript', { jsxPragma: 'h' }], +]; + +const plugins = [ + rewriteLocalTsxImports, + [ + '@babel/plugin-transform-react-jsx', + { + 'pragma': 'h', + 'pragmaFrag': 'Fragment', + 'jsxImportSource': 'preact', + }, + ], +]; + +export default { + sourceType: 'module', + targets: '> 0.5%, not dead', + presets, + plugins, + comments: false, + compact: false, + minified: false, +}; diff --git a/bewcloud.config.sample.ts b/bewcloud.config.sample.ts index 9d6a05c..b2b86c8 100644 --- a/bewcloud.config.sample.ts +++ b/bewcloud.config.sample.ts @@ -32,8 +32,8 @@ const config: PartialDeep = { // from: 'help@bewcloud.com', // host: 'localhost', // port: 465, - // tlsMode: "auto", // “auto” means “immediate” on port 465, “starttls” otherwise; `null` is legacy behaviour that will be removed in v4: on port 465 it also means “immediate”, otherwise it will use opportunistic StartTLS falling back to plain transmission - // tlsVerify: true, // Whether to verify the TLS certificate. If a string is used the hostname will be verified using that name. + // tlsMode: 'auto', // "auto" means "immediate" on port 465, "starttls" otherwise. + // tlsVerify: true, // Whether to verify the TLS certificate. If a string is used the hostname will be verified using that name. // }, // contacts: { // enableCardDavServer: true, diff --git a/components/Header.tsx b/components/Header.tsx index 1e52f2a..69db8bb 100644 --- a/components/Header.tsx +++ b/components/Header.tsx @@ -1,11 +1,9 @@ -import { Head } from 'fresh/runtime.ts'; - import { OptionalApp, User } from '/lib/types.ts'; -import { capitalizeWord } from '/lib/utils/misc.ts'; +import { capitalizeWord } from '/public/ts/utils/misc.ts'; interface Data { route: string; - user?: User; + user?: User | null; enabledApps: OptionalApp[]; } @@ -58,16 +56,17 @@ export default function Header({ route, user, enabledApps }: Data) { return ( <> - - {pageLabel} - bewCloud -