From 792498b755b9cc1835f500d27a2d9a6d56214d5a Mon Sep 17 00:00:00 2001 From: Korbs Date: Sat, 3 Aug 2024 21:51:57 -0400 Subject: [PATCH] update --- .gitignore | 19 +- instances.json => .minpluto/Instances.json | 0 .minpluto/automation/drone.yml | 0 .minpluto/automation/github.yml | 0 .../docker/.dockerignore | 0 Dockerfile => .minpluto/docker/Dockerfile | 2 +- .../docker/docker-compose.yml | 0 .minpluto/docker/supabase/.env | 107 + .minpluto/docker/supabase/docker-compose.yml | 428 + .../docker/supabase/volumes/api/kong.yml | 241 + .../docker/supabase/volumes/db/init/data.sql | 0 .minpluto/docker/supabase/volumes/db/jwt.sql | 5 + .minpluto/docker/supabase/volumes/db/logs.sql | 4 + .../docker/supabase/volumes/db/realtime.sql | 4 + .../docker/supabase/volumes/db/roles.sql | 8 + .../docker/supabase/volumes/db/webhooks.sql | 208 + .../supabase/volumes/functions/hello/index.ts | 16 + .../supabase/volumes/functions/main/index.ts | 94 + .../docker/supabase/volumes/logs/vector.yml | 232 + .minpluto/docs/API.md | 86 + .minpluto/docs/Compatibility.md | 68 + .minpluto/docs/FAQ.md | 30 + .minpluto/docs/Requirements.md | 32 + .minpluto/docs/TODO.md | 171 + README.md | 287 +- bun.lockb | Bin 244557 -> 0 bytes package-lock.json | 11778 ---------------- package.json | 18 +- .env.sample => source/.env.sample | 0 astro.config.mjs => source/astro.mjs | 18 +- {src => source}/env.d.ts | 2 +- {src => source/src}/components/Chip.astro | 0 {src => source/src}/components/Dialog.astro | 0 .../src}/components/DiscoverChannel.astro | 0 {src => source/src}/components/Dropdown.astro | 0 .../src}/components/MusicItem.astro | 0 {src => source/src}/components/Search.astro | 0 .../src}/components/VideoItem.astro | 0 .../src}/components/buttons/Telemtry.astro | 0 .../src}/components/category/trending.astro | 0 .../src}/components/global/Analytics.astro | 0 .../src}/components/global/Footer.astro | 0 .../src}/components/global/Head.astro | 0 .../src}/components/global/MobileNav.astro | 0 .../src}/components/global/Sidebar.astro | 0 .../components/information/InstanceList.astro | 0 .../components/information/Invidious.astro | 0 .../src}/components/search/Creator.astro | 0 .../src}/components/search/Stream.astro | 0 .../text/PrivacyPolicyAnalytics.astro | 0 .../text/PrivacyPolicyCloudflare.astro | 0 .../components/video-player/Controls.astro | 0 .../src}/components/video-player/Player.astro | 0 source/src/env.d.ts | 1 + {src => source/src}/layouts/API.astro | 0 {src => source/src}/layouts/Default.astro | 0 {src => source/src}/layouts/Embed.astro | 0 {src => source/src}/layouts/Error.astro | 0 {src => source/src}/layouts/Markdown.astro | 0 {src => source/src}/layouts/Settings.astro | 0 {src => source/src}/pages/404.astro | 0 {src => source/src}/pages/500.astro | 0 .../pages/account/confirm-your-email.astro | 0 {src => source/src}/pages/account/index.astro | 0 {src => source/src}/pages/api/auth/confirm.ts | 0 {src => source/src}/pages/api/auth/login.ts | 0 {src => source/src}/pages/api/auth/logout.ts | 0 .../src}/pages/api/auth/register.ts | 0 .../src}/pages/api/language/en.astro | 0 .../src}/pages/api/language/jp.astro | 0 .../pages/api/player/milieu/disable.astro | 0 .../src}/pages/api/player/milieu/enable.astro | 0 .../src}/pages/api/telemtry/disable.astro | 0 .../src}/pages/api/telemtry/enable.astro | 0 {src => source/src}/pages/api/update/email.ts | 0 {src => source/src}/pages/api/update/name.ts | 0 .../src}/pages/category/gaming.astro | 0 .../src}/pages/category/movies.astro | 0 .../src}/pages/category/music.astro | 0 .../src}/pages/category/trending.astro | 0 .../src}/pages/channel/[...slug].astro | 0 {src => source/src}/pages/discover.astro | 0 .../src}/pages/embed/[...slug].astro | 0 .../src}/pages/iframe/category/trending.astro | 0 {src => source/src}/pages/index.astro | 0 {src => source/src}/pages/instance.mdx | 0 {src => source/src}/pages/live.astro | 0 {src => source/src}/pages/login.astro | 0 {src => source/src}/pages/m/about.astro | 0 {src => source/src}/pages/m/categories.astro | 0 {src => source/src}/pages/offline.astro | 0 {src => source/src}/pages/playlist.mdx | 0 {src => source/src}/pages/privacy.mdx | 0 {src => source/src}/pages/register.astro | 0 {src => source/src}/pages/search.astro | 0 {src => source/src}/pages/telemtry.mdx | 0 {src => source/src}/pages/vp.astro | 0 {src => source/src}/pages/watch.astro | 0 {src => source/src}/public/demo-media/480.mp4 | Bin {src => source/src}/public/demo-media/720.mp4 | Bin .../src}/public/images/backgrounds/1.webp | Bin .../src}/public/images/backgrounds/2.jpg | Bin .../src}/public/images/logo/Favicon.png | Bin ...MinPluto - Image Logo Full with Shadow.png | Bin .../logo/MinPluto - Image Logo Full.png | Bin .../images/logo/MinPluto - Logo Full.png | Bin .../public/images/logo/MinPluto - Logo.png | Bin .../images/logo/MinPluto - PWA Logo.png | Bin .../public/images/pwa/MinPluto - PWA Logo.png | Bin .../src}/public/images/pwa/Mobile.png | Bin .../src}/public/locales/en/translation.json | 0 .../src}/public/locales/jp/translation.json | 0 .../src}/public/locales/ru/translation.json | 0 {src => source/src}/public/manifest.json | 0 .../src}/public/player/controller.js | 0 {src => source/src}/public/player/seek.js | 0 {src => source/src}/public/player/sync.js | 0 {src => source/src}/public/robots.txt | 0 .../scripts/aptabase/web/dist/index.cjs | 2 + .../scripts/aptabase/web/dist/index.cjs.map | 1 + .../scripts/aptabase/web/dist/index.d.cts | 11 + .../scripts/aptabase/web/dist/index.d.ts | 11 + .../public/scripts/aptabase/web/dist/index.js | 2 + .../scripts/aptabase/web/dist/index.js.map | 1 + {src => source/src}/public/scripts/zorn.js | 0 {src => source/src}/public/service-worker.js | 0 .../twitch/video.js/alt/video-js-cdn.css | 0 .../twitch/video.js/alt/video-js-cdn.min.css | 0 .../public/twitch/video.js/alt/video.core.js | 0 .../twitch/video.js/alt/video.core.min.js | 0 .../twitch/video.js/alt/video.core.novtt.js | 0 .../video.js/alt/video.core.novtt.min.js | 0 .../public/twitch/video.js/alt/video.debug.js | 0 .../public/twitch/video.js/alt/video.novtt.js | 0 .../twitch/video.js/alt/video.novtt.min.js | 0 .../examples/elephantsdream/captions.ar.vtt | 0 .../examples/elephantsdream/captions.en.vtt | 0 .../examples/elephantsdream/captions.ja.vtt | 0 .../examples/elephantsdream/captions.ru.vtt | 0 .../examples/elephantsdream/captions.sv.vtt | 0 .../examples/elephantsdream/chapters.en.vtt | 0 .../elephantsdream/descriptions.en.vtt | 0 .../examples/elephantsdream/index.html | 0 .../twitch/video.js/examples/index.html | 0 .../examples/shared/example-captions.vtt | 0 .../video.js/examples/simple-embed/index.html | 0 .../public/twitch/video.js/font/VideoJS.svg | 0 .../public/twitch/video.js/font/VideoJS.ttf | Bin .../public/twitch/video.js/font/VideoJS.woff | Bin .../src}/public/twitch/video.js/lang/ar.js | 0 .../src}/public/twitch/video.js/lang/ar.json | 0 .../src}/public/twitch/video.js/lang/az.js | 0 .../src}/public/twitch/video.js/lang/az.json | 0 .../src}/public/twitch/video.js/lang/ba.js | 0 .../src}/public/twitch/video.js/lang/ba.json | 0 .../src}/public/twitch/video.js/lang/bg.js | 0 .../src}/public/twitch/video.js/lang/bg.json | 0 .../src}/public/twitch/video.js/lang/bn.js | 0 .../src}/public/twitch/video.js/lang/bn.json | 0 .../src}/public/twitch/video.js/lang/ca.js | 0 .../src}/public/twitch/video.js/lang/ca.json | 0 .../src}/public/twitch/video.js/lang/cs.js | 0 .../src}/public/twitch/video.js/lang/cs.json | 0 .../src}/public/twitch/video.js/lang/cy.js | 0 .../src}/public/twitch/video.js/lang/cy.json | 0 .../src}/public/twitch/video.js/lang/da.js | 0 .../src}/public/twitch/video.js/lang/da.json | 0 .../src}/public/twitch/video.js/lang/de.js | 0 .../src}/public/twitch/video.js/lang/de.json | 0 .../src}/public/twitch/video.js/lang/el.js | 0 .../src}/public/twitch/video.js/lang/el.json | 0 .../src}/public/twitch/video.js/lang/en-GB.js | 0 .../public/twitch/video.js/lang/en-GB.json | 0 .../src}/public/twitch/video.js/lang/en.js | 0 .../src}/public/twitch/video.js/lang/en.json | 0 .../src}/public/twitch/video.js/lang/es.js | 0 .../src}/public/twitch/video.js/lang/es.json | 0 .../src}/public/twitch/video.js/lang/et.js | 0 .../src}/public/twitch/video.js/lang/et.json | 0 .../src}/public/twitch/video.js/lang/eu.js | 0 .../src}/public/twitch/video.js/lang/eu.json | 0 .../src}/public/twitch/video.js/lang/fa.js | 0 .../src}/public/twitch/video.js/lang/fa.json | 0 .../src}/public/twitch/video.js/lang/fi.js | 0 .../src}/public/twitch/video.js/lang/fi.json | 0 .../src}/public/twitch/video.js/lang/fr.js | 0 .../src}/public/twitch/video.js/lang/fr.json | 0 .../src}/public/twitch/video.js/lang/gd.js | 0 .../src}/public/twitch/video.js/lang/gd.json | 0 .../src}/public/twitch/video.js/lang/gl.js | 0 .../src}/public/twitch/video.js/lang/gl.json | 0 .../src}/public/twitch/video.js/lang/he.js | 0 .../src}/public/twitch/video.js/lang/he.json | 0 .../src}/public/twitch/video.js/lang/hi.js | 0 .../src}/public/twitch/video.js/lang/hi.json | 0 .../src}/public/twitch/video.js/lang/hr.js | 0 .../src}/public/twitch/video.js/lang/hr.json | 0 .../src}/public/twitch/video.js/lang/hu.js | 0 .../src}/public/twitch/video.js/lang/hu.json | 0 .../src}/public/twitch/video.js/lang/it.js | 0 .../src}/public/twitch/video.js/lang/it.json | 0 .../src}/public/twitch/video.js/lang/ja.js | 0 .../src}/public/twitch/video.js/lang/ja.json | 0 .../src}/public/twitch/video.js/lang/ko.js | 0 .../src}/public/twitch/video.js/lang/ko.json | 0 .../src}/public/twitch/video.js/lang/lv.js | 0 .../src}/public/twitch/video.js/lang/lv.json | 0 .../src}/public/twitch/video.js/lang/mr.js | 0 .../src}/public/twitch/video.js/lang/mr.json | 0 .../src}/public/twitch/video.js/lang/nb.js | 0 .../src}/public/twitch/video.js/lang/nb.json | 0 .../src}/public/twitch/video.js/lang/nl.js | 0 .../src}/public/twitch/video.js/lang/nl.json | 0 .../src}/public/twitch/video.js/lang/nn.js | 0 .../src}/public/twitch/video.js/lang/nn.json | 0 .../src}/public/twitch/video.js/lang/np.js | 0 .../src}/public/twitch/video.js/lang/np.json | 0 .../src}/public/twitch/video.js/lang/oc.js | 0 .../src}/public/twitch/video.js/lang/oc.json | 0 .../src}/public/twitch/video.js/lang/pl.js | 0 .../src}/public/twitch/video.js/lang/pl.json | 0 .../src}/public/twitch/video.js/lang/pt-BR.js | 0 .../public/twitch/video.js/lang/pt-BR.json | 0 .../src}/public/twitch/video.js/lang/pt-PT.js | 0 .../public/twitch/video.js/lang/pt-PT.json | 0 .../src}/public/twitch/video.js/lang/ro.js | 0 .../src}/public/twitch/video.js/lang/ro.json | 0 .../src}/public/twitch/video.js/lang/ru.js | 0 .../src}/public/twitch/video.js/lang/ru.json | 0 .../src}/public/twitch/video.js/lang/sk.js | 0 .../src}/public/twitch/video.js/lang/sk.json | 0 .../src}/public/twitch/video.js/lang/sl.js | 0 .../src}/public/twitch/video.js/lang/sl.json | 0 .../src}/public/twitch/video.js/lang/sr.js | 0 .../src}/public/twitch/video.js/lang/sr.json | 0 .../src}/public/twitch/video.js/lang/sv.js | 0 .../src}/public/twitch/video.js/lang/sv.json | 0 .../src}/public/twitch/video.js/lang/te.js | 0 .../src}/public/twitch/video.js/lang/te.json | 0 .../src}/public/twitch/video.js/lang/th.js | 0 .../src}/public/twitch/video.js/lang/th.json | 0 .../src}/public/twitch/video.js/lang/tr.js | 0 .../src}/public/twitch/video.js/lang/tr.json | 0 .../src}/public/twitch/video.js/lang/uk.js | 0 .../src}/public/twitch/video.js/lang/uk.json | 0 .../src}/public/twitch/video.js/lang/vi.js | 0 .../src}/public/twitch/video.js/lang/vi.json | 0 .../src}/public/twitch/video.js/lang/zh-CN.js | 0 .../public/twitch/video.js/lang/zh-CN.json | 0 .../public/twitch/video.js/lang/zh-Hans.js | 0 .../public/twitch/video.js/lang/zh-Hans.json | 0 .../public/twitch/video.js/lang/zh-Hant.js | 0 .../public/twitch/video.js/lang/zh-Hant.json | 0 .../src}/public/twitch/video.js/lang/zh-TW.js | 0 .../public/twitch/video.js/lang/zh-TW.json | 0 .../video.js/types/big-play-button.d.ts | 0 .../video.js/types/big-play-button.d.ts.map | 0 .../public/twitch/video.js/types/button.d.ts | 0 .../twitch/video.js/types/button.d.ts.map | 0 .../video.js/types/clickable-component.d.ts | 0 .../types/clickable-component.d.ts.map | 0 .../twitch/video.js/types/close-button.d.ts | 0 .../video.js/types/close-button.d.ts.map | 0 .../twitch/video.js/types/component.d.ts | 0 .../twitch/video.js/types/component.d.ts.map | 0 .../twitch/video.js/types/consts/errors.d.ts | 0 .../video.js/types/consts/errors.d.ts.map | 0 .../audio-track-button.d.ts | 0 .../audio-track-button.d.ts.map | 0 .../audio-track-menu-item.d.ts | 0 .../audio-track-menu-item.d.ts.map | 0 .../types/control-bar/control-bar.d.ts | 0 .../types/control-bar/control-bar.d.ts.map | 0 .../types/control-bar/fullscreen-toggle.d.ts | 0 .../control-bar/fullscreen-toggle.d.ts.map | 0 .../types/control-bar/live-display.d.ts | 0 .../types/control-bar/live-display.d.ts.map | 0 .../types/control-bar/mute-toggle.d.ts | 0 .../types/control-bar/mute-toggle.d.ts.map | 0 .../picture-in-picture-toggle.d.ts | 0 .../picture-in-picture-toggle.d.ts.map | 0 .../types/control-bar/play-toggle.d.ts | 0 .../types/control-bar/play-toggle.d.ts.map | 0 .../playback-rate-menu-button.d.ts | 0 .../playback-rate-menu-button.d.ts.map | 0 .../playback-rate-menu-item.d.ts | 0 .../playback-rate-menu-item.d.ts.map | 0 .../progress-control/load-progress-bar.d.ts | 0 .../load-progress-bar.d.ts.map | 0 .../progress-control/mouse-time-display.d.ts | 0 .../mouse-time-display.d.ts.map | 0 .../progress-control/play-progress-bar.d.ts | 0 .../play-progress-bar.d.ts.map | 0 .../progress-control/progress-control.d.ts | 0 .../progress-control.d.ts.map | 0 .../progress-control/seek-bar.d.ts | 0 .../progress-control/seek-bar.d.ts.map | 0 .../progress-control/time-tooltip.d.ts | 0 .../progress-control/time-tooltip.d.ts.map | 0 .../types/control-bar/seek-to-live.d.ts | 0 .../types/control-bar/seek-to-live.d.ts.map | 0 .../skip-buttons/skip-backward.d.ts | 0 .../skip-buttons/skip-backward.d.ts.map | 0 .../skip-buttons/skip-forward.d.ts | 0 .../skip-buttons/skip-forward.d.ts.map | 0 .../custom-control-spacer.d.ts | 0 .../custom-control-spacer.d.ts.map | 0 .../control-bar/spacer-controls/spacer.d.ts | 0 .../spacer-controls/spacer.d.ts.map | 0 .../caption-settings-menu-item.d.ts | 0 .../caption-settings-menu-item.d.ts.map | 0 .../text-track-controls/captions-button.d.ts | 0 .../captions-button.d.ts.map | 0 .../text-track-controls/chapters-button.d.ts | 0 .../chapters-button.d.ts.map | 0 .../chapters-track-menu-item.d.ts | 0 .../chapters-track-menu-item.d.ts.map | 0 .../descriptions-button.d.ts | 0 .../descriptions-button.d.ts.map | 0 .../off-text-track-menu-item.d.ts | 0 .../off-text-track-menu-item.d.ts.map | 0 .../text-track-controls/subs-caps-button.d.ts | 0 .../subs-caps-button.d.ts.map | 0 .../subs-caps-menu-item.d.ts | 0 .../subs-caps-menu-item.d.ts.map | 0 .../text-track-controls/subtitles-button.d.ts | 0 .../subtitles-button.d.ts.map | 0 .../text-track-button.d.ts | 0 .../text-track-button.d.ts.map | 0 .../text-track-menu-item.d.ts | 0 .../text-track-menu-item.d.ts.map | 0 .../time-controls/current-time-display.d.ts | 0 .../current-time-display.d.ts.map | 0 .../time-controls/duration-display.d.ts | 0 .../time-controls/duration-display.d.ts.map | 0 .../time-controls/remaining-time-display.d.ts | 0 .../remaining-time-display.d.ts.map | 0 .../time-controls/time-display.d.ts | 0 .../time-controls/time-display.d.ts.map | 0 .../time-controls/time-divider.d.ts | 0 .../time-controls/time-divider.d.ts.map | 0 .../types/control-bar/track-button.d.ts | 0 .../types/control-bar/track-button.d.ts.map | 0 .../volume-control/check-mute-support.d.ts | 0 .../check-mute-support.d.ts.map | 0 .../volume-control/check-volume-support.d.ts | 0 .../check-volume-support.d.ts.map | 0 .../mouse-volume-level-display.d.ts | 0 .../mouse-volume-level-display.d.ts.map | 0 .../volume-control/volume-bar.d.ts | 0 .../volume-control/volume-bar.d.ts.map | 0 .../volume-control/volume-control.d.ts | 0 .../volume-control/volume-control.d.ts.map | 0 .../volume-control/volume-level-tooltip.d.ts | 0 .../volume-level-tooltip.d.ts.map | 0 .../volume-control/volume-level.d.ts | 0 .../volume-control/volume-level.d.ts.map | 0 .../types/control-bar/volume-panel.d.ts | 0 .../types/control-bar/volume-panel.d.ts.map | 0 .../public/twitch/video.js/types/debug.d.ts | 0 .../twitch/video.js/types/debug.d.ts.map | 0 .../twitch/video.js/types/error-display.d.ts | 0 .../video.js/types/error-display.d.ts.map | 0 .../twitch/video.js/types/event-target.d.ts | 0 .../video.js/types/event-target.d.ts.map | 0 .../twitch/video.js/types/fullscreen-api.d.ts | 0 .../video.js/types/fullscreen-api.d.ts.map | 0 .../public/twitch/video.js/types/index.d.ts | 0 .../twitch/video.js/types/index.d.ts.map | 0 .../twitch/video.js/types/live-tracker.d.ts | 0 .../video.js/types/live-tracker.d.ts.map | 0 .../video.js/types/loading-spinner.d.ts | 0 .../video.js/types/loading-spinner.d.ts.map | 0 .../twitch/video.js/types/media-error.d.ts | 0 .../video.js/types/media-error.d.ts.map | 0 .../video.js/types/menu/menu-button.d.ts | 0 .../video.js/types/menu/menu-button.d.ts.map | 0 .../twitch/video.js/types/menu/menu-item.d.ts | 0 .../video.js/types/menu/menu-item.d.ts.map | 0 .../twitch/video.js/types/menu/menu-keys.d.ts | 0 .../video.js/types/menu/menu-keys.d.ts.map | 0 .../twitch/video.js/types/menu/menu.d.ts | 0 .../twitch/video.js/types/menu/menu.d.ts.map | 0 .../twitch/video.js/types/mixins/evented.d.ts | 0 .../video.js/types/mixins/evented.d.ts.map | 0 .../video.js/types/mixins/stateful.d.ts | 0 .../video.js/types/mixins/stateful.d.ts.map | 0 .../twitch/video.js/types/modal-dialog.d.ts | 0 .../video.js/types/modal-dialog.d.ts.map | 0 .../public/twitch/video.js/types/player.d.ts | 0 .../twitch/video.js/types/player.d.ts.map | 0 .../public/twitch/video.js/types/plugin.d.ts | 0 .../twitch/video.js/types/plugin.d.ts.map | 0 .../twitch/video.js/types/poster-image.d.ts | 0 .../video.js/types/poster-image.d.ts.map | 0 .../twitch/video.js/types/resize-manager.d.ts | 0 .../video.js/types/resize-manager.d.ts.map | 0 .../public/twitch/video.js/types/setup.d.ts | 0 .../twitch/video.js/types/setup.d.ts.map | 0 .../twitch/video.js/types/slider/slider.d.ts | 0 .../video.js/types/slider/slider.d.ts.map | 0 .../twitch/video.js/types/tech/html5.d.ts | 0 .../twitch/video.js/types/tech/html5.d.ts.map | 0 .../twitch/video.js/types/tech/loader.d.ts | 0 .../video.js/types/tech/loader.d.ts.map | 0 .../video.js/types/tech/middleware.d.ts | 0 .../video.js/types/tech/middleware.d.ts.map | 0 .../video.js/types/tech/setup-sourceset.d.ts | 0 .../types/tech/setup-sourceset.d.ts.map | 0 .../twitch/video.js/types/tech/tech.d.ts | 0 .../twitch/video.js/types/tech/tech.d.ts.map | 0 .../twitch/video.js/types/title-bar.d.ts | 0 .../twitch/video.js/types/title-bar.d.ts.map | 0 .../types/tracks/audio-track-list.d.ts | 0 .../types/tracks/audio-track-list.d.ts.map | 0 .../video.js/types/tracks/audio-track.d.ts | 0 .../types/tracks/audio-track.d.ts.map | 0 .../types/tracks/html-track-element-list.d.ts | 0 .../tracks/html-track-element-list.d.ts.map | 0 .../types/tracks/html-track-element.d.ts | 0 .../types/tracks/html-track-element.d.ts.map | 0 .../types/tracks/text-track-cue-list.d.ts | 0 .../types/tracks/text-track-cue-list.d.ts.map | 0 .../types/tracks/text-track-display.d.ts | 0 .../types/tracks/text-track-display.d.ts.map | 0 .../tracks/text-track-list-converter.d.ts | 0 .../tracks/text-track-list-converter.d.ts.map | 0 .../types/tracks/text-track-list.d.ts | 0 .../types/tracks/text-track-list.d.ts.map | 0 .../types/tracks/text-track-settings.d.ts | 0 .../types/tracks/text-track-settings.d.ts.map | 0 .../video.js/types/tracks/text-track.d.ts | 0 .../video.js/types/tracks/text-track.d.ts.map | 0 .../video.js/types/tracks/track-enums.d.ts | 0 .../types/tracks/track-enums.d.ts.map | 0 .../video.js/types/tracks/track-list.d.ts | 0 .../video.js/types/tracks/track-list.d.ts.map | 0 .../video.js/types/tracks/track-types.d.ts | 0 .../types/tracks/track-types.d.ts.map | 0 .../twitch/video.js/types/tracks/track.d.ts | 0 .../video.js/types/tracks/track.d.ts.map | 0 .../types/tracks/video-track-list.d.ts | 0 .../types/tracks/video-track-list.d.ts.map | 0 .../video.js/types/tracks/video-track.d.ts | 0 .../types/tracks/video-track.d.ts.map | 0 .../twitch/video.js/types/utils/browser.d.ts | 0 .../video.js/types/utils/browser.d.ts.map | 0 .../twitch/video.js/types/utils/buffer.d.ts | 0 .../video.js/types/utils/buffer.d.ts.map | 0 .../video.js/types/utils/create-logger.d.ts | 0 .../types/utils/create-logger.d.ts.map | 0 .../video.js/types/utils/deprecate.d.ts | 0 .../video.js/types/utils/deprecate.d.ts.map | 0 .../twitch/video.js/types/utils/dom-data.d.ts | 0 .../video.js/types/utils/dom-data.d.ts.map | 0 .../twitch/video.js/types/utils/dom.d.ts | 0 .../twitch/video.js/types/utils/dom.d.ts.map | 0 .../twitch/video.js/types/utils/events.d.ts | 0 .../video.js/types/utils/events.d.ts.map | 0 .../video.js/types/utils/filter-source.d.ts | 0 .../types/utils/filter-source.d.ts.map | 0 .../twitch/video.js/types/utils/fn.d.ts | 0 .../twitch/video.js/types/utils/fn.d.ts.map | 0 .../twitch/video.js/types/utils/guid.d.ts | 0 .../twitch/video.js/types/utils/guid.d.ts.map | 0 .../twitch/video.js/types/utils/hooks.d.ts | 0 .../video.js/types/utils/hooks.d.ts.map | 0 .../twitch/video.js/types/utils/log.d.ts | 0 .../twitch/video.js/types/utils/log.d.ts.map | 0 .../video.js/types/utils/mimetypes.d.ts | 0 .../video.js/types/utils/mimetypes.d.ts.map | 0 .../twitch/video.js/types/utils/num.d.ts | 0 .../twitch/video.js/types/utils/num.d.ts.map | 0 .../twitch/video.js/types/utils/obj.d.ts | 0 .../twitch/video.js/types/utils/obj.d.ts.map | 0 .../twitch/video.js/types/utils/promise.d.ts | 0 .../video.js/types/utils/promise.d.ts.map | 0 .../twitch/video.js/types/utils/str.d.ts | 0 .../twitch/video.js/types/utils/str.d.ts.map | 0 .../video.js/types/utils/stylesheet.d.ts | 0 .../video.js/types/utils/stylesheet.d.ts.map | 0 .../twitch/video.js/types/utils/time.d.ts | 0 .../twitch/video.js/types/utils/time.d.ts.map | 0 .../twitch/video.js/types/utils/url.d.ts | 0 .../twitch/video.js/types/utils/url.d.ts.map | 0 .../public/twitch/video.js/types/video.d.ts | 0 .../twitch/video.js/types/video.d.ts.map | 0 .../src}/public/twitch/video.js/video-js.css | 0 .../public/twitch/video.js/video-js.min.css | 0 .../src}/public/twitch/video.js/video.cjs.js | 0 .../src}/public/twitch/video.js/video.es.js | 0 .../src}/public/twitch/video.js/video.js | 0 .../src}/public/twitch/video.js/video.min.js | 0 {src => source/src}/styles/embed.scss | 0 {src => source/src}/styles/form.scss | 0 {src => source/src}/styles/index.scss | 0 {src => source/src}/styles/mobile.scss | 0 {src => source/src}/styles/player.scss | 0 {src => source/src}/styles/video.scss | 0 {src => source/src/tools}/data/discover.json | 0 {src => source/src/tools}/library/supabase.ts | 0 .../src/tools}/utilities/GetConfig.js | 0 .../translate.mjs | 0 tsconfig.json | 13 +- 504 files changed, 1811 insertions(+), 12089 deletions(-) rename instances.json => .minpluto/Instances.json (100%) create mode 100644 .minpluto/automation/drone.yml create mode 100644 .minpluto/automation/github.yml rename .dockerignore => .minpluto/docker/.dockerignore (100%) rename Dockerfile => .minpluto/docker/Dockerfile (74%) rename docker-compose.yml => .minpluto/docker/docker-compose.yml (100%) create mode 100755 .minpluto/docker/supabase/.env create mode 100755 .minpluto/docker/supabase/docker-compose.yml create mode 100755 .minpluto/docker/supabase/volumes/api/kong.yml create mode 100755 .minpluto/docker/supabase/volumes/db/init/data.sql create mode 100755 .minpluto/docker/supabase/volumes/db/jwt.sql create mode 100755 .minpluto/docker/supabase/volumes/db/logs.sql create mode 100755 .minpluto/docker/supabase/volumes/db/realtime.sql create mode 100755 .minpluto/docker/supabase/volumes/db/roles.sql create mode 100755 .minpluto/docker/supabase/volumes/db/webhooks.sql create mode 100755 .minpluto/docker/supabase/volumes/functions/hello/index.ts create mode 100755 .minpluto/docker/supabase/volumes/functions/main/index.ts create mode 100755 .minpluto/docker/supabase/volumes/logs/vector.yml create mode 100644 .minpluto/docs/API.md create mode 100644 .minpluto/docs/Compatibility.md create mode 100644 .minpluto/docs/FAQ.md create mode 100644 .minpluto/docs/Requirements.md create mode 100644 .minpluto/docs/TODO.md delete mode 100755 bun.lockb delete mode 100644 package-lock.json rename .env.sample => source/.env.sample (100%) rename astro.config.mjs => source/astro.mjs (58%) rename {src => source}/env.d.ts (81%) rename {src => source/src}/components/Chip.astro (100%) rename {src => source/src}/components/Dialog.astro (100%) rename {src => source/src}/components/DiscoverChannel.astro (100%) rename {src => source/src}/components/Dropdown.astro (100%) rename {src => source/src}/components/MusicItem.astro (100%) rename {src => source/src}/components/Search.astro (100%) rename {src => source/src}/components/VideoItem.astro (100%) rename {src => source/src}/components/buttons/Telemtry.astro (100%) rename {src => source/src}/components/category/trending.astro (100%) rename {src => source/src}/components/global/Analytics.astro (100%) rename {src => source/src}/components/global/Footer.astro (100%) rename {src => source/src}/components/global/Head.astro (100%) rename {src => source/src}/components/global/MobileNav.astro (100%) rename {src => source/src}/components/global/Sidebar.astro (100%) rename {src => source/src}/components/information/InstanceList.astro (100%) rename {src => source/src}/components/information/Invidious.astro (100%) rename {src => source/src}/components/search/Creator.astro (100%) rename {src => source/src}/components/search/Stream.astro (100%) rename {src => source/src}/components/text/PrivacyPolicyAnalytics.astro (100%) rename {src => source/src}/components/text/PrivacyPolicyCloudflare.astro (100%) rename {src => source/src}/components/video-player/Controls.astro (100%) rename {src => source/src}/components/video-player/Player.astro (100%) create mode 100644 source/src/env.d.ts rename {src => source/src}/layouts/API.astro (100%) rename {src => source/src}/layouts/Default.astro (100%) rename {src => source/src}/layouts/Embed.astro (100%) rename {src => source/src}/layouts/Error.astro (100%) rename {src => source/src}/layouts/Markdown.astro (100%) rename {src => source/src}/layouts/Settings.astro (100%) rename {src => source/src}/pages/404.astro (100%) rename {src => source/src}/pages/500.astro (100%) rename {src => source/src}/pages/account/confirm-your-email.astro (100%) rename {src => source/src}/pages/account/index.astro (100%) rename {src => source/src}/pages/api/auth/confirm.ts (100%) rename {src => source/src}/pages/api/auth/login.ts (100%) rename {src => source/src}/pages/api/auth/logout.ts (100%) rename {src => source/src}/pages/api/auth/register.ts (100%) rename {src => source/src}/pages/api/language/en.astro (100%) rename {src => source/src}/pages/api/language/jp.astro (100%) rename {src => source/src}/pages/api/player/milieu/disable.astro (100%) rename {src => source/src}/pages/api/player/milieu/enable.astro (100%) rename {src => source/src}/pages/api/telemtry/disable.astro (100%) rename {src => source/src}/pages/api/telemtry/enable.astro (100%) rename {src => source/src}/pages/api/update/email.ts (100%) rename {src => source/src}/pages/api/update/name.ts (100%) rename {src => source/src}/pages/category/gaming.astro (100%) rename {src => source/src}/pages/category/movies.astro (100%) rename {src => source/src}/pages/category/music.astro (100%) rename {src => source/src}/pages/category/trending.astro (100%) rename {src => source/src}/pages/channel/[...slug].astro (100%) rename {src => source/src}/pages/discover.astro (100%) rename {src => source/src}/pages/embed/[...slug].astro (100%) rename {src => source/src}/pages/iframe/category/trending.astro (100%) rename {src => source/src}/pages/index.astro (100%) rename {src => source/src}/pages/instance.mdx (100%) rename {src => source/src}/pages/live.astro (100%) rename {src => source/src}/pages/login.astro (100%) rename {src => source/src}/pages/m/about.astro (100%) rename {src => source/src}/pages/m/categories.astro (100%) rename {src => source/src}/pages/offline.astro (100%) rename {src => source/src}/pages/playlist.mdx (100%) rename {src => source/src}/pages/privacy.mdx (100%) rename {src => source/src}/pages/register.astro (100%) rename {src => source/src}/pages/search.astro (100%) rename {src => source/src}/pages/telemtry.mdx (100%) rename {src => source/src}/pages/vp.astro (100%) rename {src => source/src}/pages/watch.astro (100%) rename {src => source/src}/public/demo-media/480.mp4 (100%) rename {src => source/src}/public/demo-media/720.mp4 (100%) rename {src => source/src}/public/images/backgrounds/1.webp (100%) rename {src => source/src}/public/images/backgrounds/2.jpg (100%) rename {src => source/src}/public/images/logo/Favicon.png (100%) rename {src => source/src}/public/images/logo/MinPluto - Image Logo Full with Shadow.png (100%) rename {src => source/src}/public/images/logo/MinPluto - Image Logo Full.png (100%) rename {src => source/src}/public/images/logo/MinPluto - Logo Full.png (100%) rename {src => source/src}/public/images/logo/MinPluto - Logo.png (100%) rename {src => source/src}/public/images/logo/MinPluto - PWA Logo.png (100%) rename {src => source/src}/public/images/pwa/MinPluto - PWA Logo.png (100%) rename {src => source/src}/public/images/pwa/Mobile.png (100%) rename {src => source/src}/public/locales/en/translation.json (100%) rename {src => source/src}/public/locales/jp/translation.json (100%) rename {src => source/src}/public/locales/ru/translation.json (100%) rename {src => source/src}/public/manifest.json (100%) rename {src => source/src}/public/player/controller.js (100%) rename {src => source/src}/public/player/seek.js (100%) rename {src => source/src}/public/player/sync.js (100%) rename {src => source/src}/public/robots.txt (100%) create mode 100755 source/src/public/scripts/aptabase/web/dist/index.cjs create mode 100755 source/src/public/scripts/aptabase/web/dist/index.cjs.map create mode 100755 source/src/public/scripts/aptabase/web/dist/index.d.cts create mode 100755 source/src/public/scripts/aptabase/web/dist/index.d.ts create mode 100755 source/src/public/scripts/aptabase/web/dist/index.js create mode 100755 source/src/public/scripts/aptabase/web/dist/index.js.map rename {src => source/src}/public/scripts/zorn.js (100%) rename {src => source/src}/public/service-worker.js (100%) rename {src => source/src}/public/twitch/video.js/alt/video-js-cdn.css (100%) rename {src => source/src}/public/twitch/video.js/alt/video-js-cdn.min.css (100%) rename {src => source/src}/public/twitch/video.js/alt/video.core.js (100%) rename {src => source/src}/public/twitch/video.js/alt/video.core.min.js (100%) rename {src => source/src}/public/twitch/video.js/alt/video.core.novtt.js (100%) rename {src => source/src}/public/twitch/video.js/alt/video.core.novtt.min.js (100%) rename {src => source/src}/public/twitch/video.js/alt/video.debug.js (100%) rename {src => source/src}/public/twitch/video.js/alt/video.novtt.js (100%) rename {src => source/src}/public/twitch/video.js/alt/video.novtt.min.js (100%) rename {src => source/src}/public/twitch/video.js/examples/elephantsdream/captions.ar.vtt (100%) rename {src => source/src}/public/twitch/video.js/examples/elephantsdream/captions.en.vtt (100%) rename {src => source/src}/public/twitch/video.js/examples/elephantsdream/captions.ja.vtt (100%) rename {src => source/src}/public/twitch/video.js/examples/elephantsdream/captions.ru.vtt (100%) rename {src => source/src}/public/twitch/video.js/examples/elephantsdream/captions.sv.vtt (100%) rename {src => source/src}/public/twitch/video.js/examples/elephantsdream/chapters.en.vtt (100%) rename {src => source/src}/public/twitch/video.js/examples/elephantsdream/descriptions.en.vtt (100%) rename {src => source/src}/public/twitch/video.js/examples/elephantsdream/index.html (100%) rename {src => source/src}/public/twitch/video.js/examples/index.html (100%) rename {src => source/src}/public/twitch/video.js/examples/shared/example-captions.vtt (100%) rename {src => source/src}/public/twitch/video.js/examples/simple-embed/index.html (100%) rename {src => source/src}/public/twitch/video.js/font/VideoJS.svg (100%) rename {src => source/src}/public/twitch/video.js/font/VideoJS.ttf (100%) rename {src => source/src}/public/twitch/video.js/font/VideoJS.woff (100%) rename {src => source/src}/public/twitch/video.js/lang/ar.js (100%) rename {src => source/src}/public/twitch/video.js/lang/ar.json (100%) rename {src => source/src}/public/twitch/video.js/lang/az.js (100%) rename {src => source/src}/public/twitch/video.js/lang/az.json (100%) rename {src => source/src}/public/twitch/video.js/lang/ba.js (100%) rename {src => source/src}/public/twitch/video.js/lang/ba.json (100%) rename {src => source/src}/public/twitch/video.js/lang/bg.js (100%) rename {src => source/src}/public/twitch/video.js/lang/bg.json (100%) rename {src => source/src}/public/twitch/video.js/lang/bn.js (100%) rename {src => source/src}/public/twitch/video.js/lang/bn.json (100%) rename {src => source/src}/public/twitch/video.js/lang/ca.js (100%) rename {src => source/src}/public/twitch/video.js/lang/ca.json (100%) rename {src => source/src}/public/twitch/video.js/lang/cs.js (100%) rename {src => source/src}/public/twitch/video.js/lang/cs.json (100%) rename {src => source/src}/public/twitch/video.js/lang/cy.js (100%) rename {src => source/src}/public/twitch/video.js/lang/cy.json (100%) rename {src => source/src}/public/twitch/video.js/lang/da.js (100%) rename {src => source/src}/public/twitch/video.js/lang/da.json (100%) rename {src => source/src}/public/twitch/video.js/lang/de.js (100%) rename {src => source/src}/public/twitch/video.js/lang/de.json (100%) rename {src => source/src}/public/twitch/video.js/lang/el.js (100%) rename {src => source/src}/public/twitch/video.js/lang/el.json (100%) rename {src => source/src}/public/twitch/video.js/lang/en-GB.js (100%) rename {src => source/src}/public/twitch/video.js/lang/en-GB.json (100%) rename {src => source/src}/public/twitch/video.js/lang/en.js (100%) rename {src => source/src}/public/twitch/video.js/lang/en.json (100%) rename {src => source/src}/public/twitch/video.js/lang/es.js (100%) rename {src => source/src}/public/twitch/video.js/lang/es.json (100%) rename {src => source/src}/public/twitch/video.js/lang/et.js (100%) rename {src => source/src}/public/twitch/video.js/lang/et.json (100%) rename {src => source/src}/public/twitch/video.js/lang/eu.js (100%) rename {src => source/src}/public/twitch/video.js/lang/eu.json (100%) rename {src => source/src}/public/twitch/video.js/lang/fa.js (100%) rename {src => source/src}/public/twitch/video.js/lang/fa.json (100%) rename {src => source/src}/public/twitch/video.js/lang/fi.js (100%) rename {src => source/src}/public/twitch/video.js/lang/fi.json (100%) rename {src => source/src}/public/twitch/video.js/lang/fr.js (100%) rename {src => source/src}/public/twitch/video.js/lang/fr.json (100%) rename {src => source/src}/public/twitch/video.js/lang/gd.js (100%) rename {src => source/src}/public/twitch/video.js/lang/gd.json (100%) rename {src => source/src}/public/twitch/video.js/lang/gl.js (100%) rename {src => source/src}/public/twitch/video.js/lang/gl.json (100%) rename {src => source/src}/public/twitch/video.js/lang/he.js (100%) rename {src => source/src}/public/twitch/video.js/lang/he.json (100%) rename {src => source/src}/public/twitch/video.js/lang/hi.js (100%) rename {src => source/src}/public/twitch/video.js/lang/hi.json (100%) rename {src => source/src}/public/twitch/video.js/lang/hr.js (100%) rename {src => source/src}/public/twitch/video.js/lang/hr.json (100%) rename {src => source/src}/public/twitch/video.js/lang/hu.js (100%) rename {src => source/src}/public/twitch/video.js/lang/hu.json (100%) rename {src => source/src}/public/twitch/video.js/lang/it.js (100%) rename {src => source/src}/public/twitch/video.js/lang/it.json (100%) rename {src => source/src}/public/twitch/video.js/lang/ja.js (100%) rename {src => source/src}/public/twitch/video.js/lang/ja.json (100%) rename {src => source/src}/public/twitch/video.js/lang/ko.js (100%) rename {src => source/src}/public/twitch/video.js/lang/ko.json (100%) rename {src => source/src}/public/twitch/video.js/lang/lv.js (100%) rename {src => source/src}/public/twitch/video.js/lang/lv.json (100%) rename {src => source/src}/public/twitch/video.js/lang/mr.js (100%) rename {src => source/src}/public/twitch/video.js/lang/mr.json (100%) rename {src => source/src}/public/twitch/video.js/lang/nb.js (100%) rename {src => source/src}/public/twitch/video.js/lang/nb.json (100%) rename {src => source/src}/public/twitch/video.js/lang/nl.js (100%) rename {src => source/src}/public/twitch/video.js/lang/nl.json (100%) rename {src => source/src}/public/twitch/video.js/lang/nn.js (100%) rename {src => source/src}/public/twitch/video.js/lang/nn.json (100%) rename {src => source/src}/public/twitch/video.js/lang/np.js (100%) rename {src => source/src}/public/twitch/video.js/lang/np.json (100%) rename {src => source/src}/public/twitch/video.js/lang/oc.js (100%) rename {src => source/src}/public/twitch/video.js/lang/oc.json (100%) rename {src => source/src}/public/twitch/video.js/lang/pl.js (100%) rename {src => source/src}/public/twitch/video.js/lang/pl.json (100%) rename {src => source/src}/public/twitch/video.js/lang/pt-BR.js (100%) rename {src => source/src}/public/twitch/video.js/lang/pt-BR.json (100%) rename {src => source/src}/public/twitch/video.js/lang/pt-PT.js (100%) rename {src => source/src}/public/twitch/video.js/lang/pt-PT.json (100%) rename {src => source/src}/public/twitch/video.js/lang/ro.js (100%) rename {src => source/src}/public/twitch/video.js/lang/ro.json (100%) rename {src => source/src}/public/twitch/video.js/lang/ru.js (100%) rename {src => source/src}/public/twitch/video.js/lang/ru.json (100%) rename {src => source/src}/public/twitch/video.js/lang/sk.js (100%) rename {src => source/src}/public/twitch/video.js/lang/sk.json (100%) rename {src => source/src}/public/twitch/video.js/lang/sl.js (100%) rename {src => source/src}/public/twitch/video.js/lang/sl.json (100%) rename {src => source/src}/public/twitch/video.js/lang/sr.js (100%) rename {src => source/src}/public/twitch/video.js/lang/sr.json (100%) rename {src => source/src}/public/twitch/video.js/lang/sv.js (100%) rename {src => source/src}/public/twitch/video.js/lang/sv.json (100%) rename {src => source/src}/public/twitch/video.js/lang/te.js (100%) rename {src => source/src}/public/twitch/video.js/lang/te.json (100%) rename {src => source/src}/public/twitch/video.js/lang/th.js (100%) rename {src => source/src}/public/twitch/video.js/lang/th.json (100%) rename {src => source/src}/public/twitch/video.js/lang/tr.js (100%) rename {src => source/src}/public/twitch/video.js/lang/tr.json (100%) rename {src => source/src}/public/twitch/video.js/lang/uk.js (100%) rename {src => source/src}/public/twitch/video.js/lang/uk.json (100%) rename {src => source/src}/public/twitch/video.js/lang/vi.js (100%) rename {src => source/src}/public/twitch/video.js/lang/vi.json (100%) rename {src => source/src}/public/twitch/video.js/lang/zh-CN.js (100%) rename {src => source/src}/public/twitch/video.js/lang/zh-CN.json (100%) rename {src => source/src}/public/twitch/video.js/lang/zh-Hans.js (100%) rename {src => source/src}/public/twitch/video.js/lang/zh-Hans.json (100%) rename {src => source/src}/public/twitch/video.js/lang/zh-Hant.js (100%) rename {src => source/src}/public/twitch/video.js/lang/zh-Hant.json (100%) rename {src => source/src}/public/twitch/video.js/lang/zh-TW.js (100%) rename {src => source/src}/public/twitch/video.js/lang/zh-TW.json (100%) rename {src => source/src}/public/twitch/video.js/types/big-play-button.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/big-play-button.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/button.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/button.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/clickable-component.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/clickable-component.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/close-button.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/close-button.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/component.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/component.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/consts/errors.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/consts/errors.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/audio-track-controls/audio-track-button.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/audio-track-controls/audio-track-button.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/audio-track-controls/audio-track-menu-item.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/audio-track-controls/audio-track-menu-item.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/control-bar.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/control-bar.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/fullscreen-toggle.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/fullscreen-toggle.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/live-display.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/live-display.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/mute-toggle.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/mute-toggle.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/picture-in-picture-toggle.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/picture-in-picture-toggle.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/play-toggle.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/play-toggle.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/playback-rate-menu/playback-rate-menu-button.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/playback-rate-menu/playback-rate-menu-button.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/playback-rate-menu/playback-rate-menu-item.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/playback-rate-menu/playback-rate-menu-item.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/progress-control/load-progress-bar.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/progress-control/load-progress-bar.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/progress-control/mouse-time-display.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/progress-control/mouse-time-display.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/progress-control/play-progress-bar.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/progress-control/play-progress-bar.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/progress-control/progress-control.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/progress-control/progress-control.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/progress-control/seek-bar.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/progress-control/seek-bar.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/progress-control/time-tooltip.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/progress-control/time-tooltip.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/seek-to-live.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/seek-to-live.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/skip-buttons/skip-backward.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/skip-buttons/skip-backward.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/skip-buttons/skip-forward.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/skip-buttons/skip-forward.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/spacer-controls/custom-control-spacer.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/spacer-controls/custom-control-spacer.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/spacer-controls/spacer.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/spacer-controls/spacer.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/text-track-controls/caption-settings-menu-item.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/text-track-controls/caption-settings-menu-item.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/text-track-controls/captions-button.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/text-track-controls/captions-button.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/text-track-controls/chapters-button.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/text-track-controls/chapters-button.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/text-track-controls/chapters-track-menu-item.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/text-track-controls/chapters-track-menu-item.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/text-track-controls/descriptions-button.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/text-track-controls/descriptions-button.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/text-track-controls/off-text-track-menu-item.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/text-track-controls/off-text-track-menu-item.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/text-track-controls/subs-caps-button.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/text-track-controls/subs-caps-button.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/text-track-controls/subs-caps-menu-item.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/text-track-controls/subs-caps-menu-item.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/text-track-controls/subtitles-button.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/text-track-controls/subtitles-button.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/text-track-controls/text-track-button.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/text-track-controls/text-track-button.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/text-track-controls/text-track-menu-item.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/text-track-controls/text-track-menu-item.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/time-controls/current-time-display.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/time-controls/current-time-display.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/time-controls/duration-display.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/time-controls/duration-display.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/time-controls/remaining-time-display.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/time-controls/remaining-time-display.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/time-controls/time-display.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/time-controls/time-display.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/time-controls/time-divider.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/time-controls/time-divider.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/track-button.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/track-button.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/volume-control/check-mute-support.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/volume-control/check-mute-support.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/volume-control/check-volume-support.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/volume-control/check-volume-support.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/volume-control/mouse-volume-level-display.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/volume-control/mouse-volume-level-display.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/volume-control/volume-bar.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/volume-control/volume-bar.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/volume-control/volume-control.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/volume-control/volume-control.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/volume-control/volume-level-tooltip.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/volume-control/volume-level-tooltip.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/volume-control/volume-level.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/volume-control/volume-level.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/volume-panel.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/control-bar/volume-panel.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/debug.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/debug.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/error-display.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/error-display.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/event-target.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/event-target.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/fullscreen-api.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/fullscreen-api.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/index.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/index.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/live-tracker.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/live-tracker.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/loading-spinner.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/loading-spinner.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/media-error.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/media-error.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/menu/menu-button.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/menu/menu-button.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/menu/menu-item.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/menu/menu-item.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/menu/menu-keys.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/menu/menu-keys.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/menu/menu.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/menu/menu.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/mixins/evented.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/mixins/evented.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/mixins/stateful.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/mixins/stateful.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/modal-dialog.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/modal-dialog.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/player.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/player.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/plugin.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/plugin.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/poster-image.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/poster-image.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/resize-manager.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/resize-manager.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/setup.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/setup.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/slider/slider.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/slider/slider.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/tech/html5.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/tech/html5.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/tech/loader.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/tech/loader.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/tech/middleware.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/tech/middleware.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/tech/setup-sourceset.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/tech/setup-sourceset.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/tech/tech.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/tech/tech.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/title-bar.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/title-bar.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/audio-track-list.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/audio-track-list.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/audio-track.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/audio-track.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/html-track-element-list.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/html-track-element-list.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/html-track-element.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/html-track-element.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/text-track-cue-list.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/text-track-cue-list.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/text-track-display.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/text-track-display.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/text-track-list-converter.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/text-track-list-converter.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/text-track-list.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/text-track-list.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/text-track-settings.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/text-track-settings.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/text-track.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/text-track.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/track-enums.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/track-enums.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/track-list.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/track-list.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/track-types.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/track-types.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/track.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/track.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/video-track-list.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/video-track-list.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/video-track.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/tracks/video-track.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/utils/browser.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/utils/browser.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/utils/buffer.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/utils/buffer.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/utils/create-logger.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/utils/create-logger.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/utils/deprecate.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/utils/deprecate.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/utils/dom-data.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/utils/dom-data.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/utils/dom.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/utils/dom.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/utils/events.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/utils/events.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/utils/filter-source.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/utils/filter-source.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/utils/fn.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/utils/fn.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/utils/guid.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/utils/guid.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/utils/hooks.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/utils/hooks.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/utils/log.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/utils/log.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/utils/mimetypes.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/utils/mimetypes.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/utils/num.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/utils/num.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/utils/obj.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/utils/obj.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/utils/promise.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/utils/promise.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/utils/str.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/utils/str.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/utils/stylesheet.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/utils/stylesheet.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/utils/time.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/utils/time.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/utils/url.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/utils/url.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/types/video.d.ts (100%) rename {src => source/src}/public/twitch/video.js/types/video.d.ts.map (100%) rename {src => source/src}/public/twitch/video.js/video-js.css (100%) rename {src => source/src}/public/twitch/video.js/video-js.min.css (100%) rename {src => source/src}/public/twitch/video.js/video.cjs.js (100%) rename {src => source/src}/public/twitch/video.js/video.es.js (100%) rename {src => source/src}/public/twitch/video.js/video.js (100%) rename {src => source/src}/public/twitch/video.js/video.min.js (100%) rename {src => source/src}/styles/embed.scss (100%) rename {src => source/src}/styles/form.scss (100%) rename {src => source/src}/styles/index.scss (100%) rename {src => source/src}/styles/mobile.scss (100%) rename {src => source/src}/styles/player.scss (100%) rename {src => source/src}/styles/video.scss (100%) rename {src => source/src/tools}/data/discover.json (100%) rename {src => source/src/tools}/library/supabase.ts (100%) rename {src => source/src/tools}/utilities/GetConfig.js (100%) rename astro-i18next.config.mjs => source/translate.mjs (100%) diff --git a/.gitignore b/.gitignore index c09a35f..503fa1a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,7 @@ -# build output -dist/ - # generated types -.astro/ +source/.astro +source/node_modules +.minpluto/generated # dependencies node_modules/ @@ -13,18 +12,16 @@ yarn-debug.log* yarn-error.log* pnpm-debug.log* - # environment variables -.env -.env.production +source/.env +source/.env.production # macOS-specific files .DS_Store # i18n -/src/pages/en/ -/src/pages/jp/ -/src/pages/ru/ +/source/src/pages/en/ +/source/src/pages/jp/ +/source/src/pages/ru/ # other -supabase/ \ No newline at end of file diff --git a/instances.json b/.minpluto/Instances.json similarity index 100% rename from instances.json rename to .minpluto/Instances.json diff --git a/.minpluto/automation/drone.yml b/.minpluto/automation/drone.yml new file mode 100644 index 0000000..e69de29 diff --git a/.minpluto/automation/github.yml b/.minpluto/automation/github.yml new file mode 100644 index 0000000..e69de29 diff --git a/.dockerignore b/.minpluto/docker/.dockerignore similarity index 100% rename from .dockerignore rename to .minpluto/docker/.dockerignore diff --git a/Dockerfile b/.minpluto/docker/Dockerfile similarity index 74% rename from Dockerfile rename to .minpluto/docker/Dockerfile index 07315e0..3908246 100755 --- a/Dockerfile +++ b/.minpluto/docker/Dockerfile @@ -10,4 +10,4 @@ RUN npm run build ENV HOST=0.0.0.0 ENV PORT=1930 EXPOSE 1930 -CMD node ./dist/server/entry.mjs \ No newline at end of file +CMD node ./.minpluto/generated/astro/dist/server/entry.mjs \ No newline at end of file diff --git a/docker-compose.yml b/.minpluto/docker/docker-compose.yml similarity index 100% rename from docker-compose.yml rename to .minpluto/docker/docker-compose.yml diff --git a/.minpluto/docker/supabase/.env b/.minpluto/docker/supabase/.env new file mode 100755 index 0000000..b675925 --- /dev/null +++ b/.minpluto/docker/supabase/.env @@ -0,0 +1,107 @@ +########### +# Docker Volumes +# All folders provided in `./supabase-volume/` must be included +########### +SUPABASE_ENTIRE_VOLUME="./supabase-volume/" + +############ +# Secrets +# YOU MUST CHANGE THESE BEFORE GOING INTO PRODUCTION +############ + +POSTGRES_PASSWORD=5lgHamV44d8D1GN9LRS6b44VxREi4692 +JWT_SECRET=paxDX2xE00qFa4I1r6PKe15nIkB089I4 +ANON_KEY=9X43H6LKq3115zmZhZj95f2IJ104a603 +SERVICE_ROLE_KEY=K2G792rYBZR0kZvw9Zp6182zAwzxsdas +DASHBOARD_USERNAME=mp_admin +DASHBOARD_PASSWORD=ez116oqVWd4wHZUQNbgW3fA0m958FN09 + +############ +# Database - You can change these to any PostgreSQL database that has logical replication enabled. +############ + +# default user is postgres +POSTGRES_HOST=db +POSTGRES_DB=postgres +POSTGRES_PORT=1945 + +############ +# API Proxy - Configuration for the Kong Reverse proxy. +############ + +KONG_HTTP_PORT=1942 +KONG_HTTPS_PORT=1943 + +############ +# API - Configuration for PostgREST. +############ + +PGRST_DB_SCHEMAS=public,storage,graphql_public + +############ +# Auth - Configuration for the GoTrue authentication server. +############ + +## General +SITE_URL=http://localhost:1930 +ADDITIONAL_REDIRECT_URLS= +JWT_EXPIRY=3600 +DISABLE_SIGNUP=false +API_EXTERNAL_URL=https://db.minpluto.org + +## Mailer Config +MAILER_URLPATHS_CONFIRMATION="/auth/v1/verify" +MAILER_URLPATHS_INVITE="/auth/v1/verify" +MAILER_URLPATHS_RECOVERY="/auth/v1/verify" +MAILER_URLPATHS_EMAIL_CHANGE="/auth/v1/verify" + +## Email auth +ENABLE_EMAIL_SIGNUP=true +ENABLE_EMAIL_AUTOCONFIRM=false +SMTP_ADMIN_EMAIL=no-reply@sudovanilla.org +SMTP_HOST=smtp.resend.com +SMTP_PORT=587 +SMTP_USER=resend +SMTP_PASS=re_XLbiDxHd_9Yucx4y9EwiacKgHrRowfJVU +SMTP_SENDER_NAME=MinPluto +ENABLE_ANONYMOUS_USERS=true + +## Phone auth +ENABLE_PHONE_SIGNUP=false +ENABLE_PHONE_AUTOCONFIRM=false + +############ +# Studio - Configuration for the Dashboard +############ + +STUDIO_DEFAULT_ORGANIZATION=Default Organization +STUDIO_DEFAULT_PROJECT=Default Project + +STUDIO_PORT=1944 +SUPABASE_PUBLIC_URL=http://localhost:8000 + +# Enable webp support +IMGPROXY_ENABLE_WEBP_DETECTION=true + +############ +# Functions - Configuration for Functions +############ +# NOTE: VERIFY_JWT applies to all functions. Per-function VERIFY_JWT is not supported yet. +FUNCTIONS_VERIFY_JWT=false + +############ +# Logs - Configuration for Logflare +# Please refer to https://supabase.com/docs/reference/self-hosting-analytics/introduction +############ + +LOGFLARE_LOGGER_BACKEND_API_KEY=your-super-secret-and-long-logflare-key + +# Change vector.toml sinks to reflect this change +LOGFLARE_API_KEY=your-super-secret-and-long-logflare-key + +# Docker socket location - this value will differ depending on your OS +DOCKER_SOCKET_LOCATION=/var/run/docker.sock + +# Google Cloud Project details +GOOGLE_PROJECT_ID=GOOGLE_PROJECT_ID +GOOGLE_PROJECT_NUMBER=GOOGLE_PROJECT_NUMBER \ No newline at end of file diff --git a/.minpluto/docker/supabase/docker-compose.yml b/.minpluto/docker/supabase/docker-compose.yml new file mode 100755 index 0000000..bbb8159 --- /dev/null +++ b/.minpluto/docker/supabase/docker-compose.yml @@ -0,0 +1,428 @@ +# Usage +# Start: docker compose up +# With helpers: docker compose -f docker-compose.yml -f ./dev/docker-compose.dev.yml up +# Stop: docker compose down +# Destroy: docker compose -f docker-compose.yml -f ./dev/docker-compose.dev.yml down -v --remove-orphans + +name: supabase + +services: + studio: + container_name: supabase-studio + image: supabase/studio:20240701-05dfbec + restart: unless-stopped + healthcheck: + test: + [ + "CMD", + "node", + "-e", + "require('http').get('http://localhost:3000/api/profile', (r) => {if (r.statusCode !== 200) throw new Error(r.statusCode)})" + ] + timeout: 5s + interval: 5s + retries: 3 + depends_on: + analytics: + condition: service_healthy + environment: + STUDIO_PG_META_URL: http://meta:8080 + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + + DEFAULT_ORGANIZATION_NAME: ${STUDIO_DEFAULT_ORGANIZATION} + DEFAULT_PROJECT_NAME: ${STUDIO_DEFAULT_PROJECT} + + SUPABASE_URL: http://kong:8000 + SUPABASE_PUBLIC_URL: ${SUPABASE_PUBLIC_URL} + SUPABASE_ANON_KEY: ${ANON_KEY} + SUPABASE_SERVICE_KEY: ${SERVICE_ROLE_KEY} + AUTH_JWT_SECRET: ${JWT_SECRET} + + LOGFLARE_API_KEY: ${LOGFLARE_API_KEY} + LOGFLARE_URL: http://analytics:4000 + NEXT_PUBLIC_ENABLE_LOGS: true + # Comment to use Big Query backend for analytics + NEXT_ANALYTICS_BACKEND_PROVIDER: postgres + # Uncomment to use Big Query backend for analytics + # NEXT_ANALYTICS_BACKEND_PROVIDER: bigquery + + kong: + container_name: supabase-kong + image: kong:2.8.1 + restart: unless-stopped + # https://unix.stackexchange.com/a/294837 + entrypoint: bash -c 'eval "echo \"$$(cat ~/temp.yml)\"" > ~/kong.yml && /docker-entrypoint.sh kong docker-start' + ports: + - ${KONG_HTTP_PORT}:8000/tcp + - ${KONG_HTTPS_PORT}:8443/tcp + depends_on: + analytics: + condition: service_healthy + environment: + KONG_DATABASE: "off" + KONG_DECLARATIVE_CONFIG: /home/kong/kong.yml + # https://github.com/supabase/cli/issues/14 + KONG_DNS_ORDER: LAST,A,CNAME + KONG_PLUGINS: request-transformer,cors,key-auth,acl,basic-auth + KONG_NGINX_PROXY_PROXY_BUFFER_SIZE: 160k + KONG_NGINX_PROXY_PROXY_BUFFERS: 64 160k + SUPABASE_ANON_KEY: ${ANON_KEY} + SUPABASE_SERVICE_KEY: ${SERVICE_ROLE_KEY} + DASHBOARD_USERNAME: ${DASHBOARD_USERNAME} + DASHBOARD_PASSWORD: ${DASHBOARD_PASSWORD} + volumes: + # https://github.com/supabase/supabase/issues/12661 + - ./volumes/api/kong.yml:/home/kong/temp.yml:ro + + auth: + container_name: supabase-auth + image: supabase/gotrue:v2.151.0 + depends_on: + db: + # Disable this if you are using an external Postgres database + condition: service_healthy + analytics: + condition: service_healthy + healthcheck: + test: + [ + "CMD", + "wget", + "--no-verbose", + "--tries=1", + "--spider", + "http://localhost:9999/health" + ] + timeout: 5s + interval: 5s + retries: 3 + restart: unless-stopped + environment: + GOTRUE_API_HOST: 0.0.0.0 + GOTRUE_API_PORT: 9999 + API_EXTERNAL_URL: ${API_EXTERNAL_URL} + + GOTRUE_DB_DRIVER: postgres + GOTRUE_DB_DATABASE_URL: postgres://supabase_auth_admin:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB} + + GOTRUE_SITE_URL: ${SITE_URL} + GOTRUE_URI_ALLOW_LIST: ${ADDITIONAL_REDIRECT_URLS} + GOTRUE_DISABLE_SIGNUP: ${DISABLE_SIGNUP} + + GOTRUE_JWT_ADMIN_ROLES: service_role + GOTRUE_JWT_AUD: authenticated + GOTRUE_JWT_DEFAULT_GROUP_NAME: authenticated + GOTRUE_JWT_EXP: ${JWT_EXPIRY} + GOTRUE_JWT_SECRET: ${JWT_SECRET} + + GOTRUE_EXTERNAL_EMAIL_ENABLED: ${ENABLE_EMAIL_SIGNUP} + GOTRUE_EXTERNAL_ANONYMOUS_USERS_ENABLED: ${ENABLE_ANONYMOUS_USERS} + GOTRUE_MAILER_AUTOCONFIRM: ${ENABLE_EMAIL_AUTOCONFIRM} + # GOTRUE_MAILER_SECURE_EMAIL_CHANGE_ENABLED: true + # GOTRUE_SMTP_MAX_FREQUENCY: 1s + GOTRUE_SMTP_ADMIN_EMAIL: ${SMTP_ADMIN_EMAIL} + GOTRUE_SMTP_HOST: ${SMTP_HOST} + GOTRUE_SMTP_PORT: ${SMTP_PORT} + GOTRUE_SMTP_USER: ${SMTP_USER} + GOTRUE_SMTP_PASS: ${SMTP_PASS} + GOTRUE_SMTP_SENDER_NAME: ${SMTP_SENDER_NAME} + GOTRUE_MAILER_URLPATHS_INVITE: ${MAILER_URLPATHS_INVITE} + GOTRUE_MAILER_URLPATHS_CONFIRMATION: ${MAILER_URLPATHS_CONFIRMATION} + GOTRUE_MAILER_URLPATHS_RECOVERY: ${MAILER_URLPATHS_RECOVERY} + GOTRUE_MAILER_URLPATHS_EMAIL_CHANGE: ${MAILER_URLPATHS_EMAIL_CHANGE} + + GOTRUE_EXTERNAL_PHONE_ENABLED: ${ENABLE_PHONE_SIGNUP} + GOTRUE_SMS_AUTOCONFIRM: ${ENABLE_PHONE_AUTOCONFIRM} + # Uncomment to enable custom access token hook. You'll need to create a public.custom_access_token_hook function and grant necessary permissions. + # See: https://supabase.com/docs/guides/auth/auth-hooks#hook-custom-access-token for details + # GOTRUE_HOOK_CUSTOM_ACCESS_TOKEN_ENABLED="true" + # GOTRUE_HOOK_CUSTOM_ACCESS_TOKEN_URI="pg-functions://postgres/public/custom_access_token_hook" + + # GOTRUE_HOOK_MFA_VERIFICATION_ATTEMPT_ENABLED="true" + # GOTRUE_HOOK_MFA_VERIFICATION_ATTEMPT_URI="pg-functions://postgres/public/mfa_verification_attempt" + + # GOTRUE_HOOK_PASSWORD_VERIFICATION_ATTEMPT_ENABLED="true" + # GOTRUE_HOOK_PASSWORD_VERIFICATION_ATTEMPT_URI="pg-functions://postgres/public/password_verification_attempt" + + + + + rest: + container_name: supabase-rest + image: postgrest/postgrest:v12.2.0 + depends_on: + db: + # Disable this if you are using an external Postgres database + condition: service_healthy + analytics: + condition: service_healthy + restart: unless-stopped + environment: + PGRST_DB_URI: postgres://authenticator:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB} + PGRST_DB_SCHEMAS: ${PGRST_DB_SCHEMAS} + PGRST_DB_ANON_ROLE: anon + PGRST_JWT_SECRET: ${JWT_SECRET} + PGRST_DB_USE_LEGACY_GUCS: "false" + PGRST_APP_SETTINGS_JWT_SECRET: ${JWT_SECRET} + PGRST_APP_SETTINGS_JWT_EXP: ${JWT_EXPIRY} + command: "postgrest" + + realtime: + # This container name looks inconsistent but is correct because realtime constructs tenant id by parsing the subdomain + container_name: realtime-dev.supabase-realtime + image: supabase/realtime:v2.29.15 + depends_on: + db: + # Disable this if you are using an external Postgres database + condition: service_healthy + analytics: + condition: service_healthy + healthcheck: + test: + [ + "CMD", + "curl", + "-sSfL", + "--head", + "-o", + "/dev/null", + "-H", + "Authorization: Bearer ${ANON_KEY}", + "http://localhost:4000/api/tenants/realtime-dev/health" + ] + timeout: 5s + interval: 5s + retries: 3 + restart: unless-stopped + environment: + PORT: 4000 + DB_HOST: ${POSTGRES_HOST} + DB_PORT: ${POSTGRES_PORT} + DB_USER: supabase_admin + DB_PASSWORD: ${POSTGRES_PASSWORD} + DB_NAME: ${POSTGRES_DB} + DB_AFTER_CONNECT_QUERY: 'SET search_path TO _realtime' + DB_ENC_KEY: supabaserealtime + API_JWT_SECRET: ${JWT_SECRET} + SECRET_KEY_BASE: UpNVntn3cDxHJpq99YMc1T1AQgQpc8kfYTuRgBiYa15BLrx8etQoXz3gZv1/u2oq + ERL_AFLAGS: -proto_dist inet_tcp + DNS_NODES: "''" + RLIMIT_NOFILE: "10000" + APP_NAME: realtime + SEED_SELF_HOST: true + + # To use S3 backed storage: docker compose -f docker-compose.yml -f docker-compose.s3.yml up + storage: + container_name: supabase-storage + image: supabase/storage-api:v1.0.6 + depends_on: + db: + # Disable this if you are using an external Postgres database + condition: service_healthy + rest: + condition: service_started + imgproxy: + condition: service_started + healthcheck: + test: + [ + "CMD", + "wget", + "--no-verbose", + "--tries=1", + "--spider", + "http://localhost:5000/status" + ] + timeout: 5s + interval: 5s + retries: 3 + restart: unless-stopped + environment: + ANON_KEY: ${ANON_KEY} + SERVICE_KEY: ${SERVICE_ROLE_KEY} + POSTGREST_URL: http://rest:3000 + PGRST_JWT_SECRET: ${JWT_SECRET} + DATABASE_URL: postgres://supabase_storage_admin:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB} + FILE_SIZE_LIMIT: 52428800 + STORAGE_BACKEND: file + FILE_STORAGE_BACKEND_PATH: /var/lib/storage + TENANT_ID: stub + # TODO: https://github.com/supabase/storage-api/issues/55 + REGION: stub + GLOBAL_S3_BUCKET: stub + ENABLE_IMAGE_TRANSFORMATION: "true" + IMGPROXY_URL: http://imgproxy:5001 + volumes: + - ./volumes/storage:/var/lib/storage:z + + imgproxy: + container_name: supabase-imgproxy + image: darthsim/imgproxy:v3.8.0 + healthcheck: + test: [ "CMD", "imgproxy", "health" ] + timeout: 5s + interval: 5s + retries: 3 + environment: + IMGPROXY_BIND: ":5001" + IMGPROXY_LOCAL_FILESYSTEM_ROOT: / + IMGPROXY_USE_ETAG: "true" + IMGPROXY_ENABLE_WEBP_DETECTION: ${IMGPROXY_ENABLE_WEBP_DETECTION} + volumes: + - ./volumes/storage:/var/lib/storage:z + + meta: + container_name: supabase-meta + image: supabase/postgres-meta:v0.83.2 + depends_on: + db: + # Disable this if you are using an external Postgres database + condition: service_healthy + analytics: + condition: service_healthy + restart: unless-stopped + environment: + PG_META_PORT: 8080 + PG_META_DB_HOST: ${POSTGRES_HOST} + PG_META_DB_PORT: ${POSTGRES_PORT} + PG_META_DB_NAME: ${POSTGRES_DB} + PG_META_DB_USER: supabase_admin + PG_META_DB_PASSWORD: ${POSTGRES_PASSWORD} + + functions: + container_name: supabase-edge-functions + image: supabase/edge-runtime:v1.54.10 + restart: unless-stopped + depends_on: + analytics: + condition: service_healthy + environment: + JWT_SECRET: ${JWT_SECRET} + SUPABASE_URL: http://kong:8000 + SUPABASE_ANON_KEY: ${ANON_KEY} + SUPABASE_SERVICE_ROLE_KEY: ${SERVICE_ROLE_KEY} + SUPABASE_DB_URL: postgresql://postgres:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB} + # TODO: Allow configuring VERIFY_JWT per function. This PR might help: https://github.com/supabase/cli/pull/786 + VERIFY_JWT: "${FUNCTIONS_VERIFY_JWT}" + volumes: + - ./volumes/functions:/home/deno/functions:Z + command: + - start + - --main-service + - /home/deno/functions/main + + analytics: + container_name: supabase-analytics + image: supabase/logflare:1.4.0 + healthcheck: + test: [ "CMD", "curl", "http://localhost:4000/health" ] + timeout: 5s + interval: 5s + retries: 10 + restart: unless-stopped + depends_on: + db: + # Disable this if you are using an external Postgres database + condition: service_healthy + # Uncomment to use Big Query backend for analytics + # volumes: + # - type: bind + # source: ${PWD}/gcloud.json + # target: /opt/app/rel/logflare/bin/gcloud.json + # read_only: true + environment: + LOGFLARE_NODE_HOST: 127.0.0.1 + DB_USERNAME: supabase_admin + DB_DATABASE: ${POSTGRES_DB} + DB_HOSTNAME: ${POSTGRES_HOST} + DB_PORT: ${POSTGRES_PORT} + DB_PASSWORD: ${POSTGRES_PASSWORD} + DB_SCHEMA: _analytics + LOGFLARE_API_KEY: ${LOGFLARE_API_KEY} + LOGFLARE_SINGLE_TENANT: true + LOGFLARE_SUPABASE_MODE: true + LOGFLARE_MIN_CLUSTER_SIZE: 1 + + # Comment variables to use Big Query backend for analytics + POSTGRES_BACKEND_URL: postgresql://supabase_admin:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB} + POSTGRES_BACKEND_SCHEMA: _analytics + LOGFLARE_FEATURE_FLAG_OVERRIDE: multibackend=true + # Uncomment to use Big Query backend for analytics + # GOOGLE_PROJECT_ID: ${GOOGLE_PROJECT_ID} + # GOOGLE_PROJECT_NUMBER: ${GOOGLE_PROJECT_NUMBER} + ports: + - 4000:4000 + + # Comment out everything below this point if you are using an external Postgres database + db: + container_name: supabase-db + image: supabase/postgres:15.1.1.61 + healthcheck: + test: pg_isready -U postgres -h localhost + interval: 5s + timeout: 5s + retries: 10 + depends_on: + vector: + condition: service_healthy + command: + - postgres + - -c + - config_file=/etc/postgresql/postgresql.conf + - -c + - log_min_messages=fatal # prevents Realtime polling queries from appearing in logs + restart: unless-stopped + ports: + # Pass down internal port because it's set dynamically by other services + - ${POSTGRES_PORT}:${POSTGRES_PORT} + environment: + POSTGRES_HOST: /var/run/postgresql + PGPORT: ${POSTGRES_PORT} + POSTGRES_PORT: ${POSTGRES_PORT} + PGPASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + PGDATABASE: ${POSTGRES_DB} + POSTGRES_DB: ${POSTGRES_DB} + JWT_SECRET: ${JWT_SECRET} + JWT_EXP: ${JWT_EXPIRY} + volumes: + - ./volumes/db/realtime.sql:/docker-entrypoint-initdb.d/migrations/99-realtime.sql:Z + # Must be superuser to create event trigger + - ./volumes/db/webhooks.sql:/docker-entrypoint-initdb.d/init-scripts/98-webhooks.sql:Z + # Must be superuser to alter reserved role + - ./volumes/db/roles.sql:/docker-entrypoint-initdb.d/init-scripts/99-roles.sql:Z + # Initialize the database settings with JWT_SECRET and JWT_EXP + - ./volumes/db/jwt.sql:/docker-entrypoint-initdb.d/init-scripts/99-jwt.sql:Z + # PGDATA directory is persisted between restarts + - ./volumes/db/data:/var/lib/postgresql/data:Z + # Changes required for Analytics support + - ./volumes/db/logs.sql:/docker-entrypoint-initdb.d/migrations/99-logs.sql:Z + # Use named volume to persist pgsodium decryption key between restarts + - db-config:/etc/postgresql-custom + + vector: + container_name: supabase-vector + image: timberio/vector:0.28.1-alpine + healthcheck: + test: + [ + + "CMD", + "wget", + "--no-verbose", + "--tries=1", + "--spider", + "http://vector:9001/health" + ] + timeout: 5s + interval: 5s + retries: 3 + volumes: + - ./volumes/logs/vector.yml:/etc/vector/vector.yml:ro + - ${DOCKER_SOCKET_LOCATION}:/var/run/docker.sock:ro + environment: + LOGFLARE_API_KEY: ${LOGFLARE_API_KEY} + command: [ "--config", "etc/vector/vector.yml" ] + +volumes: + db-config: diff --git a/.minpluto/docker/supabase/volumes/api/kong.yml b/.minpluto/docker/supabase/volumes/api/kong.yml new file mode 100755 index 0000000..7abf425 --- /dev/null +++ b/.minpluto/docker/supabase/volumes/api/kong.yml @@ -0,0 +1,241 @@ +_format_version: '2.1' +_transform: true + +### +### Consumers / Users +### +consumers: + - username: DASHBOARD + - username: anon + keyauth_credentials: + - key: $SUPABASE_ANON_KEY + - username: service_role + keyauth_credentials: + - key: $SUPABASE_SERVICE_KEY + +### +### Access Control List +### +acls: + - consumer: anon + group: anon + - consumer: service_role + group: admin + +### +### Dashboard credentials +### +basicauth_credentials: + - consumer: DASHBOARD + username: $DASHBOARD_USERNAME + password: $DASHBOARD_PASSWORD + +### +### API Routes +### +services: + ## Open Auth routes + - name: auth-v1-open + url: http://auth:9999/verify + routes: + - name: auth-v1-open + strip_path: true + paths: + - /auth/v1/verify + plugins: + - name: cors + - name: auth-v1-open-callback + url: http://auth:9999/callback + routes: + - name: auth-v1-open-callback + strip_path: true + paths: + - /auth/v1/callback + plugins: + - name: cors + - name: auth-v1-open-authorize + url: http://auth:9999/authorize + routes: + - name: auth-v1-open-authorize + strip_path: true + paths: + - /auth/v1/authorize + plugins: + - name: cors + + ## Secure Auth routes + - name: auth-v1 + _comment: 'GoTrue: /auth/v1/* -> http://auth:9999/*' + url: http://auth:9999/ + routes: + - name: auth-v1-all + strip_path: true + paths: + - /auth/v1/ + plugins: + - name: cors + - name: key-auth + config: + hide_credentials: false + - name: acl + config: + hide_groups_header: true + allow: + - admin + - anon + + ## Secure REST routes + - name: rest-v1 + _comment: 'PostgREST: /rest/v1/* -> http://rest:3000/*' + url: http://rest:3000/ + routes: + - name: rest-v1-all + strip_path: true + paths: + - /rest/v1/ + plugins: + - name: cors + - name: key-auth + config: + hide_credentials: true + - name: acl + config: + hide_groups_header: true + allow: + - admin + - anon + + ## Secure GraphQL routes + - name: graphql-v1 + _comment: 'PostgREST: /graphql/v1/* -> http://rest:3000/rpc/graphql' + url: http://rest:3000/rpc/graphql + routes: + - name: graphql-v1-all + strip_path: true + paths: + - /graphql/v1 + plugins: + - name: cors + - name: key-auth + config: + hide_credentials: true + - name: request-transformer + config: + add: + headers: + - Content-Profile:graphql_public + - name: acl + config: + hide_groups_header: true + allow: + - admin + - anon + + ## Secure Realtime routes + - name: realtime-v1-ws + _comment: 'Realtime: /realtime/v1/* -> ws://realtime:4000/socket/*' + url: http://realtime-dev.supabase-realtime:4000/socket + protocol: ws + routes: + - name: realtime-v1-ws + strip_path: true + paths: + - /realtime/v1/ + plugins: + - name: cors + - name: key-auth + config: + hide_credentials: false + - name: acl + config: + hide_groups_header: true + allow: + - admin + - anon + - name: realtime-v1-rest + _comment: 'Realtime: /realtime/v1/* -> ws://realtime:4000/socket/*' + url: http://realtime-dev.supabase-realtime:4000/api + protocol: http + routes: + - name: realtime-v1-rest + strip_path: true + paths: + - /realtime/v1/api + plugins: + - name: cors + - name: key-auth + config: + hide_credentials: false + - name: acl + config: + hide_groups_header: true + allow: + - admin + - anon + ## Storage routes: the storage server manages its own auth + - name: storage-v1 + _comment: 'Storage: /storage/v1/* -> http://storage:5000/*' + url: http://storage:5000/ + routes: + - name: storage-v1-all + strip_path: true + paths: + - /storage/v1/ + plugins: + - name: cors + + ## Edge Functions routes + - name: functions-v1 + _comment: 'Edge Functions: /functions/v1/* -> http://functions:9000/*' + url: http://functions:9000/ + routes: + - name: functions-v1-all + strip_path: true + paths: + - /functions/v1/ + plugins: + - name: cors + + ## Analytics routes + - name: analytics-v1 + _comment: 'Analytics: /analytics/v1/* -> http://logflare:4000/*' + url: http://analytics:4000/ + routes: + - name: analytics-v1-all + strip_path: true + paths: + - /analytics/v1/ + + ## Secure Database routes + - name: meta + _comment: 'pg-meta: /pg/* -> http://pg-meta:8080/*' + url: http://meta:8080/ + routes: + - name: meta-all + strip_path: true + paths: + - /pg/ + plugins: + - name: key-auth + config: + hide_credentials: false + - name: acl + config: + hide_groups_header: true + allow: + - admin + + ## Protected Dashboard - catch all remaining routes + - name: dashboard + _comment: 'Studio: /* -> http://studio:3000/*' + url: http://studio:3000/ + routes: + - name: dashboard-all + strip_path: true + paths: + - / + plugins: + - name: cors + - name: basic-auth + config: + hide_credentials: true diff --git a/.minpluto/docker/supabase/volumes/db/init/data.sql b/.minpluto/docker/supabase/volumes/db/init/data.sql new file mode 100755 index 0000000..e69de29 diff --git a/.minpluto/docker/supabase/volumes/db/jwt.sql b/.minpluto/docker/supabase/volumes/db/jwt.sql new file mode 100755 index 0000000..cfd3b16 --- /dev/null +++ b/.minpluto/docker/supabase/volumes/db/jwt.sql @@ -0,0 +1,5 @@ +\set jwt_secret `echo "$JWT_SECRET"` +\set jwt_exp `echo "$JWT_EXP"` + +ALTER DATABASE postgres SET "app.settings.jwt_secret" TO :'jwt_secret'; +ALTER DATABASE postgres SET "app.settings.jwt_exp" TO :'jwt_exp'; diff --git a/.minpluto/docker/supabase/volumes/db/logs.sql b/.minpluto/docker/supabase/volumes/db/logs.sql new file mode 100755 index 0000000..22fc247 --- /dev/null +++ b/.minpluto/docker/supabase/volumes/db/logs.sql @@ -0,0 +1,4 @@ +\set pguser `echo "$POSTGRES_USER"` + +create schema if not exists _analytics; +alter schema _analytics owner to :pguser; diff --git a/.minpluto/docker/supabase/volumes/db/realtime.sql b/.minpluto/docker/supabase/volumes/db/realtime.sql new file mode 100755 index 0000000..4d4b9ff --- /dev/null +++ b/.minpluto/docker/supabase/volumes/db/realtime.sql @@ -0,0 +1,4 @@ +\set pguser `echo "$POSTGRES_USER"` + +create schema if not exists _realtime; +alter schema _realtime owner to :pguser; diff --git a/.minpluto/docker/supabase/volumes/db/roles.sql b/.minpluto/docker/supabase/volumes/db/roles.sql new file mode 100755 index 0000000..8f7161a --- /dev/null +++ b/.minpluto/docker/supabase/volumes/db/roles.sql @@ -0,0 +1,8 @@ +-- NOTE: change to your own passwords for production environments +\set pgpass `echo "$POSTGRES_PASSWORD"` + +ALTER USER authenticator WITH PASSWORD :'pgpass'; +ALTER USER pgbouncer WITH PASSWORD :'pgpass'; +ALTER USER supabase_auth_admin WITH PASSWORD :'pgpass'; +ALTER USER supabase_functions_admin WITH PASSWORD :'pgpass'; +ALTER USER supabase_storage_admin WITH PASSWORD :'pgpass'; diff --git a/.minpluto/docker/supabase/volumes/db/webhooks.sql b/.minpluto/docker/supabase/volumes/db/webhooks.sql new file mode 100755 index 0000000..5837b86 --- /dev/null +++ b/.minpluto/docker/supabase/volumes/db/webhooks.sql @@ -0,0 +1,208 @@ +BEGIN; + -- Create pg_net extension + CREATE EXTENSION IF NOT EXISTS pg_net SCHEMA extensions; + -- Create supabase_functions schema + CREATE SCHEMA supabase_functions AUTHORIZATION supabase_admin; + GRANT USAGE ON SCHEMA supabase_functions TO postgres, anon, authenticated, service_role; + ALTER DEFAULT PRIVILEGES IN SCHEMA supabase_functions GRANT ALL ON TABLES TO postgres, anon, authenticated, service_role; + ALTER DEFAULT PRIVILEGES IN SCHEMA supabase_functions GRANT ALL ON FUNCTIONS TO postgres, anon, authenticated, service_role; + ALTER DEFAULT PRIVILEGES IN SCHEMA supabase_functions GRANT ALL ON SEQUENCES TO postgres, anon, authenticated, service_role; + -- supabase_functions.migrations definition + CREATE TABLE supabase_functions.migrations ( + version text PRIMARY KEY, + inserted_at timestamptz NOT NULL DEFAULT NOW() + ); + -- Initial supabase_functions migration + INSERT INTO supabase_functions.migrations (version) VALUES ('initial'); + -- supabase_functions.hooks definition + CREATE TABLE supabase_functions.hooks ( + id bigserial PRIMARY KEY, + hook_table_id integer NOT NULL, + hook_name text NOT NULL, + created_at timestamptz NOT NULL DEFAULT NOW(), + request_id bigint + ); + CREATE INDEX supabase_functions_hooks_request_id_idx ON supabase_functions.hooks USING btree (request_id); + CREATE INDEX supabase_functions_hooks_h_table_id_h_name_idx ON supabase_functions.hooks USING btree (hook_table_id, hook_name); + COMMENT ON TABLE supabase_functions.hooks IS 'Supabase Functions Hooks: Audit trail for triggered hooks.'; + CREATE FUNCTION supabase_functions.http_request() + RETURNS trigger + LANGUAGE plpgsql + AS $function$ + DECLARE + request_id bigint; + payload jsonb; + url text := TG_ARGV[0]::text; + method text := TG_ARGV[1]::text; + headers jsonb DEFAULT '{}'::jsonb; + params jsonb DEFAULT '{}'::jsonb; + timeout_ms integer DEFAULT 1000; + BEGIN + IF url IS NULL OR url = 'null' THEN + RAISE EXCEPTION 'url argument is missing'; + END IF; + + IF method IS NULL OR method = 'null' THEN + RAISE EXCEPTION 'method argument is missing'; + END IF; + + IF TG_ARGV[2] IS NULL OR TG_ARGV[2] = 'null' THEN + headers = '{"Content-Type": "application/json"}'::jsonb; + ELSE + headers = TG_ARGV[2]::jsonb; + END IF; + + IF TG_ARGV[3] IS NULL OR TG_ARGV[3] = 'null' THEN + params = '{}'::jsonb; + ELSE + params = TG_ARGV[3]::jsonb; + END IF; + + IF TG_ARGV[4] IS NULL OR TG_ARGV[4] = 'null' THEN + timeout_ms = 1000; + ELSE + timeout_ms = TG_ARGV[4]::integer; + END IF; + + CASE + WHEN method = 'GET' THEN + SELECT http_get INTO request_id FROM net.http_get( + url, + params, + headers, + timeout_ms + ); + WHEN method = 'POST' THEN + payload = jsonb_build_object( + 'old_record', OLD, + 'record', NEW, + 'type', TG_OP, + 'table', TG_TABLE_NAME, + 'schema', TG_TABLE_SCHEMA + ); + + SELECT http_post INTO request_id FROM net.http_post( + url, + payload, + params, + headers, + timeout_ms + ); + ELSE + RAISE EXCEPTION 'method argument % is invalid', method; + END CASE; + + INSERT INTO supabase_functions.hooks + (hook_table_id, hook_name, request_id) + VALUES + (TG_RELID, TG_NAME, request_id); + + RETURN NEW; + END + $function$; + -- Supabase super admin + DO + $$ + BEGIN + IF NOT EXISTS ( + SELECT 1 + FROM pg_roles + WHERE rolname = 'supabase_functions_admin' + ) + THEN + CREATE USER supabase_functions_admin NOINHERIT CREATEROLE LOGIN NOREPLICATION; + END IF; + END + $$; + GRANT ALL PRIVILEGES ON SCHEMA supabase_functions TO supabase_functions_admin; + GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA supabase_functions TO supabase_functions_admin; + GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA supabase_functions TO supabase_functions_admin; + ALTER USER supabase_functions_admin SET search_path = "supabase_functions"; + ALTER table "supabase_functions".migrations OWNER TO supabase_functions_admin; + ALTER table "supabase_functions".hooks OWNER TO supabase_functions_admin; + ALTER function "supabase_functions".http_request() OWNER TO supabase_functions_admin; + GRANT supabase_functions_admin TO postgres; + -- Remove unused supabase_pg_net_admin role + DO + $$ + BEGIN + IF EXISTS ( + SELECT 1 + FROM pg_roles + WHERE rolname = 'supabase_pg_net_admin' + ) + THEN + REASSIGN OWNED BY supabase_pg_net_admin TO supabase_admin; + DROP OWNED BY supabase_pg_net_admin; + DROP ROLE supabase_pg_net_admin; + END IF; + END + $$; + -- pg_net grants when extension is already enabled + DO + $$ + BEGIN + IF EXISTS ( + SELECT 1 + FROM pg_extension + WHERE extname = 'pg_net' + ) + THEN + GRANT USAGE ON SCHEMA net TO supabase_functions_admin, postgres, anon, authenticated, service_role; + ALTER function net.http_get(url text, params jsonb, headers jsonb, timeout_milliseconds integer) SECURITY DEFINER; + ALTER function net.http_post(url text, body jsonb, params jsonb, headers jsonb, timeout_milliseconds integer) SECURITY DEFINER; + ALTER function net.http_get(url text, params jsonb, headers jsonb, timeout_milliseconds integer) SET search_path = net; + ALTER function net.http_post(url text, body jsonb, params jsonb, headers jsonb, timeout_milliseconds integer) SET search_path = net; + REVOKE ALL ON FUNCTION net.http_get(url text, params jsonb, headers jsonb, timeout_milliseconds integer) FROM PUBLIC; + REVOKE ALL ON FUNCTION net.http_post(url text, body jsonb, params jsonb, headers jsonb, timeout_milliseconds integer) FROM PUBLIC; + GRANT EXECUTE ON FUNCTION net.http_get(url text, params jsonb, headers jsonb, timeout_milliseconds integer) TO supabase_functions_admin, postgres, anon, authenticated, service_role; + GRANT EXECUTE ON FUNCTION net.http_post(url text, body jsonb, params jsonb, headers jsonb, timeout_milliseconds integer) TO supabase_functions_admin, postgres, anon, authenticated, service_role; + END IF; + END + $$; + -- Event trigger for pg_net + CREATE OR REPLACE FUNCTION extensions.grant_pg_net_access() + RETURNS event_trigger + LANGUAGE plpgsql + AS $$ + BEGIN + IF EXISTS ( + SELECT 1 + FROM pg_event_trigger_ddl_commands() AS ev + JOIN pg_extension AS ext + ON ev.objid = ext.oid + WHERE ext.extname = 'pg_net' + ) + THEN + GRANT USAGE ON SCHEMA net TO supabase_functions_admin, postgres, anon, authenticated, service_role; + ALTER function net.http_get(url text, params jsonb, headers jsonb, timeout_milliseconds integer) SECURITY DEFINER; + ALTER function net.http_post(url text, body jsonb, params jsonb, headers jsonb, timeout_milliseconds integer) SECURITY DEFINER; + ALTER function net.http_get(url text, params jsonb, headers jsonb, timeout_milliseconds integer) SET search_path = net; + ALTER function net.http_post(url text, body jsonb, params jsonb, headers jsonb, timeout_milliseconds integer) SET search_path = net; + REVOKE ALL ON FUNCTION net.http_get(url text, params jsonb, headers jsonb, timeout_milliseconds integer) FROM PUBLIC; + REVOKE ALL ON FUNCTION net.http_post(url text, body jsonb, params jsonb, headers jsonb, timeout_milliseconds integer) FROM PUBLIC; + GRANT EXECUTE ON FUNCTION net.http_get(url text, params jsonb, headers jsonb, timeout_milliseconds integer) TO supabase_functions_admin, postgres, anon, authenticated, service_role; + GRANT EXECUTE ON FUNCTION net.http_post(url text, body jsonb, params jsonb, headers jsonb, timeout_milliseconds integer) TO supabase_functions_admin, postgres, anon, authenticated, service_role; + END IF; + END; + $$; + COMMENT ON FUNCTION extensions.grant_pg_net_access IS 'Grants access to pg_net'; + DO + $$ + BEGIN + IF NOT EXISTS ( + SELECT 1 + FROM pg_event_trigger + WHERE evtname = 'issue_pg_net_access' + ) THEN + CREATE EVENT TRIGGER issue_pg_net_access ON ddl_command_end WHEN TAG IN ('CREATE EXTENSION') + EXECUTE PROCEDURE extensions.grant_pg_net_access(); + END IF; + END + $$; + INSERT INTO supabase_functions.migrations (version) VALUES ('20210809183423_update_grants'); + ALTER function supabase_functions.http_request() SECURITY DEFINER; + ALTER function supabase_functions.http_request() SET search_path = supabase_functions; + REVOKE ALL ON FUNCTION supabase_functions.http_request() FROM PUBLIC; + GRANT EXECUTE ON FUNCTION supabase_functions.http_request() TO postgres, anon, authenticated, service_role; +COMMIT; diff --git a/.minpluto/docker/supabase/volumes/functions/hello/index.ts b/.minpluto/docker/supabase/volumes/functions/hello/index.ts new file mode 100755 index 0000000..f1e20b9 --- /dev/null +++ b/.minpluto/docker/supabase/volumes/functions/hello/index.ts @@ -0,0 +1,16 @@ +// Follow this setup guide to integrate the Deno language server with your editor: +// https://deno.land/manual/getting_started/setup_your_environment +// This enables autocomplete, go to definition, etc. + +import { serve } from "https://deno.land/std@0.177.1/http/server.ts" + +serve(async () => { + return new Response( + `"Hello from Edge Functions!"`, + { headers: { "Content-Type": "application/json" } }, + ) +}) + +// To invoke: +// curl 'http://localhost:/functions/v1/hello' \ +// --header 'Authorization: Bearer ' diff --git a/.minpluto/docker/supabase/volumes/functions/main/index.ts b/.minpluto/docker/supabase/volumes/functions/main/index.ts new file mode 100755 index 0000000..a094010 --- /dev/null +++ b/.minpluto/docker/supabase/volumes/functions/main/index.ts @@ -0,0 +1,94 @@ +import { serve } from 'https://deno.land/std@0.131.0/http/server.ts' +import * as jose from 'https://deno.land/x/jose@v4.14.4/index.ts' + +console.log('main function started') + +const JWT_SECRET = Deno.env.get('JWT_SECRET') +const VERIFY_JWT = Deno.env.get('VERIFY_JWT') === 'true' + +function getAuthToken(req: Request) { + const authHeader = req.headers.get('authorization') + if (!authHeader) { + throw new Error('Missing authorization header') + } + const [bearer, token] = authHeader.split(' ') + if (bearer !== 'Bearer') { + throw new Error(`Auth header is not 'Bearer {token}'`) + } + return token +} + +async function verifyJWT(jwt: string): Promise { + const encoder = new TextEncoder() + const secretKey = encoder.encode(JWT_SECRET) + try { + await jose.jwtVerify(jwt, secretKey) + } catch (err) { + console.error(err) + return false + } + return true +} + +serve(async (req: Request) => { + if (req.method !== 'OPTIONS' && VERIFY_JWT) { + try { + const token = getAuthToken(req) + const isValidJWT = await verifyJWT(token) + + if (!isValidJWT) { + return new Response(JSON.stringify({ msg: 'Invalid JWT' }), { + status: 401, + headers: { 'Content-Type': 'application/json' }, + }) + } + } catch (e) { + console.error(e) + return new Response(JSON.stringify({ msg: e.toString() }), { + status: 401, + headers: { 'Content-Type': 'application/json' }, + }) + } + } + + const url = new URL(req.url) + const { pathname } = url + const path_parts = pathname.split('/') + const service_name = path_parts[1] + + if (!service_name || service_name === '') { + const error = { msg: 'missing function name in request' } + return new Response(JSON.stringify(error), { + status: 400, + headers: { 'Content-Type': 'application/json' }, + }) + } + + const servicePath = `/home/deno/functions/${service_name}` + console.error(`serving the request with ${servicePath}`) + + const memoryLimitMb = 150 + const workerTimeoutMs = 1 * 60 * 1000 + const noModuleCache = false + const importMapPath = null + const envVarsObj = Deno.env.toObject() + const envVars = Object.keys(envVarsObj).map((k) => [k, envVarsObj[k]]) + + try { + const worker = await EdgeRuntime.userWorkers.create({ + servicePath, + memoryLimitMb, + workerTimeoutMs, + noModuleCache, + importMapPath, + envVars, + }) + return await worker.fetch(req) + } catch (e) { + const error = { msg: e.toString() } + return new Response(JSON.stringify(error), { + status: 500, + headers: { 'Content-Type': 'application/json' }, + }) + } +}) diff --git a/.minpluto/docker/supabase/volumes/logs/vector.yml b/.minpluto/docker/supabase/volumes/logs/vector.yml new file mode 100755 index 0000000..cce46df --- /dev/null +++ b/.minpluto/docker/supabase/volumes/logs/vector.yml @@ -0,0 +1,232 @@ +api: + enabled: true + address: 0.0.0.0:9001 + +sources: + docker_host: + type: docker_logs + exclude_containers: + - supabase-vector + +transforms: + project_logs: + type: remap + inputs: + - docker_host + source: |- + .project = "default" + .event_message = del(.message) + .appname = del(.container_name) + del(.container_created_at) + del(.container_id) + del(.source_type) + del(.stream) + del(.label) + del(.image) + del(.host) + del(.stream) + router: + type: route + inputs: + - project_logs + route: + kong: '.appname == "supabase-kong"' + auth: '.appname == "supabase-auth"' + rest: '.appname == "supabase-rest"' + realtime: '.appname == "supabase-realtime"' + storage: '.appname == "supabase-storage"' + functions: '.appname == "supabase-functions"' + db: '.appname == "supabase-db"' + # Ignores non nginx errors since they are related with kong booting up + kong_logs: + type: remap + inputs: + - router.kong + source: |- + req, err = parse_nginx_log(.event_message, "combined") + if err == null { + .timestamp = req.timestamp + .metadata.request.headers.referer = req.referer + .metadata.request.headers.user_agent = req.agent + .metadata.request.headers.cf_connecting_ip = req.client + .metadata.request.method = req.method + .metadata.request.path = req.path + .metadata.request.protocol = req.protocol + .metadata.response.status_code = req.status + } + if err != null { + abort + } + # Ignores non nginx errors since they are related with kong booting up + kong_err: + type: remap + inputs: + - router.kong + source: |- + .metadata.request.method = "GET" + .metadata.response.status_code = 200 + parsed, err = parse_nginx_log(.event_message, "error") + if err == null { + .timestamp = parsed.timestamp + .severity = parsed.severity + .metadata.request.host = parsed.host + .metadata.request.headers.cf_connecting_ip = parsed.client + url, err = split(parsed.request, " ") + if err == null { + .metadata.request.method = url[0] + .metadata.request.path = url[1] + .metadata.request.protocol = url[2] + } + } + if err != null { + abort + } + # Gotrue logs are structured json strings which frontend parses directly. But we keep metadata for consistency. + auth_logs: + type: remap + inputs: + - router.auth + source: |- + parsed, err = parse_json(.event_message) + if err == null { + .metadata.timestamp = parsed.time + .metadata = merge!(.metadata, parsed) + } + # PostgREST logs are structured so we separate timestamp from message using regex + rest_logs: + type: remap + inputs: + - router.rest + source: |- + parsed, err = parse_regex(.event_message, r'^(?P