right before packages, env, db, and auth refactor
removing env validation, moving db and auth to each app
This commit is contained in:
parent
04c09b439b
commit
811491ba9c
|
|
@ -14,6 +14,7 @@
|
|||
"dependencies": {
|
||||
"@hookform/resolvers": "^3.9.1",
|
||||
"@opencut/env": "workspace:*",
|
||||
"@opencut/ui": "workspace:*",
|
||||
"@radix-ui/react-separator": "^1.1.7",
|
||||
"@upstash/ratelimit": "^2.0.6",
|
||||
"@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 { SITE_URL } from "@/constants/site-constants";
|
||||
|
||||
|
|
@ -13,9 +10,7 @@ export const metadata: Metadata = {
|
|||
export default async function Home() {
|
||||
return (
|
||||
<div>
|
||||
<Header />
|
||||
<Hero />
|
||||
<Footer />
|
||||
<h1>Hello World</h1>
|
||||
</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/db": "workspace:*",
|
||||
"@opencut/env": "workspace:*",
|
||||
"@opencut/ui": "workspace:*",
|
||||
"@radix-ui/react-separator": "^1.1.7",
|
||||
"@upstash/ratelimit": "^2.0.6",
|
||||
"@upstash/redis": "^1.35.4",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
|||
import { Button } from "@/components/ui/button";
|
||||
import { ExternalLink } from "lucide-react";
|
||||
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 { GitHubContributeSection } from "@/components/gitHub-contribute-section";
|
||||
import { BasePage } from "../base-page";
|
||||
|
|
@ -75,7 +75,7 @@ export default async function ContributorsPage() {
|
|||
title="Contributors"
|
||||
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={totalContributions} label="contributions" />
|
||||
</div>
|
||||
|
|
|
|||
45
bun.lock
45
bun.lock
|
|
@ -18,23 +18,18 @@
|
|||
"dependencies": {
|
||||
"@hookform/resolvers": "^3.9.1",
|
||||
"@opencut/env": "workspace:*",
|
||||
"@opencut/ui": "workspace:*",
|
||||
"@radix-ui/react-separator": "^1.1.7",
|
||||
"@upstash/ratelimit": "^2.0.6",
|
||||
"@upstash/redis": "^1.35.4",
|
||||
"@vercel/analytics": "^1.4.1",
|
||||
"aws4fetch": "^1.0.20",
|
||||
"better-auth": "^1.2.7",
|
||||
"botid": "^1.4.2",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"cmdk": "^1.0.0",
|
||||
"dayjs": "^1.11.13",
|
||||
"dotenv": "^16.5.0",
|
||||
"drizzle-orm": "^0.44.2",
|
||||
"embla-carousel-react": "^8.5.1",
|
||||
"eventemitter3": "^5.0.1",
|
||||
"feed": "^5.1.0",
|
||||
"framer-motion": "^11.13.1",
|
||||
"input-otp": "^1.4.1",
|
||||
"lucide-react": "^0.468.0",
|
||||
"mediabunny": "^1.9.3",
|
||||
|
|
@ -45,7 +40,6 @@
|
|||
"pg": "^8.16.2",
|
||||
"radix-ui": "^1.4.2",
|
||||
"react": "^18.2.0",
|
||||
"react-country-flag": "^3.1.0",
|
||||
"react-day-picker": "^8.10.1",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-hook-form": "^7.54.0",
|
||||
|
|
@ -62,10 +56,7 @@
|
|||
"sonner": "^1.7.1",
|
||||
"tailwind-merge": "^2.5.5",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"unified": "^11.0.5",
|
||||
"use-deep-compare-effect": "^1.8.1",
|
||||
"vaul": "^1.1.1",
|
||||
"wavesurfer.js": "^7.9.8",
|
||||
"zod": "^3.25.67",
|
||||
"zustand": "^5.0.2",
|
||||
},
|
||||
|
|
@ -99,6 +90,7 @@
|
|||
"@opencut/auth": "workspace:*",
|
||||
"@opencut/db": "workspace:*",
|
||||
"@opencut/env": "workspace:*",
|
||||
"@opencut/ui": "workspace:*",
|
||||
"@radix-ui/react-separator": "^1.1.7",
|
||||
"@upstash/ratelimit": "^2.0.6",
|
||||
"@upstash/redis": "^1.35.4",
|
||||
|
|
@ -115,7 +107,6 @@
|
|||
"embla-carousel-react": "^8.5.1",
|
||||
"eventemitter3": "^5.0.1",
|
||||
"feed": "^5.1.0",
|
||||
"framer-motion": "^11.13.1",
|
||||
"input-otp": "^1.4.1",
|
||||
"lucide-react": "^0.468.0",
|
||||
"mediabunny": "^1.9.3",
|
||||
|
|
@ -210,6 +201,18 @@
|
|||
"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": [
|
||||
"@tailwindcss/oxide",
|
||||
|
|
@ -411,6 +414,8 @@
|
|||
|
||||
"@opencut/tools": ["@opencut/tools@workspace:apps/tools"],
|
||||
|
||||
"@opencut/ui": ["@opencut/ui@workspace:packages/ui"],
|
||||
|
||||
"@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=="],
|
||||
|
|
@ -779,7 +784,7 @@
|
|||
|
||||
"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=="],
|
||||
|
||||
|
|
@ -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-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=="],
|
||||
|
||||
|
|
@ -1217,6 +1222,10 @@
|
|||
|
||||
"@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/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=="],
|
||||
|
||||
"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=="],
|
||||
|
||||
"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/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/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=="],
|
||||
|
||||
"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=="],
|
||||
|
||||
"@opencut/tools/next/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { z } from "zod";
|
||||
|
||||
const envSchema = z.object({
|
||||
const webEnvSchema = z.object({
|
||||
// Node
|
||||
NODE_ENV: z.enum(["development", "production", "test"]),
|
||||
ANALYZE: z.string().optional(),
|
||||
|
|
@ -29,6 +29,6 @@ const envSchema = z.object({
|
|||
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"]
|
||||
}
|
||||
Loading…
Reference in New Issue