Merge branch 'main' of https://github.com/VAR-Virtual-Air-Rescue/var-monorepo
This commit is contained in:
@@ -1,4 +1,10 @@
|
|||||||
node_modules
|
node_modules
|
||||||
|
apps/dispatch/node_modules
|
||||||
|
apps/dispatch-server/node_modules
|
||||||
|
apps/hub/node_modules
|
||||||
|
apps/hub-server/node_modules
|
||||||
|
packages/database/node_modules
|
||||||
|
packages/eslint-config/node_modules
|
||||||
Dockerfile
|
Dockerfile
|
||||||
.dockerignore
|
.dockerignore
|
||||||
.eslint.config.msj
|
.eslint.config.msj
|
||||||
|
|||||||
12
.env.prod
12
.env.prod
@@ -1,12 +0,0 @@
|
|||||||
NEXTAUTH_SECRET=dispatch
|
|
||||||
NEXTAUTH_HUB_SECRET=var
|
|
||||||
NEXTAUTH_COOKIE_PREFIX=DISPATCH
|
|
||||||
NEXT_PUBLIC_DISPATCH_SERVER_URL=http://localhost:3002
|
|
||||||
NEXTAUTH_URL=http://localhost:3001
|
|
||||||
NEXT_PUBLIC_HUB_URL=http://localhost:3000
|
|
||||||
NEXT_PUBLIC_PUBLIC_URL=http://localhost:3001
|
|
||||||
NEXT_PUBLIC_SERVICE_ID=1
|
|
||||||
DATABASE_URL=postgresql://persistant-data:persistant-data-pw@postgres:5432/var
|
|
||||||
NEXT_PUBLIC_LIVEKIT_URL=ws://localhost:7880
|
|
||||||
LIVEKIT_API_KEY=APIAnsGdtdYp2Ho
|
|
||||||
LIVEKIT_API_SECRET=tdPjVsYUx8ddC7K9NvdmVAeLRF9GeADD6Fedm1x63fWC
|
|
||||||
@@ -1,29 +1,48 @@
|
|||||||
FROM node:22-alpine
|
FROM node:22-alpine AS base
|
||||||
|
|
||||||
|
ENV PNPM_HOME="/usr/local/pnpm"
|
||||||
|
ENV PATH="${PNPM_HOME}:${PATH}"
|
||||||
|
RUN corepack enable && corepack prepare pnpm@latest --activate
|
||||||
|
|
||||||
|
RUN pnpm add -g turbo@^2.5
|
||||||
|
|
||||||
|
FROM base AS builder
|
||||||
|
RUN apk update
|
||||||
|
RUN apk add --no-cache libc6-compat
|
||||||
|
|
||||||
# Set the working directory
|
|
||||||
WORKDIR /usr/app
|
WORKDIR /usr/app
|
||||||
|
|
||||||
# Copy package.json and package-lock.json
|
|
||||||
COPY package*.json ./
|
|
||||||
|
|
||||||
# Install dependencies
|
|
||||||
RUN npm install
|
|
||||||
|
|
||||||
# Change ownership to the non-root user
|
|
||||||
RUN chown -R node:node /usr/app
|
|
||||||
|
|
||||||
# Copy the rest of the application code
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
# Build the application
|
RUN turbo prune dispatch-server --docker
|
||||||
RUN npm run build
|
|
||||||
|
FROM base AS installer
|
||||||
|
RUN apk update
|
||||||
|
RUN apk add --no-cache libc6-compat
|
||||||
|
|
||||||
|
WORKDIR /usr/app
|
||||||
|
|
||||||
|
COPY --from=builder /usr/app/out/json/ .
|
||||||
|
RUN pnpm install --frozen-lockfile
|
||||||
|
|
||||||
|
# Build the project
|
||||||
|
COPY --from=builder /usr/app/out/full/ .
|
||||||
|
|
||||||
|
RUN turbo run build
|
||||||
|
|
||||||
|
FROM base AS runner
|
||||||
|
WORKDIR /usr/app
|
||||||
|
|
||||||
|
# Don't run production as root
|
||||||
|
RUN addgroup --system --gid 1001 nodejs
|
||||||
|
RUN adduser --system --uid 1001 nextjs
|
||||||
|
USER nextjs
|
||||||
|
|
||||||
|
# Automatically leverage output traces to reduce image size
|
||||||
|
# https://nextjs.org/docs/advanced-features/output-file-tracing
|
||||||
|
COPY --from=installer --chown=nextjs:nodejs /usr/app/ ./
|
||||||
|
|
||||||
# Expose the application port
|
# Expose the application port
|
||||||
EXPOSE 3002
|
EXPOSE 3002
|
||||||
|
|
||||||
# Run container as non-root (unprivileged) user
|
CMD ["pnpm", "--dir", "apps/dispatch-server", "run", "start"]
|
||||||
# The "node" user is provided in the Node.js Alpine base image
|
|
||||||
USER node
|
|
||||||
|
|
||||||
# Command to run the application
|
|
||||||
CMD ["node", "index.js"]
|
|
||||||
@@ -7,11 +7,11 @@ import { jwtMiddleware } from "modules/socketJWTmiddleware";
|
|||||||
import { pubClient, subClient } from "modules/redis";
|
import { pubClient, subClient } from "modules/redis";
|
||||||
import { handleConnectDispatch } from "socket-events/connect-dispatch";
|
import { handleConnectDispatch } from "socket-events/connect-dispatch";
|
||||||
import router from "routes/router";
|
import router from "routes/router";
|
||||||
import cors from "cors";
|
|
||||||
import { handleSendMessage } from "socket-events/send-message";
|
import { handleSendMessage } from "socket-events/send-message";
|
||||||
import { handleConnectPilot } from "socket-events/connect-pilot";
|
import { handleConnectPilot } from "socket-events/connect-pilot";
|
||||||
import { handleConnectDesktop } from "socket-events/connect-desktop";
|
import { handleConnectDesktop } from "socket-events/connect-desktop";
|
||||||
import cookieParser from "cookie-parser";
|
import cookieParser from "cookie-parser";
|
||||||
|
import cors from "cors";
|
||||||
import { authMiddleware } from "modules/expressMiddleware";
|
import { authMiddleware } from "modules/expressMiddleware";
|
||||||
import { prisma, User } from "@repo/db";
|
import { prisma, User } from "@repo/db";
|
||||||
import { Request, Response, NextFunction } from "express";
|
import { Request, Response, NextFunction } from "express";
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { createClient } from "redis";
|
import { createClient, RedisClientType } from "redis";
|
||||||
|
|
||||||
export const pubClient = createClient();
|
export const pubClient: RedisClientType = createClient();
|
||||||
export const subClient = pubClient.duplicate();
|
export const subClient: RedisClientType = pubClient.duplicate();
|
||||||
|
|
||||||
Promise.all([pubClient.connect(), subClient.connect()]).then(() => {
|
Promise.all([pubClient.connect(), subClient.connect()]).then(() => {
|
||||||
console.log("Redis connected");
|
console.log("Redis connected");
|
||||||
|
|||||||
@@ -5,12 +5,14 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "nodemon --signal SIGINT",
|
"dev": "nodemon --signal SIGINT",
|
||||||
|
"start": "node index.js",
|
||||||
"build": "tsc"
|
"build": "tsc"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@repo/db": "*",
|
"@repo/db": "*",
|
||||||
"@repo/typescript-config": "*",
|
"@repo/typescript-config": "*",
|
||||||
"@types/cookie-parser": "^1.4.8",
|
"@types/cookie-parser": "^1.4.8",
|
||||||
|
"@types/cors": "^2.8.18",
|
||||||
"@types/express": "^5.0.0",
|
"@types/express": "^5.0.0",
|
||||||
"@types/node": "^22.13.5",
|
"@types/node": "^22.13.5",
|
||||||
"@types/nodemailer": "^6.4.17",
|
"@types/nodemailer": "^6.4.17",
|
||||||
|
|||||||
@@ -1,14 +1,8 @@
|
|||||||
import {
|
import { ConnectedAircraft, getPublicUser, MissionLog, Prisma, prisma } from "@repo/db";
|
||||||
ConnectedAircraft,
|
|
||||||
getPublicUser,
|
|
||||||
MissionLog,
|
|
||||||
Prisma,
|
|
||||||
prisma,
|
|
||||||
} from "@repo/db";
|
|
||||||
import { Router } from "express";
|
import { Router } from "express";
|
||||||
import { io } from "../index";
|
import { io } from "../index";
|
||||||
|
|
||||||
const router = Router();
|
const router: Router = Router();
|
||||||
|
|
||||||
// Get all connectedAircrafts
|
// Get all connectedAircrafts
|
||||||
router.post("/", async (req, res) => {
|
router.post("/", async (req, res) => {
|
||||||
@@ -97,10 +91,7 @@ router.patch("/:id", async (req, res) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
io.to("dispatchers").emit(
|
io.to("dispatchers").emit("update-connectedAircraft", updatedConnectedAircraft);
|
||||||
"update-connectedAircraft",
|
|
||||||
updatedConnectedAircraft,
|
|
||||||
);
|
|
||||||
io.to(`user:${updatedConnectedAircraft.userId}`).emit(
|
io.to(`user:${updatedConnectedAircraft.userId}`).emit(
|
||||||
"aircraft-update",
|
"aircraft-update",
|
||||||
updatedConnectedAircraft,
|
updatedConnectedAircraft,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { prisma } from "@repo/db";
|
|||||||
import { Router } from "express";
|
import { Router } from "express";
|
||||||
import { pubClient } from "modules/redis";
|
import { pubClient } from "modules/redis";
|
||||||
|
|
||||||
const router = Router();
|
const router: Router = Router();
|
||||||
|
|
||||||
router.get("/", async (req, res) => {
|
router.get("/", async (req, res) => {
|
||||||
const user = await prisma.connectedDispatcher.findMany({
|
const user = await prisma.connectedDispatcher.findMany({
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ import { Router } from "express";
|
|||||||
import { AccessToken } from "livekit-server-sdk";
|
import { AccessToken } from "livekit-server-sdk";
|
||||||
|
|
||||||
if (!process.env.LIVEKIT_API_KEY) throw new Error("LIVEKIT_API_KEY not set");
|
if (!process.env.LIVEKIT_API_KEY) throw new Error("LIVEKIT_API_KEY not set");
|
||||||
if (!process.env.LIVEKIT_API_SECRET)
|
if (!process.env.LIVEKIT_API_SECRET) throw new Error("LIVEKIT_API_SECRET not set");
|
||||||
throw new Error("LIVEKIT_API_SECRET not set");
|
|
||||||
|
|
||||||
const createToken = async (roomName: string) => {
|
const createToken = async (roomName: string) => {
|
||||||
// If this room doesn't exist, it'll be automatically created when the first
|
// If this room doesn't exist, it'll be automatically created when the first
|
||||||
@@ -11,24 +10,19 @@ const createToken = async (roomName: string) => {
|
|||||||
// Identifier to be used for participant.
|
// Identifier to be used for participant.
|
||||||
// It's available as LocalParticipant.identity with livekit-client SDK
|
// It's available as LocalParticipant.identity with livekit-client SDK
|
||||||
// TODO: Move function to dispatch nextjs app as API route to use authentication of nextAuth
|
// TODO: Move function to dispatch nextjs app as API route to use authentication of nextAuth
|
||||||
const participantName =
|
const participantName = "quickstart-username" + Math.random().toString(36).substring(7);
|
||||||
"quickstart-username" + Math.random().toString(36).substring(7);
|
|
||||||
|
|
||||||
const at = new AccessToken(
|
const at = new AccessToken(process.env.LIVEKIT_API_KEY, process.env.LIVEKIT_API_SECRET, {
|
||||||
process.env.LIVEKIT_API_KEY,
|
identity: participantName,
|
||||||
process.env.LIVEKIT_API_SECRET,
|
// Token to expire after 10 minutes
|
||||||
{
|
ttl: "10m",
|
||||||
identity: participantName,
|
});
|
||||||
// Token to expire after 10 minutes
|
|
||||||
ttl: "10m",
|
|
||||||
},
|
|
||||||
);
|
|
||||||
at.addGrant({ roomJoin: true, room: roomName });
|
at.addGrant({ roomJoin: true, room: roomName });
|
||||||
|
|
||||||
return await at.toJwt();
|
return await at.toJwt();
|
||||||
};
|
};
|
||||||
|
|
||||||
const router = Router();
|
const router: Router = Router();
|
||||||
|
|
||||||
router.get("/token", async (req, res) => {
|
router.get("/token", async (req, res) => {
|
||||||
const roomName = req.query.roomName as string;
|
const roomName = req.query.roomName as string;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { io } from "../index";
|
|||||||
import { sendNtfyMission } from "modules/ntfy";
|
import { sendNtfyMission } from "modules/ntfy";
|
||||||
import { sendAlert } from "modules/mission";
|
import { sendAlert } from "modules/mission";
|
||||||
|
|
||||||
const router = Router();
|
const router: Router = Router();
|
||||||
|
|
||||||
// Get all missions
|
// Get all missions
|
||||||
router.post("/", async (req, res) => {
|
router.post("/", async (req, res) => {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { Router } from "express";
|
|||||||
|
|
||||||
import { prisma } from "@repo/db";
|
import { prisma } from "@repo/db";
|
||||||
|
|
||||||
const router = Router();
|
const router: Router = Router();
|
||||||
|
|
||||||
router.put("/", async (req, res) => {
|
router.put("/", async (req, res) => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import statusRouter from "./status";
|
|||||||
import aircraftsRouter from "./aircraft";
|
import aircraftsRouter from "./aircraft";
|
||||||
import reportRouter from "./report";
|
import reportRouter from "./report";
|
||||||
|
|
||||||
const router = Router();
|
const router: Router = Router();
|
||||||
|
|
||||||
router.use("/livekit", livekitRouter);
|
router.use("/livekit", livekitRouter);
|
||||||
router.use("/dispatcher", dispatcherRotuer);
|
router.use("/dispatcher", dispatcherRotuer);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { prisma } from "@repo/db";
|
import { prisma } from "@repo/db";
|
||||||
import { Router } from "express";
|
import { Router } from "express";
|
||||||
|
|
||||||
const router = Router();
|
const router: Router = Router();
|
||||||
|
|
||||||
router.get("/connected-users", async (req, res) => {
|
router.get("/connected-users", async (req, res) => {
|
||||||
const connectedDispatcher = await prisma.connectedDispatcher.findMany({
|
const connectedDispatcher = await prisma.connectedDispatcher.findMany({
|
||||||
|
|||||||
@@ -1,24 +1,18 @@
|
|||||||
FROM node:22-alpine AS base
|
FROM node:22-alpine AS base
|
||||||
|
|
||||||
|
|
||||||
ENV PNPM_HOME="/usr/local/pnpm"
|
ENV PNPM_HOME="/usr/local/pnpm"
|
||||||
ENV PATH="${PNPM_HOME}:${PATH}"
|
ENV PATH="${PNPM_HOME}:${PATH}"
|
||||||
RUN corepack enable && corepack prepare pnpm@latest --activate
|
RUN corepack enable && corepack prepare pnpm@latest --activate
|
||||||
|
|
||||||
RUN pnpm add -g turbo@^2.5
|
RUN pnpm add -g turbo@^2.5
|
||||||
|
|
||||||
ARG DATABASE_URL
|
|
||||||
ENV DATABASE_URL=${DATABASE_URL}
|
|
||||||
|
|
||||||
FROM base AS builder
|
FROM base AS builder
|
||||||
RUN apk update
|
RUN apk update
|
||||||
RUN apk add --no-cache libc6-compat
|
RUN apk add --no-cache libc6-compat
|
||||||
|
|
||||||
WORKDIR /usr/app
|
WORKDIR /usr/app
|
||||||
|
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN cat .env.prod
|
|
||||||
|
|
||||||
RUN turbo prune dispatch --docker
|
RUN turbo prune dispatch --docker
|
||||||
|
|
||||||
@@ -34,9 +28,6 @@ RUN pnpm install --frozen-lockfile
|
|||||||
# Build the project
|
# Build the project
|
||||||
COPY --from=builder /usr/app/out/full/ .
|
COPY --from=builder /usr/app/out/full/ .
|
||||||
|
|
||||||
COPY --from=builder /usr/app/.env.prod ./apps/dispatch/.env
|
|
||||||
COPY --from=builder /usr/app/.env.prod ./packages/databse/.env
|
|
||||||
|
|
||||||
RUN turbo run build
|
RUN turbo run build
|
||||||
|
|
||||||
FROM base AS runner
|
FROM base AS runner
|
||||||
@@ -52,6 +43,6 @@ USER nextjs
|
|||||||
COPY --from=installer --chown=nextjs:nodejs /usr/app/ ./
|
COPY --from=installer --chown=nextjs:nodejs /usr/app/ ./
|
||||||
|
|
||||||
# Expose the application port
|
# Expose the application port
|
||||||
EXPOSE 3000
|
EXPOSE 3001
|
||||||
|
|
||||||
CMD ["pnpm", "--dir", "apps/dispatch", "run", "start"]
|
CMD ["pnpm", "--dir", "apps/dispatch", "run", "start"]
|
||||||
@@ -4,20 +4,18 @@ import { AccessToken } from "livekit-server-sdk";
|
|||||||
import { NextRequest } from "next/server";
|
import { NextRequest } from "next/server";
|
||||||
import { prisma } from "@repo/db";
|
import { prisma } from "@repo/db";
|
||||||
|
|
||||||
if (!process.env.LIVEKIT_API_KEY) throw new Error("LIVEKIT_API_KEY not set");
|
/* if (!process.env.LIVEKIT_API_KEY) throw new Error("LIVEKIT_API_KEY not set");
|
||||||
if (!process.env.LIVEKIT_API_SECRET)
|
if (!process.env.LIVEKIT_API_SECRET)
|
||||||
throw new Error("LIVEKIT_API_SECRET not set");
|
throw new Error("LIVEKIT_API_SECRET not set"); */
|
||||||
|
|
||||||
export const GET = async (request: NextRequest) => {
|
export const GET = async (request: NextRequest) => {
|
||||||
const roomName = request.nextUrl.searchParams.get("roomName");
|
const roomName = request.nextUrl.searchParams.get("roomName");
|
||||||
|
|
||||||
if (!roomName)
|
if (!roomName) return Response.json({ message: "Missing roomName" }, { status: 400 });
|
||||||
return Response.json({ message: "Missing roomName" }, { status: 400 });
|
|
||||||
|
|
||||||
const session = await getServerSession();
|
const session = await getServerSession();
|
||||||
|
|
||||||
if (!session)
|
if (!session) return Response.json({ message: "Unauthorized" }, { status: 401 });
|
||||||
return Response.json({ message: "Unauthorized" }, { status: 401 });
|
|
||||||
const user = await prisma.user.findUnique({
|
const user = await prisma.user.findUnique({
|
||||||
where: {
|
where: {
|
||||||
id: session.user.id,
|
id: session.user.id,
|
||||||
@@ -29,15 +27,11 @@ export const GET = async (request: NextRequest) => {
|
|||||||
|
|
||||||
const participantName = user.publicId;
|
const participantName = user.publicId;
|
||||||
|
|
||||||
const at = new AccessToken(
|
const at = new AccessToken(process.env.LIVEKIT_API_KEY, process.env.LIVEKIT_API_SECRET, {
|
||||||
process.env.LIVEKIT_API_KEY,
|
identity: participantName,
|
||||||
process.env.LIVEKIT_API_SECRET,
|
// Token to expire after 10 minutes
|
||||||
{
|
ttl: "1d",
|
||||||
identity: participantName,
|
});
|
||||||
// Token to expire after 10 minutes
|
|
||||||
ttl: "1d",
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
at.addGrant({
|
at.addGrant({
|
||||||
room: roomName,
|
room: roomName,
|
||||||
|
|||||||
@@ -1,31 +1,48 @@
|
|||||||
FROM node:22-alpine
|
FROM node:22-alpine AS base
|
||||||
|
|
||||||
ENV NODE_ENV=production
|
ENV PNPM_HOME="/usr/local/pnpm"
|
||||||
|
ENV PATH="${PNPM_HOME}:${PATH}"
|
||||||
|
RUN corepack enable && corepack prepare pnpm@latest --activate
|
||||||
|
|
||||||
|
RUN pnpm add -g turbo@^2.5
|
||||||
|
|
||||||
|
FROM base AS builder
|
||||||
|
RUN apk update
|
||||||
|
RUN apk add --no-cache libc6-compat
|
||||||
|
|
||||||
# Set the working directory
|
|
||||||
WORKDIR /usr/app
|
WORKDIR /usr/app
|
||||||
|
|
||||||
# Copy package.json and package-lock.json
|
|
||||||
COPY package*.json ./
|
|
||||||
|
|
||||||
# Install dependencies
|
|
||||||
RUN npm install
|
|
||||||
|
|
||||||
# Change ownership to the non-root user
|
|
||||||
RUN chown -R node:node /usr/app
|
|
||||||
|
|
||||||
# Copy the rest of the application code
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
# Build the application
|
RUN turbo prune hub-server --docker
|
||||||
RUN npm run build
|
|
||||||
|
FROM base AS installer
|
||||||
|
RUN apk update
|
||||||
|
RUN apk add --no-cache libc6-compat
|
||||||
|
|
||||||
|
WORKDIR /usr/app
|
||||||
|
|
||||||
|
COPY --from=builder /usr/app/out/json/ .
|
||||||
|
RUN pnpm install --frozen-lockfile
|
||||||
|
|
||||||
|
# Build the project
|
||||||
|
COPY --from=builder /usr/app/out/full/ .
|
||||||
|
|
||||||
|
RUN turbo run build
|
||||||
|
|
||||||
|
FROM base AS runner
|
||||||
|
WORKDIR /usr/app
|
||||||
|
|
||||||
|
# Don't run production as root
|
||||||
|
RUN addgroup --system --gid 1001 nodejs
|
||||||
|
RUN adduser --system --uid 1001 nextjs
|
||||||
|
USER nextjs
|
||||||
|
|
||||||
|
# Automatically leverage output traces to reduce image size
|
||||||
|
# https://nextjs.org/docs/advanced-features/output-file-tracing
|
||||||
|
COPY --from=installer --chown=nextjs:nodejs /usr/app/ ./
|
||||||
|
|
||||||
# Expose the application port
|
# Expose the application port
|
||||||
EXPOSE 3003
|
EXPOSE 3003
|
||||||
|
|
||||||
# Run container as non-root (unprivileged) user
|
CMD ["pnpm", "--dir", "apps/hub-server", "run", "start"]
|
||||||
# The "node" user is provided in the Node.js Alpine base image
|
|
||||||
USER node
|
|
||||||
|
|
||||||
# Command to run the application
|
|
||||||
CMD ["node", "index.js"]
|
|
||||||
@@ -5,13 +5,17 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "nodemon --signal SIGINT",
|
"dev": "nodemon --signal SIGINT",
|
||||||
|
"start": "node index.js",
|
||||||
"build": "tsc"
|
"build": "tsc"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@repo/db": "*",
|
"@repo/db": "*",
|
||||||
"@repo/typescript-config": "*",
|
"@repo/typescript-config": "*",
|
||||||
|
"@types/cors": "^2.8.18",
|
||||||
|
"@types/express": "^5.0.2",
|
||||||
"@types/node": "^22.13.5",
|
"@types/node": "^22.13.5",
|
||||||
"@types/nodemailer": "^6.4.17",
|
"@types/nodemailer": "^6.4.17",
|
||||||
|
"@types/react": "^19.1.5",
|
||||||
"concurrently": "^9.1.2",
|
"concurrently": "^9.1.2",
|
||||||
"typescript": "latest"
|
"typescript": "latest"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { Router } from "express";
|
|||||||
import { sendMail } from "modules/mail";
|
import { sendMail } from "modules/mail";
|
||||||
import { sendPasswordChanged, sendCourseCompletedEmail } from "modules/mail";
|
import { sendPasswordChanged, sendCourseCompletedEmail } from "modules/mail";
|
||||||
|
|
||||||
const router = Router();
|
const router: Router = Router();
|
||||||
|
|
||||||
router.post("/send", async (req, res) => {
|
router.post("/send", async (req, res) => {
|
||||||
const { to, subject, html } = req.body;
|
const { to, subject, html } = req.body;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Router } from "express";
|
import { Router } from "express";
|
||||||
import mailRouter from "./mail";
|
import mailRouter from "./mail";
|
||||||
|
|
||||||
const router = Router();
|
const router: Router = Router();
|
||||||
|
|
||||||
router.use("/mail", mailRouter);
|
router.use("/mail", mailRouter);
|
||||||
|
|
||||||
|
|||||||
@@ -1,29 +1,48 @@
|
|||||||
FROM node:22-alpine
|
FROM node:22-alpine AS base
|
||||||
|
|
||||||
|
ENV PNPM_HOME="/usr/local/pnpm"
|
||||||
|
ENV PATH="${PNPM_HOME}:${PATH}"
|
||||||
|
RUN corepack enable && corepack prepare pnpm@latest --activate
|
||||||
|
|
||||||
|
RUN pnpm add -g turbo@^2.5
|
||||||
|
|
||||||
|
FROM base AS builder
|
||||||
|
RUN apk update
|
||||||
|
RUN apk add --no-cache libc6-compat
|
||||||
|
|
||||||
# Set the working directory
|
|
||||||
WORKDIR /usr/app
|
WORKDIR /usr/app
|
||||||
|
|
||||||
# Copy package.json and package-lock.json
|
|
||||||
COPY package*.json ./
|
|
||||||
|
|
||||||
# Install dependencies
|
|
||||||
RUN npm install
|
|
||||||
|
|
||||||
# Change ownership to the non-root user
|
|
||||||
RUN chown -R node:node /usr/app
|
|
||||||
|
|
||||||
# Copy the rest of the application code
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
# Build the application
|
RUN turbo prune hub --docker
|
||||||
RUN npm run build
|
|
||||||
|
FROM base AS installer
|
||||||
|
RUN apk update
|
||||||
|
RUN apk add --no-cache libc6-compat
|
||||||
|
|
||||||
|
WORKDIR /usr/app
|
||||||
|
|
||||||
|
COPY --from=builder /usr/app/out/json/ .
|
||||||
|
RUN pnpm install --frozen-lockfile
|
||||||
|
|
||||||
|
# Build the project
|
||||||
|
COPY --from=builder /usr/app/out/full/ .
|
||||||
|
|
||||||
|
RUN turbo run build
|
||||||
|
|
||||||
|
FROM base AS runner
|
||||||
|
WORKDIR /usr/app
|
||||||
|
|
||||||
|
# Don't run production as root
|
||||||
|
RUN addgroup --system --gid 1001 nodejs
|
||||||
|
RUN adduser --system --uid 1001 nextjs
|
||||||
|
USER nextjs
|
||||||
|
|
||||||
|
# Automatically leverage output traces to reduce image size
|
||||||
|
# https://nextjs.org/docs/advanced-features/output-file-tracing
|
||||||
|
COPY --from=installer --chown=nextjs:nodejs /usr/app/ ./
|
||||||
|
|
||||||
# Expose the application port
|
# Expose the application port
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
|
||||||
# Run container as non-root (unprivileged) user
|
CMD ["pnpm", "--dir", "apps/hub", "run", "start"]
|
||||||
# The "node" user is provided in the Node.js Alpine base image
|
|
||||||
USER node
|
|
||||||
|
|
||||||
# Command to run the application
|
|
||||||
CMD ["npm", "start"]
|
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@hookform/resolvers": "^4.1.3",
|
"@hookform/resolvers": "^4.1.3",
|
||||||
"@next-auth/prisma-adapter": "^1.0.7",
|
"@next-auth/prisma-adapter": "^1.0.7",
|
||||||
|
"@radix-ui/react-icons": "^1.3.2",
|
||||||
"@repo/db": "*",
|
"@repo/db": "*",
|
||||||
"@tanstack/react-query": "^5.67.2",
|
"@tanstack/react-query": "^5.67.2",
|
||||||
"@tanstack/react-table": "^8.20.6",
|
"@tanstack/react-table": "^8.20.6",
|
||||||
@@ -40,6 +41,8 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/eslintrc": "^3",
|
"@eslint/eslintrc": "^3",
|
||||||
|
"@repo/eslint-config": "*",
|
||||||
|
"@repo/typescript-config": "*",
|
||||||
"@tailwindcss/postcss": "^4.0.8",
|
"@tailwindcss/postcss": "^4.0.8",
|
||||||
"@types/bcryptjs": "^2.4.6",
|
"@types/bcryptjs": "^2.4.6",
|
||||||
"@types/jsonwebtoken": "^9.0.8",
|
"@types/jsonwebtoken": "^9.0.8",
|
||||||
|
|||||||
27
docker-compose.mini.yml
Normal file
27
docker-compose.mini.yml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
services:
|
||||||
|
redis:
|
||||||
|
container_name: redis
|
||||||
|
image: redis/redis-stack:latest
|
||||||
|
ports:
|
||||||
|
- "6379:6379"
|
||||||
|
volumes:
|
||||||
|
- "redis_data:/data"
|
||||||
|
# Für den Zugriff auf den Host
|
||||||
|
livekit-server:
|
||||||
|
image: livekit/livekit-server
|
||||||
|
container_name: livekit_server
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "7880:7880"
|
||||||
|
- "7881:7881"
|
||||||
|
- "7882:7882/udp"
|
||||||
|
volumes:
|
||||||
|
- "./livekit.yaml:/livekit.yaml"
|
||||||
|
command:
|
||||||
|
- "--config"
|
||||||
|
- "/livekit.yaml"
|
||||||
|
- "--node-ip=127.0.0.1"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
redis_data:
|
||||||
|
driver: local
|
||||||
85
pnpm-lock.yaml
generated
85
pnpm-lock.yaml
generated
@@ -31,7 +31,7 @@ importers:
|
|||||||
version: 1.1.6
|
version: 1.1.6
|
||||||
'@livekit/track-processors':
|
'@livekit/track-processors':
|
||||||
specifier: ^0.5.6
|
specifier: ^0.5.6
|
||||||
version: 0.5.6(livekit-client@2.13.3(@types/dom-mediacapture-record@1.0.22))
|
version: 0.5.7(@types/dom-mediacapture-transform@0.1.11)(livekit-client@2.13.3(@types/dom-mediacapture-record@1.0.22))
|
||||||
'@next-auth/prisma-adapter':
|
'@next-auth/prisma-adapter':
|
||||||
specifier: ^1.0.7
|
specifier: ^1.0.7
|
||||||
version: 1.0.7(@prisma/client@6.8.2(prisma@6.8.2(typescript@5.8.3))(typescript@5.8.3))(next-auth@4.24.11(next@15.3.2(@babel/core@7.27.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(nodemailer@6.10.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))
|
version: 1.0.7(@prisma/client@6.8.2(prisma@6.8.2(typescript@5.8.3))(typescript@5.8.3))(next-auth@4.24.11(next@15.3.2(@babel/core@7.27.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(nodemailer@6.10.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))
|
||||||
@@ -46,7 +46,7 @@ importers:
|
|||||||
version: 4.1.7
|
version: 4.1.7
|
||||||
'@tanstack/react-query':
|
'@tanstack/react-query':
|
||||||
specifier: ^5.75.4
|
specifier: ^5.75.4
|
||||||
version: 5.77.0(react@19.1.0)
|
version: 5.77.2(react@19.1.0)
|
||||||
'@types/jsonwebtoken':
|
'@types/jsonwebtoken':
|
||||||
specifier: ^9.0.9
|
specifier: ^9.0.9
|
||||||
version: 9.0.9
|
version: 9.0.9
|
||||||
@@ -205,6 +205,9 @@ importers:
|
|||||||
'@types/cookie-parser':
|
'@types/cookie-parser':
|
||||||
specifier: ^1.4.8
|
specifier: ^1.4.8
|
||||||
version: 1.4.8(@types/express@5.0.2)
|
version: 1.4.8(@types/express@5.0.2)
|
||||||
|
'@types/cors':
|
||||||
|
specifier: ^2.8.18
|
||||||
|
version: 2.8.18
|
||||||
'@types/express':
|
'@types/express':
|
||||||
specifier: ^5.0.0
|
specifier: ^5.0.0
|
||||||
version: 5.0.2
|
version: 5.0.2
|
||||||
@@ -229,12 +232,15 @@ importers:
|
|||||||
'@next-auth/prisma-adapter':
|
'@next-auth/prisma-adapter':
|
||||||
specifier: ^1.0.7
|
specifier: ^1.0.7
|
||||||
version: 1.0.7(@prisma/client@6.8.2(prisma@6.8.2(typescript@5.8.3))(typescript@5.8.3))(next-auth@4.24.11(next@15.3.2(@babel/core@7.27.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(nodemailer@6.10.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))
|
version: 1.0.7(@prisma/client@6.8.2(prisma@6.8.2(typescript@5.8.3))(typescript@5.8.3))(next-auth@4.24.11(next@15.3.2(@babel/core@7.27.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(nodemailer@6.10.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))
|
||||||
|
'@radix-ui/react-icons':
|
||||||
|
specifier: ^1.3.2
|
||||||
|
version: 1.3.2(react@19.1.0)
|
||||||
'@repo/db':
|
'@repo/db':
|
||||||
specifier: '*'
|
specifier: '*'
|
||||||
version: link:../../packages/database
|
version: link:../../packages/database
|
||||||
'@tanstack/react-query':
|
'@tanstack/react-query':
|
||||||
specifier: ^5.67.2
|
specifier: ^5.67.2
|
||||||
version: 5.77.0(react@19.1.0)
|
version: 5.77.2(react@19.1.0)
|
||||||
'@tanstack/react-table':
|
'@tanstack/react-table':
|
||||||
specifier: ^8.20.6
|
specifier: ^8.20.6
|
||||||
version: 8.21.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
version: 8.21.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
@@ -282,7 +288,7 @@ importers:
|
|||||||
version: 19.1.0
|
version: 19.1.0
|
||||||
react-datepicker:
|
react-datepicker:
|
||||||
specifier: ^8.1.0
|
specifier: ^8.1.0
|
||||||
version: 8.3.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
version: 8.4.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
react-day-picker:
|
react-day-picker:
|
||||||
specifier: ^9.6.2
|
specifier: ^9.6.2
|
||||||
version: 9.7.0(react@19.1.0)
|
version: 9.7.0(react@19.1.0)
|
||||||
@@ -311,6 +317,12 @@ importers:
|
|||||||
'@eslint/eslintrc':
|
'@eslint/eslintrc':
|
||||||
specifier: ^3
|
specifier: ^3
|
||||||
version: 3.3.1
|
version: 3.3.1
|
||||||
|
'@repo/eslint-config':
|
||||||
|
specifier: '*'
|
||||||
|
version: link:../../packages/eslint-config
|
||||||
|
'@repo/typescript-config':
|
||||||
|
specifier: '*'
|
||||||
|
version: link:../../packages/typescript-config
|
||||||
'@tailwindcss/postcss':
|
'@tailwindcss/postcss':
|
||||||
specifier: ^4.0.8
|
specifier: ^4.0.8
|
||||||
version: 4.1.7
|
version: 4.1.7
|
||||||
@@ -381,12 +393,21 @@ importers:
|
|||||||
'@repo/typescript-config':
|
'@repo/typescript-config':
|
||||||
specifier: '*'
|
specifier: '*'
|
||||||
version: link:../../packages/typescript-config
|
version: link:../../packages/typescript-config
|
||||||
|
'@types/cors':
|
||||||
|
specifier: ^2.8.18
|
||||||
|
version: 2.8.18
|
||||||
|
'@types/express':
|
||||||
|
specifier: ^5.0.2
|
||||||
|
version: 5.0.2
|
||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^22.13.5
|
specifier: ^22.13.5
|
||||||
version: 22.15.21
|
version: 22.15.21
|
||||||
'@types/nodemailer':
|
'@types/nodemailer':
|
||||||
specifier: ^6.4.17
|
specifier: ^6.4.17
|
||||||
version: 6.4.17
|
version: 6.4.17
|
||||||
|
'@types/react':
|
||||||
|
specifier: ^19.1.5
|
||||||
|
version: 19.1.5
|
||||||
concurrently:
|
concurrently:
|
||||||
specifier: ^9.1.2
|
specifier: ^9.1.2
|
||||||
version: 9.1.2
|
version: 9.1.2
|
||||||
@@ -634,8 +655,8 @@ packages:
|
|||||||
react: '>=16.8.0'
|
react: '>=16.8.0'
|
||||||
react-dom: '>=16.8.0'
|
react-dom: '>=16.8.0'
|
||||||
|
|
||||||
'@floating-ui/react@0.27.8':
|
'@floating-ui/react@0.27.9':
|
||||||
resolution: {integrity: sha512-EQJ4Th328y2wyHR3KzOUOoTW2UKjFk53fmyahfwExnFQ8vnsMYqKc+fFPOkeYtj5tcp1DUMiNJ7BFhed7e9ONw==}
|
resolution: {integrity: sha512-Y0aCJBNtfVF6ikI1kVzA0WzSAhVBz79vFWOhvb5MLCRNODZ1ylGSLTuncchR7JsLyn9QzV6JD44DyZhhOtvpRw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
react: '>=17.0.0'
|
react: '>=17.0.0'
|
||||||
react-dom: '>=17.0.0'
|
react-dom: '>=17.0.0'
|
||||||
@@ -839,9 +860,10 @@ packages:
|
|||||||
'@livekit/protocol@1.38.0':
|
'@livekit/protocol@1.38.0':
|
||||||
resolution: {integrity: sha512-XX6ulvsE1XCN18LVf3ydHN7Ri1Z1M1P5dQdjnm5nVDsSqUL12Vbo/4RKcRlCEXAg2qB62mKjcaVLXVwkfXggkg==}
|
resolution: {integrity: sha512-XX6ulvsE1XCN18LVf3ydHN7Ri1Z1M1P5dQdjnm5nVDsSqUL12Vbo/4RKcRlCEXAg2qB62mKjcaVLXVwkfXggkg==}
|
||||||
|
|
||||||
'@livekit/track-processors@0.5.6':
|
'@livekit/track-processors@0.5.7':
|
||||||
resolution: {integrity: sha512-TlzObrSlp2PKor4VXqg6iefLRFVEb2T1lXwddBFdkPod60XVgYoMOj7V5xJm+UTE2MEtlE0003vUli9PyQGB1g==}
|
resolution: {integrity: sha512-/2SkuVAF+YiPNtOi9zQJz/yH1WGaK53XZ3PaESpLOiEYUBsYky13BrriXCXUf6kwn5R5+7ZsYWc2k3XSsAuLtg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
'@types/dom-mediacapture-transform': ^0.1.9
|
||||||
livekit-client: ^1.12.0 || ^2.1.0
|
livekit-client: ^1.12.0 || ^2.1.0
|
||||||
|
|
||||||
'@mediapipe/tasks-vision@0.10.14':
|
'@mediapipe/tasks-vision@0.10.14':
|
||||||
@@ -1249,11 +1271,11 @@ packages:
|
|||||||
'@tailwindcss/postcss@4.1.7':
|
'@tailwindcss/postcss@4.1.7':
|
||||||
resolution: {integrity: sha512-88g3qmNZn7jDgrrcp3ZXEQfp9CVox7xjP1HN2TFKI03CltPVd/c61ydn5qJJL8FYunn0OqBaW5HNUga0kmPVvw==}
|
resolution: {integrity: sha512-88g3qmNZn7jDgrrcp3ZXEQfp9CVox7xjP1HN2TFKI03CltPVd/c61ydn5qJJL8FYunn0OqBaW5HNUga0kmPVvw==}
|
||||||
|
|
||||||
'@tanstack/query-core@5.77.0':
|
'@tanstack/query-core@5.77.2':
|
||||||
resolution: {integrity: sha512-PFeWjgMQjOsnxBwnW/TJoO0pCja2dzuMQoZ3Diho7dPz7FnTUwTrjNmdf08evrhSE5nvPIKeqV6R0fvQfmhGeg==}
|
resolution: {integrity: sha512-1lqJwPsR6GX6nZFw06erRt518O19tWU6Q+x0fJUygl4lxHCYF2nhzBPwLKk2NPjYOrpR0K567hxPc5K++xDe9Q==}
|
||||||
|
|
||||||
'@tanstack/react-query@5.77.0':
|
'@tanstack/react-query@5.77.2':
|
||||||
resolution: {integrity: sha512-jX52ot8WxWzWnAknpRSEWj6PTR/7nkULOfoiaVPk6nKu0otwt30UMBC9PTg/m1x0uhz1g71/imwjViTm/oYHxA==}
|
resolution: {integrity: sha512-BRHxWdy1mHmgAcYA/qy2IPLylT81oebLgkm9K85viN2Qol/Vq48t1dzDFeDIVQjTWDV96AmqsLNPlH5HjyKCxA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
react: ^18 || ^19
|
react: ^18 || ^19
|
||||||
|
|
||||||
@@ -1294,6 +1316,12 @@ packages:
|
|||||||
'@types/dom-mediacapture-record@1.0.22':
|
'@types/dom-mediacapture-record@1.0.22':
|
||||||
resolution: {integrity: sha512-mUMZLK3NvwRLcAAT9qmcK+9p7tpU2FHdDsntR3YI4+GY88XrgG4XiE7u1Q2LAN2/FZOz/tdMDC3GQCR4T8nFuw==}
|
resolution: {integrity: sha512-mUMZLK3NvwRLcAAT9qmcK+9p7tpU2FHdDsntR3YI4+GY88XrgG4XiE7u1Q2LAN2/FZOz/tdMDC3GQCR4T8nFuw==}
|
||||||
|
|
||||||
|
'@types/dom-mediacapture-transform@0.1.11':
|
||||||
|
resolution: {integrity: sha512-Y2p+nGf1bF2XMttBnsVPHUWzRRZzqUoJAKmiP10b5umnO6DDrWI0BrGDJy1pOHoOULVmGSfFNkQrAlC5dcj6nQ==}
|
||||||
|
|
||||||
|
'@types/dom-webcodecs@0.1.15':
|
||||||
|
resolution: {integrity: sha512-omOlCPvTWyPm4ZE5bZUhlSvnHM2ZWM2U+1cPiYFL/e8aV5O9MouELp+L4dMKNTON0nTeHqEg+KWDfFQMY5Wkaw==}
|
||||||
|
|
||||||
'@types/eslint-scope@3.7.7':
|
'@types/eslint-scope@3.7.7':
|
||||||
resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==}
|
resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==}
|
||||||
|
|
||||||
@@ -3594,8 +3622,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==}
|
resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==}
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
|
|
||||||
react-datepicker@8.3.0:
|
react-datepicker@8.4.0:
|
||||||
resolution: {integrity: sha512-DhfrIJnTPJTUVRtXU7c7zooug40rD6q+Fc8UTCt19dYEotLpDQgTN98MfocY6Rc4S99oOFFEoxyanOM/TKauuw==}
|
resolution: {integrity: sha512-6nPDnj8vektWCIOy9ArS3avus9Ndsyz5XgFCJ7nBxXASSpBdSL6lG9jzNNmViPOAOPh6T5oJyGaXuMirBLECag==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
react: ^16.9.0 || ^17 || ^18 || ^19 || ^19.0.0-rc
|
react: ^16.9.0 || ^17 || ^18 || ^19 || ^19.0.0-rc
|
||||||
react-dom: ^16.9.0 || ^17 || ^18 || ^19 || ^19.0.0-rc
|
react-dom: ^16.9.0 || ^17 || ^18 || ^19 || ^19.0.0-rc
|
||||||
@@ -4027,8 +4055,8 @@ packages:
|
|||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
tinyglobby@0.2.13:
|
tinyglobby@0.2.14:
|
||||||
resolution: {integrity: sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==}
|
resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==}
|
||||||
engines: {node: '>=12.0.0'}
|
engines: {node: '>=12.0.0'}
|
||||||
|
|
||||||
to-regex-range@5.0.1:
|
to-regex-range@5.0.1:
|
||||||
@@ -4622,7 +4650,7 @@ snapshots:
|
|||||||
react: 19.1.0
|
react: 19.1.0
|
||||||
react-dom: 19.1.0(react@19.1.0)
|
react-dom: 19.1.0(react@19.1.0)
|
||||||
|
|
||||||
'@floating-ui/react@0.27.8(react-dom@19.1.0(react@19.1.0))(react@19.1.0)':
|
'@floating-ui/react@0.27.9(react-dom@19.1.0(react@19.1.0))(react@19.1.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@floating-ui/react-dom': 2.1.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
'@floating-ui/react-dom': 2.1.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
'@floating-ui/utils': 0.2.9
|
'@floating-ui/utils': 0.2.9
|
||||||
@@ -4783,9 +4811,10 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@bufbuild/protobuf': 1.10.1
|
'@bufbuild/protobuf': 1.10.1
|
||||||
|
|
||||||
'@livekit/track-processors@0.5.6(livekit-client@2.13.3(@types/dom-mediacapture-record@1.0.22))':
|
'@livekit/track-processors@0.5.7(@types/dom-mediacapture-transform@0.1.11)(livekit-client@2.13.3(@types/dom-mediacapture-record@1.0.22))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@mediapipe/tasks-vision': 0.10.14
|
'@mediapipe/tasks-vision': 0.10.14
|
||||||
|
'@types/dom-mediacapture-transform': 0.1.11
|
||||||
livekit-client: 2.13.3(@types/dom-mediacapture-record@1.0.22)
|
livekit-client: 2.13.3(@types/dom-mediacapture-record@1.0.22)
|
||||||
|
|
||||||
'@mediapipe/tasks-vision@0.10.14': {}
|
'@mediapipe/tasks-vision@0.10.14': {}
|
||||||
@@ -5136,11 +5165,11 @@ snapshots:
|
|||||||
postcss: 8.5.3
|
postcss: 8.5.3
|
||||||
tailwindcss: 4.1.7
|
tailwindcss: 4.1.7
|
||||||
|
|
||||||
'@tanstack/query-core@5.77.0': {}
|
'@tanstack/query-core@5.77.2': {}
|
||||||
|
|
||||||
'@tanstack/react-query@5.77.0(react@19.1.0)':
|
'@tanstack/react-query@5.77.2(react@19.1.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tanstack/query-core': 5.77.0
|
'@tanstack/query-core': 5.77.2
|
||||||
react: 19.1.0
|
react: 19.1.0
|
||||||
|
|
||||||
'@tanstack/react-table@8.21.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0)':
|
'@tanstack/react-table@8.21.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0)':
|
||||||
@@ -5181,6 +5210,12 @@ snapshots:
|
|||||||
|
|
||||||
'@types/dom-mediacapture-record@1.0.22': {}
|
'@types/dom-mediacapture-record@1.0.22': {}
|
||||||
|
|
||||||
|
'@types/dom-mediacapture-transform@0.1.11':
|
||||||
|
dependencies:
|
||||||
|
'@types/dom-webcodecs': 0.1.15
|
||||||
|
|
||||||
|
'@types/dom-webcodecs@0.1.15': {}
|
||||||
|
|
||||||
'@types/eslint-scope@3.7.7':
|
'@types/eslint-scope@3.7.7':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/eslint': 9.6.1
|
'@types/eslint': 9.6.1
|
||||||
@@ -6218,7 +6253,7 @@ snapshots:
|
|||||||
get-tsconfig: 4.10.1
|
get-tsconfig: 4.10.1
|
||||||
is-bun-module: 2.0.0
|
is-bun-module: 2.0.0
|
||||||
stable-hash: 0.0.5
|
stable-hash: 0.0.5
|
||||||
tinyglobby: 0.2.13
|
tinyglobby: 0.2.14
|
||||||
unrs-resolver: 1.7.2
|
unrs-resolver: 1.7.2
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.27.0(jiti@2.4.2))
|
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.27.0(jiti@2.4.2))
|
||||||
@@ -7897,9 +7932,9 @@ snapshots:
|
|||||||
iconv-lite: 0.4.24
|
iconv-lite: 0.4.24
|
||||||
unpipe: 1.0.0
|
unpipe: 1.0.0
|
||||||
|
|
||||||
react-datepicker@8.3.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0):
|
react-datepicker@8.4.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@floating-ui/react': 0.27.8(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
'@floating-ui/react': 0.27.9(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
clsx: 2.1.1
|
clsx: 2.1.1
|
||||||
date-fns: 4.1.0
|
date-fns: 4.1.0
|
||||||
react: 19.1.0
|
react: 19.1.0
|
||||||
@@ -8530,7 +8565,7 @@ snapshots:
|
|||||||
commander: 2.20.3
|
commander: 2.20.3
|
||||||
source-map-support: 0.5.21
|
source-map-support: 0.5.21
|
||||||
|
|
||||||
tinyglobby@0.2.13:
|
tinyglobby@0.2.14:
|
||||||
dependencies:
|
dependencies:
|
||||||
fdir: 6.4.4(picomatch@4.0.2)
|
fdir: 6.4.4(picomatch@4.0.2)
|
||||||
picomatch: 4.0.2
|
picomatch: 4.0.2
|
||||||
|
|||||||
0
tsconfig.json
Normal file
0
tsconfig.json
Normal file
Reference in New Issue
Block a user