mirror of
https://github.com/OpenCut-app/OpenCut.git
synced 2026-07-13 21:52:53 +02:00
right before packages, env, db, and auth refactor
removing env validation, moving db and auth to each app
This commit is contained in:
@@ -14,6 +14,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@hookform/resolvers": "^3.9.1",
|
"@hookform/resolvers": "^3.9.1",
|
||||||
"@opencut/env": "workspace:*",
|
"@opencut/env": "workspace:*",
|
||||||
|
"@opencut/ui": "workspace:*",
|
||||||
"@radix-ui/react-separator": "^1.1.7",
|
"@radix-ui/react-separator": "^1.1.7",
|
||||||
"@upstash/ratelimit": "^2.0.6",
|
"@upstash/ratelimit": "^2.0.6",
|
||||||
"@upstash/redis": "^1.35.4",
|
"@upstash/redis": "^1.35.4",
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
import { Hero } from "@/components/landing/hero";
|
|
||||||
import { Header } from "@/components/header";
|
|
||||||
import { Footer } from "@/components/footer";
|
|
||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
import { SITE_URL } from "@/constants/site-constants";
|
import { SITE_URL } from "@/constants/site-constants";
|
||||||
|
|
||||||
@@ -13,9 +10,7 @@ export const metadata: Metadata = {
|
|||||||
export default async function Home() {
|
export default async function Home() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Header />
|
<h1>Hello World</h1>
|
||||||
<Hero />
|
|
||||||
<Footer />
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,113 @@
|
|||||||
|
import Link from "next/link";
|
||||||
|
import { RiDiscordFill, RiTwitterXLine } from "react-icons/ri";
|
||||||
|
import { FaGithub } from "react-icons/fa6";
|
||||||
|
import Image from "next/image";
|
||||||
|
import { DEFAULT_LOGO_URL, SOCIAL_LINKS } from "@/constants/site-constants";
|
||||||
|
import { capitalizeFirstLetter } from "@/lib/utils";
|
||||||
|
|
||||||
|
type Category = "resources" | "company";
|
||||||
|
|
||||||
|
interface Link {
|
||||||
|
label: string;
|
||||||
|
href: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
type CategoryLinks = Record<Category, Link[]>;
|
||||||
|
|
||||||
|
const links: CategoryLinks = {
|
||||||
|
resources: [
|
||||||
|
{ label: "Roadmap", href: "/roadmap" },
|
||||||
|
{ label: "Blog", href: "/blog" },
|
||||||
|
{ label: "Privacy", href: "/privacy" },
|
||||||
|
{ label: "Terms of use", href: "/terms" },
|
||||||
|
],
|
||||||
|
company: [
|
||||||
|
{ label: "Contributors", href: "/contributors" },
|
||||||
|
{ label: "Sponsors", href: "/sponsors" },
|
||||||
|
{ label: "Branding", href: "/branding" },
|
||||||
|
{ label: "About", href: `${SOCIAL_LINKS.github}/blob/main/README.md` },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
export function Footer() {
|
||||||
|
return (
|
||||||
|
<footer className="bg-background border-t">
|
||||||
|
<div className="mx-auto max-w-5xl px-8 py-10">
|
||||||
|
<div className="mb-8 grid grid-cols-1 gap-12 md:grid-cols-2">
|
||||||
|
{/* Brand Section */}
|
||||||
|
<div className="max-w-sm md:col-span-1">
|
||||||
|
<div className="mb-4 flex items-center justify-start gap-2">
|
||||||
|
<Image
|
||||||
|
src={DEFAULT_LOGO_URL}
|
||||||
|
alt="OpenCut"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
className="invert dark:invert-0"
|
||||||
|
/>
|
||||||
|
<span className="text-lg font-bold">OpenCut</span>
|
||||||
|
</div>
|
||||||
|
<p className="text-muted-foreground mb-5 text-sm md:text-left">
|
||||||
|
The open source video editor that gets the job done. Simple,
|
||||||
|
powerful, and works on any platform.
|
||||||
|
</p>
|
||||||
|
<div className="flex justify-start gap-3">
|
||||||
|
<Link
|
||||||
|
href={SOCIAL_LINKS.github}
|
||||||
|
className="text-muted-foreground hover:text-foreground transition-colors"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
<FaGithub className="h-5 w-5" />
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href={SOCIAL_LINKS.x}
|
||||||
|
className="text-muted-foreground hover:text-foreground transition-colors"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
<RiTwitterXLine className="h-5 w-5" />
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href={SOCIAL_LINKS.discord}
|
||||||
|
className="text-muted-foreground hover:text-foreground transition-colors"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
<RiDiscordFill className="h-5 w-5" />
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-start justify-start gap-12 py-2">
|
||||||
|
{(Object.keys(links) as Category[]).map((category) => (
|
||||||
|
<div key={category} className="flex flex-col gap-2">
|
||||||
|
<h3 className="text-foreground font-semibold">{capitalizeFirstLetter({ string: category })}</h3>
|
||||||
|
<ul className="space-y-2 text-sm">
|
||||||
|
{links[category].map((link) => (
|
||||||
|
<li key={link.href}>
|
||||||
|
<Link
|
||||||
|
href={link.href}
|
||||||
|
className="text-muted-foreground hover:text-foreground transition-colors"
|
||||||
|
target={link.href.startsWith("http") ? "_blank" : undefined}
|
||||||
|
rel={link.href.startsWith("http") ? "noopener noreferrer" : undefined}
|
||||||
|
>
|
||||||
|
{link.label}
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Bottom Section */}
|
||||||
|
<div className="flex flex-col items-start justify-between gap-4 pt-2 md:flex-row">
|
||||||
|
<div className="text-muted-foreground flex items-center gap-4 text-sm">
|
||||||
|
<span>© 2025 OpenCut, All Rights Reserved</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useState } from "react";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { motion } from "motion/react";
|
||||||
|
import { Button } from "./ui/button";
|
||||||
|
import { ArrowRight } from "lucide-react";
|
||||||
|
import Image from "next/image";
|
||||||
|
import { ThemeToggle } from "./theme-toggle";
|
||||||
|
import { GithubIcon, MenuIcon } from "@opencut/ui/icons";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
import { DEFAULT_LOGO_URL, SOCIAL_LINKS } from "@/constants/site-constants";
|
||||||
|
|
||||||
|
export function Header() {
|
||||||
|
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
||||||
|
|
||||||
|
const links = [
|
||||||
|
{
|
||||||
|
label: "Contributors",
|
||||||
|
href: "/contributors",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Sponsors",
|
||||||
|
href: "/sponsors",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Blog",
|
||||||
|
href: "/blog",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<header className="bg-background shadow-background/85 sticky top-0 z-10 shadow-[0_30px_35px_15px_rgba(0,0,0,1)]">
|
||||||
|
<div className="relative flex w-full items-center justify-between px-6 pt-4">
|
||||||
|
<div className="relative z-10 flex items-center gap-6">
|
||||||
|
<Link href="/" className="flex items-center gap-3">
|
||||||
|
<Image
|
||||||
|
src={DEFAULT_LOGO_URL}
|
||||||
|
alt="OpenCut Logo"
|
||||||
|
className="invert dark:invert-0"
|
||||||
|
width={32}
|
||||||
|
height={32}
|
||||||
|
/>
|
||||||
|
</Link>
|
||||||
|
<nav className="hidden items-center gap-4 md:flex">
|
||||||
|
{links.map((link) => (
|
||||||
|
<Link key={link.href} href={link.href}>
|
||||||
|
<Button variant="text" className="p-0 text-sm">
|
||||||
|
{link.label}
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="relative z-10">
|
||||||
|
<div className="flex items-center gap-3 md:hidden">
|
||||||
|
<Button
|
||||||
|
variant="text"
|
||||||
|
size="icon"
|
||||||
|
className="flex items-center justify-center p-0"
|
||||||
|
onClick={() => setIsMenuOpen(!isMenuOpen)}
|
||||||
|
>
|
||||||
|
<MenuIcon size={30} />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className="hidden items-center gap-3 md:flex">
|
||||||
|
<Link href={SOCIAL_LINKS.github}>
|
||||||
|
<Button className="bg-background text-sm" variant="outline">
|
||||||
|
<GithubIcon className="h-4 w-4" />
|
||||||
|
31k+
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
<Link href="/projects">
|
||||||
|
<Button className="text-sm">
|
||||||
|
Projects
|
||||||
|
<ArrowRight className="h-4 w-4" />
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
<ThemeToggle />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
"bg-background/20 pointer-events-none fixed inset-0 opacity-0 backdrop-blur-3xl",
|
||||||
|
"transition-opacity duration-150",
|
||||||
|
isMenuOpen && "pointer-events-auto opacity-100",
|
||||||
|
)}
|
||||||
|
onClick={() => setIsMenuOpen(false)}
|
||||||
|
>
|
||||||
|
<div className="relative h-full">
|
||||||
|
<nav className="flex flex-col gap-3 px-6 pt-[5rem]">
|
||||||
|
{links.map((link, index) => (
|
||||||
|
<motion.div
|
||||||
|
key={link.href}
|
||||||
|
initial={{ scale: 0.98, opacity: 0 }}
|
||||||
|
animate={{
|
||||||
|
scale: isMenuOpen ? 1 : 0.98,
|
||||||
|
opacity: isMenuOpen ? 1 : 0,
|
||||||
|
}}
|
||||||
|
transition={{
|
||||||
|
duration: 0.4,
|
||||||
|
delay: isMenuOpen ? index * 0.1 : 0,
|
||||||
|
ease: [0.25, 0.46, 0.45, 0.94],
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Link
|
||||||
|
href={link.href}
|
||||||
|
className="text-2xl font-semibold"
|
||||||
|
onClick={() => setIsMenuOpen(false)}
|
||||||
|
>
|
||||||
|
{link.label}
|
||||||
|
</Link>
|
||||||
|
</motion.div>
|
||||||
|
))}
|
||||||
|
</nav>
|
||||||
|
<ThemeToggle
|
||||||
|
className="absolute bottom-8 right-8 size-10"
|
||||||
|
iconClassName="!size-[1.2rem]"
|
||||||
|
onToggle={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -24,6 +24,7 @@
|
|||||||
"@opencut/auth": "workspace:*",
|
"@opencut/auth": "workspace:*",
|
||||||
"@opencut/db": "workspace:*",
|
"@opencut/db": "workspace:*",
|
||||||
"@opencut/env": "workspace:*",
|
"@opencut/env": "workspace:*",
|
||||||
|
"@opencut/ui": "workspace:*",
|
||||||
"@radix-ui/react-separator": "^1.1.7",
|
"@radix-ui/react-separator": "^1.1.7",
|
||||||
"@upstash/ratelimit": "^2.0.6",
|
"@upstash/ratelimit": "^2.0.6",
|
||||||
"@upstash/redis": "^1.35.4",
|
"@upstash/redis": "^1.35.4",
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
|||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { ExternalLink } from "lucide-react";
|
import { ExternalLink } from "lucide-react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { GithubIcon } from "@/components/icons";
|
import { GithubIcon } from "@opencut/ui/icons";
|
||||||
import { EXTERNAL_TOOLS, SOCIAL_LINKS } from "@/constants/site-constants";
|
import { EXTERNAL_TOOLS, SOCIAL_LINKS } from "@/constants/site-constants";
|
||||||
import { GitHubContributeSection } from "@/components/gitHub-contribute-section";
|
import { GitHubContributeSection } from "@/components/gitHub-contribute-section";
|
||||||
import { BasePage } from "../base-page";
|
import { BasePage } from "../base-page";
|
||||||
@@ -75,7 +75,7 @@ export default async function ContributorsPage() {
|
|||||||
title="Contributors"
|
title="Contributors"
|
||||||
description="Meet the amazing people who contribute to OpenCut, the free and open-source video editor."
|
description="Meet the amazing people who contribute to OpenCut, the free and open-source video editor."
|
||||||
>
|
>
|
||||||
<div className="flex items-center justify-center gap-8 text-sm -mt-4">
|
<div className="-mt-4 flex items-center justify-center gap-8 text-sm">
|
||||||
<StatItem value={contributors.length} label="contributors" />
|
<StatItem value={contributors.length} label="contributors" />
|
||||||
<StatItem value={totalContributions} label="contributions" />
|
<StatItem value={totalContributions} label="contributions" />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -18,23 +18,18 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@hookform/resolvers": "^3.9.1",
|
"@hookform/resolvers": "^3.9.1",
|
||||||
"@opencut/env": "workspace:*",
|
"@opencut/env": "workspace:*",
|
||||||
|
"@opencut/ui": "workspace:*",
|
||||||
"@radix-ui/react-separator": "^1.1.7",
|
"@radix-ui/react-separator": "^1.1.7",
|
||||||
"@upstash/ratelimit": "^2.0.6",
|
"@upstash/ratelimit": "^2.0.6",
|
||||||
"@upstash/redis": "^1.35.4",
|
"@upstash/redis": "^1.35.4",
|
||||||
"@vercel/analytics": "^1.4.1",
|
|
||||||
"aws4fetch": "^1.0.20",
|
"aws4fetch": "^1.0.20",
|
||||||
"better-auth": "^1.2.7",
|
"better-auth": "^1.2.7",
|
||||||
"botid": "^1.4.2",
|
"botid": "^1.4.2",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"cmdk": "^1.0.0",
|
"cmdk": "^1.0.0",
|
||||||
"dayjs": "^1.11.13",
|
|
||||||
"dotenv": "^16.5.0",
|
"dotenv": "^16.5.0",
|
||||||
"drizzle-orm": "^0.44.2",
|
|
||||||
"embla-carousel-react": "^8.5.1",
|
"embla-carousel-react": "^8.5.1",
|
||||||
"eventemitter3": "^5.0.1",
|
|
||||||
"feed": "^5.1.0",
|
|
||||||
"framer-motion": "^11.13.1",
|
|
||||||
"input-otp": "^1.4.1",
|
"input-otp": "^1.4.1",
|
||||||
"lucide-react": "^0.468.0",
|
"lucide-react": "^0.468.0",
|
||||||
"mediabunny": "^1.9.3",
|
"mediabunny": "^1.9.3",
|
||||||
@@ -45,7 +40,6 @@
|
|||||||
"pg": "^8.16.2",
|
"pg": "^8.16.2",
|
||||||
"radix-ui": "^1.4.2",
|
"radix-ui": "^1.4.2",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-country-flag": "^3.1.0",
|
|
||||||
"react-day-picker": "^8.10.1",
|
"react-day-picker": "^8.10.1",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-hook-form": "^7.54.0",
|
"react-hook-form": "^7.54.0",
|
||||||
@@ -62,10 +56,7 @@
|
|||||||
"sonner": "^1.7.1",
|
"sonner": "^1.7.1",
|
||||||
"tailwind-merge": "^2.5.5",
|
"tailwind-merge": "^2.5.5",
|
||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7",
|
||||||
"unified": "^11.0.5",
|
|
||||||
"use-deep-compare-effect": "^1.8.1",
|
|
||||||
"vaul": "^1.1.1",
|
"vaul": "^1.1.1",
|
||||||
"wavesurfer.js": "^7.9.8",
|
|
||||||
"zod": "^3.25.67",
|
"zod": "^3.25.67",
|
||||||
"zustand": "^5.0.2",
|
"zustand": "^5.0.2",
|
||||||
},
|
},
|
||||||
@@ -99,6 +90,7 @@
|
|||||||
"@opencut/auth": "workspace:*",
|
"@opencut/auth": "workspace:*",
|
||||||
"@opencut/db": "workspace:*",
|
"@opencut/db": "workspace:*",
|
||||||
"@opencut/env": "workspace:*",
|
"@opencut/env": "workspace:*",
|
||||||
|
"@opencut/ui": "workspace:*",
|
||||||
"@radix-ui/react-separator": "^1.1.7",
|
"@radix-ui/react-separator": "^1.1.7",
|
||||||
"@upstash/ratelimit": "^2.0.6",
|
"@upstash/ratelimit": "^2.0.6",
|
||||||
"@upstash/redis": "^1.35.4",
|
"@upstash/redis": "^1.35.4",
|
||||||
@@ -115,7 +107,6 @@
|
|||||||
"embla-carousel-react": "^8.5.1",
|
"embla-carousel-react": "^8.5.1",
|
||||||
"eventemitter3": "^5.0.1",
|
"eventemitter3": "^5.0.1",
|
||||||
"feed": "^5.1.0",
|
"feed": "^5.1.0",
|
||||||
"framer-motion": "^11.13.1",
|
|
||||||
"input-otp": "^1.4.1",
|
"input-otp": "^1.4.1",
|
||||||
"lucide-react": "^0.468.0",
|
"lucide-react": "^0.468.0",
|
||||||
"mediabunny": "^1.9.3",
|
"mediabunny": "^1.9.3",
|
||||||
@@ -210,6 +201,18 @@
|
|||||||
"typescript": "^5.8.3",
|
"typescript": "^5.8.3",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"packages/ui": {
|
||||||
|
"name": "@opencut/ui",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/react": "^19.2.7",
|
||||||
|
"react": "^19.2.0",
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/bun": "latest",
|
||||||
|
"typescript": "^5.8.3",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"trustedDependencies": [
|
"trustedDependencies": [
|
||||||
"@tailwindcss/oxide",
|
"@tailwindcss/oxide",
|
||||||
@@ -411,6 +414,8 @@
|
|||||||
|
|
||||||
"@opencut/tools": ["@opencut/tools@workspace:apps/tools"],
|
"@opencut/tools": ["@opencut/tools@workspace:apps/tools"],
|
||||||
|
|
||||||
|
"@opencut/ui": ["@opencut/ui@workspace:packages/ui"],
|
||||||
|
|
||||||
"@opencut/web": ["@opencut/web@workspace:apps/web"],
|
"@opencut/web": ["@opencut/web@workspace:apps/web"],
|
||||||
|
|
||||||
"@peculiar/asn1-android": ["@peculiar/asn1-android@2.4.0", "", { "dependencies": { "@peculiar/asn1-schema": "^2.4.0", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-YFueREq97CLslZZBI8dKzis7jMfEHSLxM+nr0Zdx1POiXFLjqqwoY5s0F1UimdBiEw/iKlHey2m56MRDv7Jtyg=="],
|
"@peculiar/asn1-android": ["@peculiar/asn1-android@2.4.0", "", { "dependencies": { "@peculiar/asn1-schema": "^2.4.0", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-YFueREq97CLslZZBI8dKzis7jMfEHSLxM+nr0Zdx1POiXFLjqqwoY5s0F1UimdBiEw/iKlHey2m56MRDv7Jtyg=="],
|
||||||
@@ -779,7 +784,7 @@
|
|||||||
|
|
||||||
"feed": ["feed@5.1.0", "", { "dependencies": { "xml-js": "^1.6.11" } }, "sha512-qGNhgYygnefSkAHHrNHqC7p3R8J0/xQDS/cYUud8er/qD9EFGWyCdUDfULHTJQN1d3H3WprzVwMc9MfB4J50Wg=="],
|
"feed": ["feed@5.1.0", "", { "dependencies": { "xml-js": "^1.6.11" } }, "sha512-qGNhgYygnefSkAHHrNHqC7p3R8J0/xQDS/cYUud8er/qD9EFGWyCdUDfULHTJQN1d3H3WprzVwMc9MfB4J50Wg=="],
|
||||||
|
|
||||||
"framer-motion": ["framer-motion@11.18.2", "", { "dependencies": { "motion-dom": "^11.18.1", "motion-utils": "^11.18.1", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-5F5Och7wrvtLVElIpclDT0CBzMVg3dL22B64aZwHtsIY8RB4mXICLrkajK4G9R+ieSAGcgrLeae2SeUTg2pr6w=="],
|
"framer-motion": ["framer-motion@12.23.6", "", { "dependencies": { "motion-dom": "^12.23.6", "motion-utils": "^12.23.6", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-dsJ389QImVE3lQvM8Mnk99/j8tiZDM/7706PCqvkQ8sSCnpmWxsgX+g0lj7r5OBVL0U36pIecCTBoIWcM2RuKw=="],
|
||||||
|
|
||||||
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
||||||
|
|
||||||
@@ -955,9 +960,9 @@
|
|||||||
|
|
||||||
"motion": ["motion@12.23.6", "", { "dependencies": { "framer-motion": "^12.23.6", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-6U55IW5i6Vut2ryKEhrZKg55490k9d6qdGXZoNSf98oQgDj5D7bqTnVJotQ6UW3AS6QfbW6KSLa7/e1gy+a07g=="],
|
"motion": ["motion@12.23.6", "", { "dependencies": { "framer-motion": "^12.23.6", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-6U55IW5i6Vut2ryKEhrZKg55490k9d6qdGXZoNSf98oQgDj5D7bqTnVJotQ6UW3AS6QfbW6KSLa7/e1gy+a07g=="],
|
||||||
|
|
||||||
"motion-dom": ["motion-dom@11.18.1", "", { "dependencies": { "motion-utils": "^11.18.1" } }, "sha512-g76KvA001z+atjfxczdRtw/RXOM3OMSdd1f4DL77qCTF/+avrRJiawSG4yDibEQ215sr9kpinSlX2pCTJ9zbhw=="],
|
"motion-dom": ["motion-dom@12.23.6", "", { "dependencies": { "motion-utils": "^12.23.6" } }, "sha512-G2w6Nw7ZOVSzcQmsdLc0doMe64O/Sbuc2bVAbgMz6oP/6/pRStKRiVRV4bQfHp5AHYAKEGhEdVHTM+R3FDgi5w=="],
|
||||||
|
|
||||||
"motion-utils": ["motion-utils@11.18.1", "", {}, "sha512-49Kt+HKjtbJKLtgO/LKj9Ld+6vw9BjH5d9sc40R/kVyH8GLAXgT42M2NnuPcJNuA3s9ZfZBUcwIgpmZWGEE+hA=="],
|
"motion-utils": ["motion-utils@12.23.6", "", {}, "sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ=="],
|
||||||
|
|
||||||
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||||
|
|
||||||
@@ -1217,6 +1222,10 @@
|
|||||||
|
|
||||||
"@opencut/tools/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
|
"@opencut/tools/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
|
||||||
|
|
||||||
|
"@opencut/ui/@types/react": ["@types/react@19.2.7", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg=="],
|
||||||
|
|
||||||
|
"@opencut/ui/react": ["react@19.2.0", "", {}, "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ=="],
|
||||||
|
|
||||||
"@opencut/web/@types/node": ["@types/node@24.2.1", "", { "dependencies": { "undici-types": "~7.10.0" } }, "sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ=="],
|
"@opencut/web/@types/node": ["@types/node@24.2.1", "", { "dependencies": { "undici-types": "~7.10.0" } }, "sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ=="],
|
||||||
|
|
||||||
"@opencut/web/next": ["next@15.5.3", "", { "dependencies": { "@next/env": "15.5.3", "@swc/helpers": "0.5.15", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "15.5.3", "@next/swc-darwin-x64": "15.5.3", "@next/swc-linux-arm64-gnu": "15.5.3", "@next/swc-linux-arm64-musl": "15.5.3", "@next/swc-linux-x64-gnu": "15.5.3", "@next/swc-linux-x64-musl": "15.5.3", "@next/swc-win32-arm64-msvc": "15.5.3", "@next/swc-win32-x64-msvc": "15.5.3", "sharp": "^0.34.3" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-r/liNAx16SQj4D+XH/oI1dlpv9tdKJ6cONYPwwcCC46f2NjpaRWY+EKCzULfgQYV6YKXjHBchff2IZBSlZmJNw=="],
|
"@opencut/web/next": ["next@15.5.3", "", { "dependencies": { "@next/env": "15.5.3", "@swc/helpers": "0.5.15", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "15.5.3", "@next/swc-darwin-x64": "15.5.3", "@next/swc-linux-arm64-gnu": "15.5.3", "@next/swc-linux-arm64-musl": "15.5.3", "@next/swc-linux-x64-gnu": "15.5.3", "@next/swc-linux-x64-musl": "15.5.3", "@next/swc-win32-arm64-msvc": "15.5.3", "@next/swc-win32-x64-msvc": "15.5.3", "sharp": "^0.34.3" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-r/liNAx16SQj4D+XH/oI1dlpv9tdKJ6cONYPwwcCC46f2NjpaRWY+EKCzULfgQYV6YKXjHBchff2IZBSlZmJNw=="],
|
||||||
@@ -1241,8 +1250,6 @@
|
|||||||
|
|
||||||
"better-auth/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
|
"better-auth/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
|
||||||
|
|
||||||
"motion/framer-motion": ["framer-motion@12.23.6", "", { "dependencies": { "motion-dom": "^12.23.6", "motion-utils": "^12.23.6", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-dsJ389QImVE3lQvM8Mnk99/j8tiZDM/7706PCqvkQ8sSCnpmWxsgX+g0lj7r5OBVL0U36pIecCTBoIWcM2RuKw=="],
|
|
||||||
|
|
||||||
"next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
|
"next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
|
||||||
|
|
||||||
"parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="],
|
"parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="],
|
||||||
@@ -1321,6 +1328,8 @@
|
|||||||
|
|
||||||
"@opencut/tools/next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
|
"@opencut/tools/next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
|
||||||
|
|
||||||
|
"@opencut/ui/@types/react/csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
|
||||||
|
|
||||||
"@opencut/web/@types/node/undici-types": ["undici-types@7.10.0", "", {}, "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag=="],
|
"@opencut/web/@types/node/undici-types": ["undici-types@7.10.0", "", {}, "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag=="],
|
||||||
|
|
||||||
"@opencut/web/next/@next/env": ["@next/env@15.5.3", "", {}, "sha512-RSEDTRqyihYXygx/OJXwvVupfr9m04+0vH8vyy0HfZ7keRto6VX9BbEk0J2PUk0VGy6YhklJUSrgForov5F9pw=="],
|
"@opencut/web/next/@next/env": ["@next/env@15.5.3", "", {}, "sha512-RSEDTRqyihYXygx/OJXwvVupfr9m04+0vH8vyy0HfZ7keRto6VX9BbEk0J2PUk0VGy6YhklJUSrgForov5F9pw=="],
|
||||||
@@ -1347,10 +1356,6 @@
|
|||||||
|
|
||||||
"@types/bun/bun-types/@types/node": ["@types/node@24.2.1", "", { "dependencies": { "undici-types": "~7.10.0" } }, "sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ=="],
|
"@types/bun/bun-types/@types/node": ["@types/node@24.2.1", "", { "dependencies": { "undici-types": "~7.10.0" } }, "sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ=="],
|
||||||
|
|
||||||
"motion/framer-motion/motion-dom": ["motion-dom@12.23.6", "", { "dependencies": { "motion-utils": "^12.23.6" } }, "sha512-G2w6Nw7ZOVSzcQmsdLc0doMe64O/Sbuc2bVAbgMz6oP/6/pRStKRiVRV4bQfHp5AHYAKEGhEdVHTM+R3FDgi5w=="],
|
|
||||||
|
|
||||||
"motion/framer-motion/motion-utils": ["motion-utils@12.23.6", "", {}, "sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ=="],
|
|
||||||
|
|
||||||
"next/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
|
"next/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
|
||||||
|
|
||||||
"@opencut/tools/next/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
|
"@opencut/tools/next/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
|
||||||
|
|||||||
Vendored
+30
@@ -0,0 +1,30 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
const toolsEnvSchema = z.object({
|
||||||
|
// Node
|
||||||
|
NODE_ENV: z.enum(["development", "production", "test"]),
|
||||||
|
ANALYZE: z.string().optional(),
|
||||||
|
NEXT_RUNTIME: z.enum(["nodejs", "edge"]).optional(),
|
||||||
|
|
||||||
|
// Public
|
||||||
|
NEXT_PUBLIC_SITE_URL: z.url().default("http://localhost:3000"),
|
||||||
|
NEXT_PUBLIC_MARBLE_API_URL: z.url(),
|
||||||
|
|
||||||
|
// Server
|
||||||
|
DATABASE_URL: z
|
||||||
|
.string()
|
||||||
|
.startsWith("postgres://")
|
||||||
|
.or(z.string().startsWith("postgresql://")),
|
||||||
|
|
||||||
|
BETTER_AUTH_SECRET: z.string(),
|
||||||
|
UPSTASH_REDIS_REST_URL: z.url(),
|
||||||
|
UPSTASH_REDIS_REST_TOKEN: z.string(),
|
||||||
|
CLOUDFLARE_ACCOUNT_ID: z.string(),
|
||||||
|
R2_ACCESS_KEY_ID: z.string(),
|
||||||
|
R2_SECRET_ACCESS_KEY: z.string(),
|
||||||
|
R2_BUCKET_NAME: z.string(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type ToolsEnv = z.infer<typeof toolsEnvSchema>;
|
||||||
|
|
||||||
|
export const toolsEnv = toolsEnvSchema.parse(process.env);
|
||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
const envSchema = z.object({
|
const webEnvSchema = z.object({
|
||||||
// Node
|
// Node
|
||||||
NODE_ENV: z.enum(["development", "production", "test"]),
|
NODE_ENV: z.enum(["development", "production", "test"]),
|
||||||
ANALYZE: z.string().optional(),
|
ANALYZE: z.string().optional(),
|
||||||
@@ -29,6 +29,6 @@ const envSchema = z.object({
|
|||||||
MODAL_TRANSCRIPTION_URL: z.url(),
|
MODAL_TRANSCRIPTION_URL: z.url(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export type Env = z.infer<typeof envSchema>;
|
export type WebEnv = z.infer<typeof webEnvSchema>;
|
||||||
|
|
||||||
export const env = envSchema.parse(process.env);
|
export const webEnv = webEnvSchema.parse(process.env);
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"name": "@opencut/ui",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"description": "UI package for OpenCut",
|
||||||
|
"main": "./src/index.ts",
|
||||||
|
"types": "./src/index.ts",
|
||||||
|
"exports": {
|
||||||
|
".": "./src/index.ts",
|
||||||
|
"./icons": "./src/icons/index.tsx"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/bun": "latest",
|
||||||
|
"typescript": "^5.8.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@types/react": "^19.2.7",
|
||||||
|
"react": "^19.2.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export * from "./icons";
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2020",
|
||||||
|
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||||
|
"module": "ESNext",
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"strict": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"noFallthroughCasesInSwitch": true
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"],
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user