Update dependencies, containerize, add build workflow
All checks were successful
Build / build (push) Successful in 1m14s
All checks were successful
Build / build (push) Successful in 1m14s
This commit is contained in:
parent
ae1c71f4c5
commit
88f0632194
38 changed files with 1139 additions and 829 deletions
3
.dockerignore
Normal file
3
.dockerignore
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
/node_modules
|
||||||
|
/dist
|
||||||
|
/.idea
|
34
.forgejo/workflows/build.yaml
Normal file
34
.forgejo/workflows/build.yaml
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
name: "Build"
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: "docker"
|
||||||
|
container:
|
||||||
|
image: "code.forgejo.org/oci/node:22-alpine"
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: "Checkout"
|
||||||
|
uses: "https://code.forgejo.org/actions/checkout@v4"
|
||||||
|
|
||||||
|
- name: "Install Docker"
|
||||||
|
run: |
|
||||||
|
apk add docker
|
||||||
|
|
||||||
|
- name: "Login to the container registry"
|
||||||
|
uses: "https://code.forgejo.org/docker/login-action@v3"
|
||||||
|
with:
|
||||||
|
registry: "git.moritzruth.de"
|
||||||
|
username: "moritzruth"
|
||||||
|
password: "${{ secrets.PACKAGES_TOKEN }}"
|
||||||
|
|
||||||
|
- name: "Build and push the container image"
|
||||||
|
uses: "https://code.forgejo.org/docker/build-push-action@v6"
|
||||||
|
with:
|
||||||
|
context: "."
|
||||||
|
file: "./Containerfile"
|
||||||
|
push: true
|
||||||
|
tags: "git.moritzruth.de/${{ github.repository }}:latest"
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,4 +1,3 @@
|
||||||
.idea/
|
.idea/
|
||||||
node_modules/
|
node_modules/
|
||||||
dist/
|
dist/
|
||||||
*.env
|
|
1
.nvmrc
1
.nvmrc
|
@ -1 +0,0 @@
|
||||||
22
|
|
22
Containerfile
Normal file
22
Containerfile
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
FROM node:22-alpine AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
COPY . .
|
||||||
|
RUN npm install --global pnpm
|
||||||
|
RUN pnpm install --frozen-lockfile
|
||||||
|
RUN pnpm build
|
||||||
|
|
||||||
|
FROM node:22-alpine
|
||||||
|
RUN npm install --global pnpm
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=builder /app/package.json /app/
|
||||||
|
COPY --from=builder /app/pnpm-lock.yaml /app/
|
||||||
|
COPY --from=builder /app/tsconfig.json /app/
|
||||||
|
COPY --from=builder /app/backend /app/backend
|
||||||
|
COPY --from=builder /app/shared /app/shared
|
||||||
|
COPY --from=builder /app/dist /app/dist
|
||||||
|
RUN pnpm install --frozen-lockfile --prod
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
ENTRYPOINT ["pnpm", "start"]
|
|
@ -1,4 +1,4 @@
|
||||||
import createExpressApp from "express"
|
import createExpressApp, { static as staticMiddleware } from "express"
|
||||||
import { listen } from "listhen"
|
import { listen } from "listhen"
|
||||||
import { WebSocketServer } from "ws"
|
import { WebSocketServer } from "ws"
|
||||||
import { appRouter } from "./trpc"
|
import { appRouter } from "./trpc"
|
||||||
|
@ -6,6 +6,7 @@ import { createExpressMiddleware as createTrpcMiddleware } from "@trpc/server/ad
|
||||||
import { applyWSSHandler } from "@trpc/server/adapters/ws"
|
import { applyWSSHandler } from "@trpc/server/adapters/ws"
|
||||||
import { createContext } from "./trpc/base"
|
import { createContext } from "./trpc/base"
|
||||||
import { isDev } from "./isDev"
|
import { isDev } from "./isDev"
|
||||||
|
import { resolve } from "node:path"
|
||||||
|
|
||||||
const expressApp = createExpressApp()
|
const expressApp = createExpressApp()
|
||||||
|
|
||||||
|
@ -14,7 +15,9 @@ expressApp.use("/trpc", createTrpcMiddleware({
|
||||||
createContext: ({ req, res }) => createContext(res),
|
createContext: ({ req, res }) => createContext(res),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const { server } = await listen(expressApp, { isProd: !isDev, autoClose: false, port: 3001 })
|
if (!isDev) expressApp.use(staticMiddleware(resolve(import.meta.dirname, "../dist")))
|
||||||
|
|
||||||
|
const { server } = await listen(expressApp, { isProd: !isDev, autoClose: false })
|
||||||
|
|
||||||
const wss = new WebSocketServer({ server, path: "/ws" })
|
const wss = new WebSocketServer({ server, path: "/ws" })
|
||||||
const wssTrpcHandler = applyWSSHandler({
|
const wssTrpcHandler = applyWSSHandler({
|
|
@ -56,11 +56,19 @@
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
body {
|
*, *::before, *:after {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
border: none;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
html, body, #app {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
font-size: 16px;
|
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
@ -62,10 +62,10 @@
|
||||||
import TrashIcon from "virtual:icons/ph/trash-bold"
|
import TrashIcon from "virtual:icons/ph/trash-bold"
|
||||||
import CheckIcon from "virtual:icons/ph/check-bold"
|
import CheckIcon from "virtual:icons/ph/check-bold"
|
||||||
import HandPointingIcon from "virtual:icons/ph/hand-pointing-duotone"
|
import HandPointingIcon from "virtual:icons/ph/hand-pointing-duotone"
|
||||||
import type { InteractionQueueItem } from "../shared/script/types"
|
import type { InteractionQueueItem } from "../../shared/script/types"
|
||||||
import ObjectPicture from "./ObjectPicture.vue"
|
import ObjectPicture from "./ObjectPicture.vue"
|
||||||
import { useGame } from "../game"
|
import { useGame } from "../game"
|
||||||
import { findMatchingCombination } from "../shared/util"
|
import { findMatchingCombination } from "../../shared/util"
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
item: InteractionQueueItem
|
item: InteractionQueueItem
|
|
@ -37,7 +37,7 @@
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { GameObject } from "../shared/script/types"
|
import type { GameObject } from "../../shared/script/types"
|
||||||
import interact from "@interactjs/interact"
|
import interact from "@interactjs/interact"
|
||||||
import { useCurrentElement } from "@vueuse/core"
|
import { useCurrentElement } from "@vueuse/core"
|
||||||
import { computed, onMounted, onUnmounted, ref, useCssModule } from "vue"
|
import { computed, onMounted, onUnmounted, ref, useCssModule } from "vue"
|
|
@ -1,10 +1,10 @@
|
||||||
import { defineStore } from "pinia"
|
import { defineStore } from "pinia"
|
||||||
import { computed, reactive, ref } from "vue"
|
import { computed, reactive, ref } from "vue"
|
||||||
import { script } from "./shared/script"
|
import { script } from "../shared/script"
|
||||||
import type { GameObject, Interaction, InteractionQueueItem } from "./shared/script/types"
|
import type { GameObject, Interaction, InteractionQueueItem } from "../shared/script/types"
|
||||||
import { trpcClient } from "./trpc"
|
import { trpcClient } from "./trpc"
|
||||||
import type { GameEvent } from "./shared/gameEvents"
|
import type { GameEvent } from "../shared/gameEvents"
|
||||||
import { getInteractionQueueItemId } from "./shared/util"
|
import { getInteractionQueueItemId } from "../shared/util"
|
||||||
|
|
||||||
export const useGame = defineStore("gameState", () => {
|
export const useGame = defineStore("gameState", () => {
|
||||||
const currentRoom = computed(() => script.roomsById.get(currentRoomId.value)!)
|
const currentRoom = computed(() => script.roomsById.get(currentRoomId.value)!)
|
|
@ -1,4 +1,4 @@
|
||||||
import "virtual:windi.css"
|
import "virtual:uno.css"
|
||||||
import "@interactjs/actions"
|
import "@interactjs/actions"
|
||||||
import "@interactjs/auto-start"
|
import "@interactjs/auto-start"
|
||||||
import "core-js/actual/iterator"
|
import "core-js/actual/iterator"
|
|
@ -3,21 +3,23 @@
|
||||||
<section class="w-80">
|
<section class="w-80">
|
||||||
<div class="font-bold text-2xl pb-2">Raum</div>
|
<div class="font-bold text-2xl pb-2">Raum</div>
|
||||||
<div class="flex flex-col overflow-y-auto bg-dark-900 bg-opacity-50 h-80vh">
|
<div class="flex flex-col overflow-y-auto bg-dark-900 bg-opacity-50 h-80vh">
|
||||||
<div
|
<template
|
||||||
v-for="room in script.roomsById.values()"
|
v-for="(room, index) in script.roomsById.values()"
|
||||||
:key="room.id"
|
:key="room.id"
|
||||||
class="flex-shrink-0 bg-dark-600 not-last:border-b border-solid border-dark-300 flex items-center"
|
|
||||||
>
|
>
|
||||||
<div class="px-3 py-2 flex-grow">
|
<div v-if="index !== 0" class="w-full h-1px bg-dark-300"/>
|
||||||
{{ room.label }}
|
<div class="flex-shrink-0 bg-dark-600 flex items-center">
|
||||||
|
<div class="px-3 py-2 flex-grow">
|
||||||
|
{{ room.label }}
|
||||||
|
</div>
|
||||||
|
<button v-if="game.currentRoomId === room.id" disabled class="bg-green-900 h-full px-3 text-sm cursor-not-allowed">
|
||||||
|
Aktiv
|
||||||
|
</button>
|
||||||
|
<button v-else class="bg-dark-300 h-full px-3 text-sm" @click="game.switchRoom(room.id)">
|
||||||
|
Aktivieren
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<button v-if="game.currentRoomId === room.id" disabled class="bg-green-900 h-full px-3 text-sm cursor-not-allowed">
|
</template>
|
||||||
Aktiv
|
|
||||||
</button>
|
|
||||||
<button v-else class="bg-dark-300 h-full px-3 text-sm" @click="game.switchRoom(room.id)">
|
|
||||||
Aktivieren
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section class="flex-grow">
|
<section class="flex-grow">
|
||||||
|
@ -61,7 +63,7 @@
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { script } from "../shared/script"
|
import { script } from "../../shared/script"
|
||||||
import { useGame } from "../game"
|
import { useGame } from "../game"
|
||||||
import ObjectPicture from "../components/ObjectPicture.vue"
|
import ObjectPicture from "../components/ObjectPicture.vue"
|
||||||
import InteractionQueueItemCard from "../components/InteractionQueueItemCard.vue"
|
import InteractionQueueItemCard from "../components/InteractionQueueItemCard.vue"
|
|
@ -1,6 +1,6 @@
|
||||||
import { createTRPCProxyClient, createWSClient, wsLink } from "@trpc/client"
|
import { createTRPCProxyClient, createWSClient, wsLink } from "@trpc/client"
|
||||||
import superjson from "superjson"
|
import superjson from "superjson"
|
||||||
import type { AppRouter } from "./server"
|
import type { AppRouter } from "../backend"
|
||||||
|
|
||||||
const wsUrl = new URL(location.href)
|
const wsUrl = new URL(location.href)
|
||||||
wsUrl.protocol = wsUrl.protocol.replace("http", "ws")
|
wsUrl.protocol = wsUrl.protocol.replace("http", "ws")
|
||||||
|
@ -8,7 +8,7 @@ wsUrl.pathname = "/ws"
|
||||||
wsUrl.hash = ""
|
wsUrl.hash = ""
|
||||||
|
|
||||||
if (import.meta.env.PROD) {
|
if (import.meta.env.PROD) {
|
||||||
wsUrl.hostname = "server." + wsUrl.hostname
|
wsUrl.hostname = "backend." + wsUrl.hostname
|
||||||
}
|
}
|
||||||
|
|
||||||
export const trpcClient = createTRPCProxyClient<AppRouter>({
|
export const trpcClient = createTRPCProxyClient<AppRouter>({
|
|
@ -4,9 +4,9 @@
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Level Up</title>
|
<title>Level Up</title>
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||||
<script type="module" src="./src/index.ts"></script>
|
<script type="module" src="frontend/index.ts"></script>
|
||||||
<link rel="stylesheet" href="./node_modules/@fontsource-variable/inter/wght.css"/>
|
<link rel="stylesheet" href="./node_modules/@fontsource-variable/inter/wght.css"/>
|
||||||
<link rel="stylesheet" href="./node_modules/@fontsource/titan-one/400.css"/>
|
<link rel="stylesheet" href="./node_modules/modern-normalize/modern-normalize.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|
53
package.json
53
package.json
|
@ -3,50 +3,53 @@
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start:ui": "vite preview --host --port 3000",
|
"start": "NODE_ENV=production tsx ./backend/main.ts",
|
||||||
"start:server": "NODE_ENV=production tsx ./src/server/main.ts",
|
"build": "vite build",
|
||||||
"build:ui": "vite build",
|
"dev:frontend": "vite",
|
||||||
"dev:ui": "vite --host",
|
"dev:backend": "NODE_ENV=development tsx watch --clear-screen=false ./backend/main.ts"
|
||||||
"dev:server": "NODE_ENV=development tsx watch --clear-screen=false ./src/server/main.ts"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@iconify-json/ph": "^1.2.2",
|
"@iconify-json/ph": "^1.2.2",
|
||||||
"@types/express": "^5.0.0",
|
"@types/express": "^5.0.0",
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/node": "22.10.2",
|
"@types/node": "^22.13.8",
|
||||||
"@types/ws": "^8.5.13",
|
"@types/ws": "^8.5.14",
|
||||||
"@vitejs/plugin-vue": "^5.2.1",
|
"@vitejs/plugin-vue": "^5.2.1",
|
||||||
"sass": "^1.83.0",
|
"sass": "^1.85.1",
|
||||||
"tsx": "^4.19.2",
|
"typescript": "^5.8.2",
|
||||||
"typescript": "^5.7.2",
|
"unocss": "66.1.0-beta.3",
|
||||||
"unplugin-icons": "^0.22.0",
|
"unplugin-icons": "^22.1.0",
|
||||||
"vite": "^6.0.3",
|
"vite": "^6.2.0"
|
||||||
"vite-plugin-windicss": "^1.9.4",
|
|
||||||
"windicss": "^3.5.6"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fontsource-variable/inter": "^5.1.0",
|
"@fontsource-variable/inter": "^5.2.5",
|
||||||
"@fontsource/titan-one": "^5.1.0",
|
|
||||||
"@headlessui/vue": "^1.7.23",
|
"@headlessui/vue": "^1.7.23",
|
||||||
"@interactjs/actions": "^1.10.27",
|
"@interactjs/actions": "^1.10.27",
|
||||||
"@interactjs/auto-start": "^1.10.27",
|
"@interactjs/auto-start": "^1.10.27",
|
||||||
"@interactjs/interact": "^1.10.27",
|
"@interactjs/interact": "^1.10.27",
|
||||||
"@trpc/client": "^10.45.2",
|
"@trpc/client": "^10.45.2",
|
||||||
"@trpc/server": "^10.45.2",
|
"@trpc/server": "^10.45.2",
|
||||||
"@vueuse/core": "^12.0.0",
|
"@unocss/preset-wind3": "66.1.0-beta.3",
|
||||||
"@vueuse/integrations": "^12.0.0",
|
"@vueuse/core": "^12.7.0",
|
||||||
"bufferutil": "^4.0.8",
|
"@vueuse/integrations": "^12.7.0",
|
||||||
"core-js": "^3.40.0",
|
"bufferutil": "^4.0.9",
|
||||||
|
"core-js": "^3.41.0",
|
||||||
|
"date-fns": "^4.1.0",
|
||||||
"eventemitter3": "^5.0.1",
|
"eventemitter3": "^5.0.1",
|
||||||
"express": "^4.21.2",
|
"express": "^4.21.2",
|
||||||
"immer": "^10.1.1",
|
|
||||||
"listhen": "^1.9.0",
|
"listhen": "^1.9.0",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"nanoid": "^5.0.9",
|
"modern-normalize": "^3.0.1",
|
||||||
"pinia": "^2.3.0",
|
"nanoid": "^5.1.2",
|
||||||
|
"pinia": "^3.0.1",
|
||||||
"superjson": "^2.2.2",
|
"superjson": "^2.2.2",
|
||||||
|
"tsx": "^4.19.3",
|
||||||
"vue": "^3.5.13",
|
"vue": "^3.5.13",
|
||||||
"ws": "^8.18.0",
|
"vue-router": "^4.5.0",
|
||||||
"zod": "^3.24.1"
|
"ws": "^8.18.1",
|
||||||
|
"zod": "^3.24.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "22"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
1704
pnpm-lock.yaml
generated
1704
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
|
@ -1,31 +1,31 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"declaration": true,
|
"declaration": false,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"jsx": "preserve",
|
"jsx": "preserve",
|
||||||
"lib": ["esnext", "dom"],
|
"lib": ["esnext", "dom"],
|
||||||
"module": "esnext",
|
"module": "esnext",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "bundler",
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"importsNotUsedAsValues": "error",
|
"importsNotUsedAsValues": "error",
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"rootDir": "src",
|
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"sourceMap": true,
|
"sourceMap": false,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"stripInternal": true,
|
"stripInternal": true,
|
||||||
"target": "esnext",
|
"target": "esnext",
|
||||||
"types": [
|
"types": [
|
||||||
"./src/types.d.ts",
|
|
||||||
"vite/client",
|
"vite/client",
|
||||||
"unplugin-icons/types/vue",
|
"unplugin-icons/types/vue",
|
||||||
"vite-plugin-pages/client"
|
"vite-plugin-pages/client"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src/**/*.ts",
|
"backend/**/*.ts",
|
||||||
"src/**/*.vue"
|
"shared/**/*.ts",
|
||||||
|
"frontend/**/*.ts",
|
||||||
|
"frontend/**/*.vue"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
31
uno.config.ts
Normal file
31
uno.config.ts
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
import { defineConfig, transformerDirectives } from "unocss"
|
||||||
|
import { presetWind, colors } from "@unocss/preset-wind3"
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
presets: [
|
||||||
|
presetWind({
|
||||||
|
arbitraryVariants: true,
|
||||||
|
preflight: true
|
||||||
|
})
|
||||||
|
],
|
||||||
|
theme: {
|
||||||
|
fontFamily: {
|
||||||
|
"normal": `"Inter Variable", sans-serif`
|
||||||
|
},
|
||||||
|
colors: {
|
||||||
|
transparent: "transparent",
|
||||||
|
white: colors.white,
|
||||||
|
black: colors.black,
|
||||||
|
gray: colors.zinc,
|
||||||
|
light: colors.light,
|
||||||
|
dark: colors.dark,
|
||||||
|
red: colors.rose,
|
||||||
|
yellow: colors.yellow,
|
||||||
|
green: colors.green,
|
||||||
|
blue: colors.indigo,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
transformers: [
|
||||||
|
transformerDirectives()
|
||||||
|
]
|
||||||
|
})
|
|
@ -1,20 +1,19 @@
|
||||||
import { defineConfig } from "vite"
|
import { defineConfig } from "vite"
|
||||||
import vuePlugin from "@vitejs/plugin-vue"
|
import vuePlugin from "@vitejs/plugin-vue"
|
||||||
import iconsPlugin from "unplugin-icons/vite"
|
import iconsPlugin from "unplugin-icons/vite"
|
||||||
import windiPlugin from "vite-plugin-windicss"
|
import unoCssPlugin from "unocss/vite"
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [
|
plugins: [
|
||||||
vuePlugin(),
|
vuePlugin(),
|
||||||
iconsPlugin(),
|
iconsPlugin(),
|
||||||
windiPlugin()
|
unoCssPlugin()
|
||||||
],
|
],
|
||||||
server: {
|
server: {
|
||||||
port: 3000,
|
|
||||||
proxy: {
|
proxy: {
|
||||||
"/trpc": "http://localhost:3001",
|
"/trpc": "http://localhost:3000",
|
||||||
"/ws": {
|
"/ws": {
|
||||||
target: "http://localhost:3001",
|
target: "http://localhost:3000",
|
||||||
ws: true
|
ws: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
import { defineConfig } from "vite-plugin-windicss"
|
|
||||||
import colors from "windicss/colors"
|
|
||||||
|
|
||||||
export default defineConfig({
|
|
||||||
theme: {
|
|
||||||
fontFamily: {
|
|
||||||
"normal": ["InterVariable", "sans-serif"],
|
|
||||||
"fat": ["Titan One", "sans-serif"]
|
|
||||||
},
|
|
||||||
colors: {
|
|
||||||
transparent: "transparent",
|
|
||||||
white: "white",
|
|
||||||
black: "black",
|
|
||||||
gray: colors.zinc,
|
|
||||||
light: colors.light,
|
|
||||||
dark: colors.dark,
|
|
||||||
red: colors.rose,
|
|
||||||
yellow: colors.yellow,
|
|
||||||
green: colors.green,
|
|
||||||
blue: colors.indigo,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
Loading…
Add table
Reference in a new issue