Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Features/supabase-companion #21

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
**/node_modules
**/dist
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SUPABASE_ANON_KEY=
SUPABASE_API_URL=
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ dist-ssr
*.local

.vercel

.env
6 changes: 6 additions & 0 deletions 40-import-meta-env.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh
# 40-import-meta-env.sh is named like that to be executed
# to follow order placed on /docker-entrypoint.d directory
# https://iendeavor.github.io/import-meta-env/guide/getting-started/introduction.html

/app/import-meta-env-alpine -x /app/.env.example -o /app/index.html || exit 1
37 changes: 37 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
FROM node:latest as build-stage

WORKDIR /app

# Install dependencies
COPY package.json yarn.lock ./
RUN yarn install

# Build the app
COPY ./ .
RUN yarn build


# Pack import-meta-env in a binary
RUN npx pkg ./node_modules/@import-meta-env/cli/bin/import-meta-env.js \
--target node18-alpine-x64 \
--output /app/dist/import-meta-env-alpine


FROM nginx:1.23.3-alpine as production-stage

# Copy the built files from the build stage
RUN mkdir /app
COPY --from=build-stage /app/dist /app
COPY --from=build-stage /app/.env.example /app/dist/import-meta-env-alpine /app

# define env variables defaults
ENV SUPABASE_ANON_KEY=
ENV SUPABASE_API_URL=


# Copy the nginx configuration file
COPY nginx.conf /etc/nginx/nginx.conf

# Copy import-meta-env injection script
# Placed the last to be executed in /docker-entrypoint.d by /docker-entrypoint.sh
COPY 40-import-meta-env.sh /docker-entrypoint.d
2 changes: 2 additions & 0 deletions components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ declare module 'vue' {
Helper: typeof import('./src/components/Helper.vue')['default']
HelperZoom: typeof import('./src/components/HelperZoom.vue')['default']
'IBx:bxNews': typeof import('~icons/bx/bx-news')['default']
'IHeroiconsSolid:ban': typeof import('~icons/heroicons-solid/ban')['default']
'IHeroiconsSolid:lightningBolt': typeof import('~icons/heroicons-solid/lightning-bolt')['default']
'IHeroiconsSolid:minusSm': typeof import('~icons/heroicons-solid/minus-sm')['default']
'IHeroiconsSolid:plusSm': typeof import('~icons/heroicons-solid/plus-sm')['default']
'IIc:baselineAutoFixHigh': typeof import('~icons/ic/baseline-auto-fix-high')['default']
Expand Down
16 changes: 16 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
version: '3.8'

services:
schema:
container_name: supabase-schema
build: .
image: supabase-schema:latest
restart: unless-stopped
ports:
- 8080:80 # host:container
environment:
# do not remove .env.example
# you can define both variables on a new .env file
# this example is defined to match ENV substitution from supabase official repo.
SUPABASE_ANON_KEY: ${ANON_KEY}
SUPABASE_API_URL: ${API_EXTERNAL_URL}
10 changes: 10 additions & 0 deletions import-meta-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Generated by '@import-meta-env/typescript'

interface ImportMetaEnv {
readonly SUPABASE_ANON_KEY: string;
readonly SUPABASE_API_URL: string;
}

interface ImportMeta {
readonly env: ImportMetaEnv;
}
2 changes: 2 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
data-website-id="0ace2abc-d7f5-4ebb-909b-0d8b101e8557"
src="https://umami-zernonia.vercel.app/umami.js"
></script>
<!-- get environment variables -->
<script>globalThis.import_meta_env=JSON.parse('"import_meta_env_placeholder"')</script>
</head>
<body>
<div id="app"></div>
Expand Down
30 changes: 30 additions & 0 deletions nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root /app;
index index.html;
try_files $uri $uri/ /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
}
11 changes: 8 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
"name": "supabase-schema",
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "vite build",
"dev": "env-cmd -f .env.example vite",
"build": "vite build && env-cmd -f .env.example import-meta-env -x .env.example",
"test": "vue-tsc --noEmit",
"serve": "vite preview"
"serve": "env-cmd -f .env.example import-meta-env -x .env.example && vite preview"
},
"dependencies": {
"@supabase/supabase-js": "^1.11.14",
Expand All @@ -18,13 +18,18 @@
},
"devDependencies": {
"@iconify/json": "^1.1.461",
"@import-meta-env/cli": "^0.4.1",
"@import-meta-env/typescript": "^0.3.0",
"@import-meta-env/unplugin": "^0.4.1",
"@types/crypto-js": "^4.1.1",
"@types/d3": "^6.6.0",
"@typescript-eslint/eslint-plugin": "^4.22.1",
"@typescript-eslint/parser": "^4.22.1",
"@vitejs/plugin-vue": "^2.2.2",
"@vue/compiler-sfc": "^3.2.31",
"@vue/eslint-config-typescript": "^10.0.0",
"dotenv": "^16.0.3",
"env-cmd": "^10.1.0",
"eslint": "^7.25.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-vue": "^7.9.0",
Expand Down
8 changes: 8 additions & 0 deletions src/assets/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ input[type='color']::-webkit-color-swatch {
@apply p-3 flex rounded-md bg-light-300 dark:bg-dark-800 border-2 dark:border-dark-border cursor-pointer dark:opacity-50 hover:opacity-100 hover:bg-light-700 dark:hover:bg-dark-600 focus:outline-none transition duration-300 ease-in;
}

.btn-square-green {
@apply p-3 flex rounded-md bg-green-500 border-2 dark:border-green-800 cursor-pointer hover:bg-green-600 focus:outline-none focus:ring focus:ring-green-600 transition duration-300 ease-in;
}

.btn-square-to-red {
@apply p-3 flex rounded-md bg-light-300 dark:bg-dark-800 border-2 dark:border-dark-border dark:hover:border-red-800 cursor-pointer dark:opacity-50 hover:opacity-100 hover:bg-light-700 dark:hover:bg-red-600 focus:outline-none transition duration-300 ease-in;
}

.btn-green {
@apply bg-green-500 text-white rounded-md px-4 py-0 h-8 text-sm font-medium hover:bg-green-600 focus:outline-none focus:ring focus:ring-green-600;
}
59 changes: 43 additions & 16 deletions src/components/Settings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -70,20 +70,36 @@
<span class="text-sm text-white-900">{{ error }}</span>
</form>
<!-- arrow -->
<button
v-tooltip:left.tooltip="'Settings'"
class="-left-3.95rem -top-1px !absolute btn duration-300"
@click="togglePanel = !togglePanel"
>
<i-majesticons:cog-line></i-majesticons:cog-line>
</button>
<button
v-tooltip:left.tooltip="'Toggle Dark mode'"
class="-left-3.95rem top-14 !absolute btn duration-300"
@click="toggleDark()"
>
<i-majesticons:moon></i-majesticons:moon>
</button>
<div class="flex gap-3 flex-col -left-3.95rem -top-1px !absolute">
<button
v-tooltip:left.tooltip="'Settings'"
class="btn duration-300"
@click="togglePanel = !togglePanel"
>
<i-majesticons:cog-line></i-majesticons:cog-line>
</button>
<button
v-tooltip:left.tooltip="'Toggle Dark mode'"
class="btn duration-300"
@click="toggleDark()"
>
<i-majesticons:moon></i-majesticons:moon>
</button>
<button
v-tooltip:left.tooltip="'Clear Storage'"
class="btn-square-to-red duration-300"
@click.prevent="clearStorage"
>
<i-heroicons-solid:ban></i-heroicons-solid:ban>
</button>
<button
v-tooltip:left.tooltip="'Fetch / Refresh'"
class="btn-square-green duration-300"
@click.prevent="fetchData"
>
<i-heroicons-solid:lightning-bolt></i-heroicons-solid:lightning-bolt>
</button>
</div>
</div>
</menu>
</template>
Expand Down Expand Up @@ -150,13 +166,24 @@
})
}

// fetch data if VITE_SUPABASE_API_URL is provided
const initialFetch = () => {
if (!!import.meta.env.SUPABASE_API_URL) {
fetchData()
}
}
initialFetch()

const clearStorage = () => {
localStorage.clear()
window.location.reload()
}

// toggle Panel
const togglePanel = useStorage('togglePanel', true)
// toggle Panel (closed by default when SUPABASE_API_URL provided)
const togglePanel = useStorage(
'togglePanel',
!!import.meta.env.SUPABASE_API_URL ? false : true
)
const positionPanel = computed(() => {
return togglePanel.value ? '1.25rem' : '-22.5rem'
})
Expand Down
10 changes: 9 additions & 1 deletion src/router.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createRouter, createWebHistory } from 'vue-router'
import { createRouter, createWebHistory, RouteLocation } from 'vue-router'

const routes = [
{ path: '/', name: 'Schema', component: () => import('./views/Schema.vue') },
Expand All @@ -8,4 +8,12 @@ const router = createRouter({
history: createWebHistory(),
routes,
})

router.beforeEach((to: RouteLocation, from: RouteLocation) => {
// Redirect to the root path if the route is not the root path
if (to.path !== '/') {
router.push('/')
}
})

export default router
6 changes: 3 additions & 3 deletions src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,10 @@ export const state = reactive({

export const supabaseClientState = reactive({
apikey: useStorage('supabase-apikey', {
url: '',
anon: '',
url: import.meta.env.SUPABASE_API_URL || '',
anon: import.meta.env.SUPABASE_ANON_KEY || '',
last_url: '',
}),
} as { url: string; anon: string; last_url: string }),
supabase: () =>
createClient(
supabaseClientState.apikey.url,
Expand Down
6 changes: 6 additions & 0 deletions vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Components from 'unplugin-vue-components/vite'
import Icons from 'unplugin-icons/vite'
import IconsResolver from 'unplugin-icons/resolver'
import WindiCSS from 'vite-plugin-windicss'
import ImportMetaEnvPlugin from '@import-meta-env/unplugin'

// https://vitejs.dev/config/
export default defineConfig({
Expand All @@ -14,5 +15,10 @@ export default defineConfig({
}),
Icons(),
WindiCSS(),
ImportMetaEnvPlugin.vite({
example: '.env.example',
// "env": "...",
// "transformMode": "..."
}),
],
})
Loading