veryfront 0.0.35 → 0.0.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/dist/ai/index.js +365 -179
  2. package/dist/ai/index.js.map +4 -4
  3. package/dist/ai/react.js +1 -3
  4. package/dist/ai/react.js.map +2 -2
  5. package/dist/cli.js +359 -2304
  6. package/dist/components.js +4 -2
  7. package/dist/components.js.map +2 -2
  8. package/dist/config.js +4 -2
  9. package/dist/config.js.map +2 -2
  10. package/dist/data.js +4 -2
  11. package/dist/data.js.map +2 -2
  12. package/dist/index.js +7 -2
  13. package/dist/index.js.map +2 -2
  14. package/dist/templates/ai/ai/agents/assistant.ts +20 -0
  15. package/dist/templates/ai/ai/prompts/assistant.ts +14 -0
  16. package/dist/templates/ai/ai/tools/get-weather.ts +29 -0
  17. package/dist/templates/ai/app/api/chat/route.ts +37 -0
  18. package/dist/templates/ai/app/layout.tsx +18 -0
  19. package/dist/templates/ai/app/page.tsx +28 -0
  20. package/dist/templates/ai/tsconfig.json +18 -0
  21. package/dist/templates/ai/veryfront.config.ts +9 -0
  22. package/dist/templates/app/_env.example +16 -0
  23. package/dist/templates/app/app/api/auth/login/route.ts +53 -0
  24. package/dist/templates/app/app/api/auth/logout/route.ts +27 -0
  25. package/dist/templates/app/app/api/auth/me/route.ts +34 -0
  26. package/dist/templates/app/app/api/auth/register/route.ts +42 -0
  27. package/dist/templates/app/app/api/stats/route.ts +21 -0
  28. package/dist/templates/app/app/api/users/route.ts +42 -0
  29. package/dist/templates/app/app/dashboard/page.tsx +29 -0
  30. package/dist/templates/app/app/layout.tsx +45 -0
  31. package/dist/templates/app/app/login/page.tsx +222 -0
  32. package/dist/templates/app/app/page.tsx +15 -0
  33. package/dist/templates/app/components/AuthProvider.tsx +51 -0
  34. package/dist/templates/app/components/DashboardLayout.tsx +142 -0
  35. package/dist/templates/app/components/FeatureGrid.tsx +98 -0
  36. package/dist/templates/app/components/Header.tsx +58 -0
  37. package/dist/templates/app/components/HeroSection.tsx +49 -0
  38. package/dist/templates/app/components/RecentActivity.tsx +98 -0
  39. package/dist/templates/app/components/StatsGrid.tsx +126 -0
  40. package/dist/templates/app/components/Toaster.tsx +113 -0
  41. package/dist/templates/app/lib/auth-client.ts +38 -0
  42. package/dist/templates/app/lib/auth.ts +49 -0
  43. package/dist/templates/app/lib/stats.ts +34 -0
  44. package/dist/templates/app/lib/users.ts +86 -0
  45. package/dist/templates/app/middleware/auth.ts +34 -0
  46. package/dist/templates/app/public/robots.txt +4 -0
  47. package/dist/templates/app/veryfront.config.js +74 -0
  48. package/dist/templates/blog/app/about/page.mdx +14 -0
  49. package/dist/templates/blog/app/archive/page.tsx +42 -0
  50. package/dist/templates/blog/app/blog/[slug]/page.tsx +47 -0
  51. package/dist/templates/blog/app/layout.tsx +54 -0
  52. package/dist/templates/blog/app/page.tsx +13 -0
  53. package/dist/templates/blog/components/BlogPostList.tsx +53 -0
  54. package/dist/templates/blog/components/MDXContent.tsx +26 -0
  55. package/dist/templates/blog/content/posts/hello-world.mdx +29 -0
  56. package/dist/templates/blog/content/posts/markdown-showcase.mdx +105 -0
  57. package/dist/templates/blog/lib/posts.ts +76 -0
  58. package/dist/templates/blog/lib/utils.ts +14 -0
  59. package/dist/templates/blog/public/robots.txt +4 -0
  60. package/dist/templates/blog/styles/globals.css +21 -0
  61. package/dist/templates/blog/veryfront.config.js +39 -0
  62. package/dist/templates/docs/app/docs/api/page.mdx +102 -0
  63. package/dist/templates/docs/app/docs/core-concepts/page.mdx +82 -0
  64. package/dist/templates/docs/app/docs/getting-started/page.mdx +67 -0
  65. package/dist/templates/docs/app/layout.tsx +41 -0
  66. package/dist/templates/docs/app/page.mdx +51 -0
  67. package/dist/templates/docs/components/CodeBlock.tsx +44 -0
  68. package/dist/templates/docs/components/Header.tsx +49 -0
  69. package/dist/templates/docs/components/Sidebar.tsx +68 -0
  70. package/dist/templates/docs/public/robots.txt +4 -0
  71. package/dist/templates/docs/styles/globals.css +48 -0
  72. package/dist/templates/docs/veryfront.config.js +47 -0
  73. package/dist/templates/minimal/app/about/page.mdx +18 -0
  74. package/dist/templates/minimal/app/layout.tsx +20 -0
  75. package/dist/templates/minimal/app/page.tsx +26 -0
  76. package/dist/templates/minimal/veryfront.config.js +29 -0
  77. package/package.json +1 -1
@@ -0,0 +1,20 @@
1
+ import { agent, promptRegistry } from "veryfront/ai";
2
+
3
+ function getSystemPrompt(): string {
4
+ const prompt = promptRegistry.get("assistant");
5
+ if (prompt) {
6
+ const content = prompt.getContent();
7
+ return typeof content === "string" ? content : "";
8
+ }
9
+ return "You are a helpful AI assistant.";
10
+ }
11
+
12
+ export default agent({
13
+ id: "assistant",
14
+ model: "openai/gpt-4o",
15
+ system: getSystemPrompt,
16
+ tools: {
17
+ getWeather: true,
18
+ },
19
+ maxSteps: 10,
20
+ });
@@ -0,0 +1,14 @@
1
+ import { prompt } from "veryfront/ai";
2
+
3
+ export default prompt({
4
+ id: "assistant",
5
+ description: "System prompt for the AI assistant",
6
+ content: `You are a helpful AI assistant with access to weather information.
7
+
8
+ When users ask about the weather:
9
+ 1. Use the getWeather tool to fetch current conditions
10
+ 2. Provide a friendly summary of the weather
11
+ 3. Suggest appropriate activities based on conditions
12
+
13
+ Be conversational and helpful. If you don't know something, say so honestly.`,
14
+ });
@@ -0,0 +1,29 @@
1
+ import { tool } from "veryfront/ai";
2
+ import { z } from "zod";
3
+
4
+ export default tool({
5
+ description: "Get the current weather for a location",
6
+ inputSchema: z.object({
7
+ location: z.string().describe("The city and state, e.g. San Francisco, CA"),
8
+ }),
9
+ execute: ({ location }: { location: string }) => {
10
+ const mockWeather: Record<string, { temp: number; condition: string }> = {
11
+ "San Francisco, CA": { temp: 65, condition: "Foggy" },
12
+ "New York, NY": { temp: 75, condition: "Sunny" },
13
+ "London, UK": { temp: 60, condition: "Rainy" },
14
+ "Tokyo, Japan": { temp: 80, condition: "Humid" },
15
+ };
16
+
17
+ const weather = mockWeather[location] || {
18
+ temp: 70,
19
+ condition: "Clear",
20
+ };
21
+
22
+ return {
23
+ location,
24
+ temperature: weather.temp,
25
+ condition: weather.condition,
26
+ unit: "fahrenheit",
27
+ };
28
+ },
29
+ });
@@ -0,0 +1,37 @@
1
+ import { z } from "zod";
2
+ import { getAgent } from "veryfront/ai";
3
+
4
+ const messageSchema = z.object({
5
+ role: z.enum(["user", "assistant", "system"]),
6
+ content: z.string().max(10000),
7
+ });
8
+
9
+ const chatRequestSchema = z.object({
10
+ messages: z.array(messageSchema).min(1).max(100),
11
+ });
12
+
13
+ export async function POST(request: Request) {
14
+ try {
15
+ const body = await request.json();
16
+ const { messages } = chatRequestSchema.parse(body);
17
+
18
+ const agent = getAgent("assistant");
19
+ if (!agent) {
20
+ return Response.json({ error: "Agent not found" }, { status: 404 });
21
+ }
22
+
23
+ const result = await agent.stream({ messages });
24
+ return result.toDataStreamResponse();
25
+ } catch (error) {
26
+ if (error instanceof z.ZodError) {
27
+ return Response.json(
28
+ { error: "Invalid request", details: error.errors },
29
+ { status: 400 }
30
+ );
31
+ }
32
+ return Response.json(
33
+ { error: "Internal server error" },
34
+ { status: 500 }
35
+ );
36
+ }
37
+ }
@@ -0,0 +1,18 @@
1
+ export default function RootLayout({
2
+ children,
3
+ }: {
4
+ children: React.ReactNode;
5
+ }) {
6
+ return (
7
+ <html lang="en" className="h-full">
8
+ <head>
9
+ <title>Veryfront AI Starter</title>
10
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
11
+ <script src="https://cdn.tailwindcss.com"></script>
12
+ </head>
13
+ <body className="h-full bg-slate-50 dark:bg-slate-900">
14
+ {children}
15
+ </body>
16
+ </html>
17
+ );
18
+ }
@@ -0,0 +1,28 @@
1
+ 'use client'
2
+
3
+ import { Chat } from 'veryfront/ai/components'
4
+ import { useChat } from 'veryfront/ai/react'
5
+
6
+ export default function ChatPage() {
7
+ const chat = useChat({ api: '/api/chat' })
8
+
9
+ return (
10
+ <div className="flex flex-col h-screen bg-slate-50 dark:bg-slate-900">
11
+ <header className="flex-shrink-0 border-b border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-900">
12
+ <div className="max-w-4xl mx-auto px-4 py-3 flex items-center gap-3">
13
+ <div className="w-10 h-10 rounded-xl bg-gradient-to-br from-violet-500 to-purple-600 flex items-center justify-center shadow-lg">
14
+ <svg className="w-5 h-5 text-white" viewBox="0 0 24 24" fill="currentColor">
15
+ <path d="M9.813 15.904L9 18.75l-.813-2.846a4.5 4.5 0 00-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 003.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 003.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 00-3.09 3.09zM18.259 8.715L18 9.75l-.259-1.035a3.375 3.375 0 00-2.455-2.456L14.25 6l1.036-.259a3.375 3.375 0 002.455-2.456L18 2.25l.259 1.035a3.375 3.375 0 002.456 2.456L21.75 6l-1.035.259a3.375 3.375 0 00-2.456 2.456z" />
16
+ </svg>
17
+ </div>
18
+ <div>
19
+ <h1 className="font-semibold text-slate-800 dark:text-white">Veryfront AI</h1>
20
+ <p className="text-xs text-slate-500 dark:text-slate-400">Powered by Agents & Tools</p>
21
+ </div>
22
+ </div>
23
+ </header>
24
+
25
+ <Chat {...chat} className="flex-1" placeholder="Ask me anything..." />
26
+ </div>
27
+ )
28
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "jsx": "react-jsx",
7
+ "strict": true,
8
+ "esModuleInterop": true,
9
+ "skipLibCheck": true,
10
+ "forceConsistentCasingInFileNames": true,
11
+ "resolveJsonModule": true,
12
+ "isolatedModules": true,
13
+ "noEmit": true,
14
+ "lib": ["DOM", "DOM.Iterable", "ES2020"]
15
+ },
16
+ "include": ["**/*.ts", "**/*.tsx"],
17
+ "exclude": ["node_modules"]
18
+ }
@@ -0,0 +1,9 @@
1
+ import type { VeryfrontConfig } from "veryfront";
2
+
3
+ const config: VeryfrontConfig = {
4
+ client: {
5
+ moduleResolution: "self-hosted",
6
+ },
7
+ };
8
+
9
+ export default config;
@@ -0,0 +1,16 @@
1
+ # Environment variables
2
+ DATABASE_URL=postgresql://user:password@localhost:5432/myapp
3
+ REDIS_URL=redis://localhost:6379
4
+ JWT_SECRET=your-secret-key-here
5
+
6
+ # OAuth providers
7
+ GITHUB_CLIENT_ID=
8
+ GITHUB_CLIENT_SECRET=
9
+ GOOGLE_CLIENT_ID=
10
+ GOOGLE_CLIENT_SECRET=
11
+
12
+ # Email service
13
+ SMTP_HOST=smtp.example.com
14
+ SMTP_PORT=587
15
+ SMTP_USER=
16
+ SMTP_PASS=
@@ -0,0 +1,53 @@
1
+ import { z } from "zod";
2
+ import { getEnv } from "veryfront/platform";
3
+ import { createSession } from "../../../../lib/auth.ts";
4
+ import { validatePassword } from "../../../../lib/users.ts";
5
+
6
+ const loginSchema = z.object({
7
+ email: z.string().email(),
8
+ password: z.string().min(8),
9
+ });
10
+
11
+ export async function POST(request: Request) {
12
+ try {
13
+ const body = await request.json();
14
+ const { email, password } = loginSchema.parse(body);
15
+
16
+ // Validate credentials (replace with real DB lookup)
17
+ const user = await validatePassword(email, password);
18
+ if (!user) {
19
+ return Response.json(
20
+ { error: "Invalid credentials" },
21
+ { status: 401 }
22
+ );
23
+ }
24
+
25
+ // Create session
26
+ const session = await createSession(user);
27
+
28
+ // In production, ensure Secure flag is set for HTTPS-only transmission
29
+ const isProduction = getEnv("NODE_ENV") === "production";
30
+ const secureFlag = isProduction ? "; Secure" : "";
31
+
32
+ return Response.json(
33
+ { user, token: session.token },
34
+ {
35
+ headers: {
36
+ "Set-Cookie": `session=${session.token}; Path=/; HttpOnly; SameSite=Strict${secureFlag}`,
37
+ },
38
+ }
39
+ );
40
+ } catch (error) {
41
+ if (error instanceof z.ZodError) {
42
+ return Response.json(
43
+ { error: "Invalid input", details: error.errors },
44
+ { status: 400 }
45
+ );
46
+ }
47
+
48
+ return Response.json(
49
+ { error: "Internal server error" },
50
+ { status: 500 }
51
+ );
52
+ }
53
+ }
@@ -0,0 +1,27 @@
1
+ import { deleteSession } from "../../../../lib/auth.ts";
2
+
3
+ export async function POST(request: Request) {
4
+ try {
5
+ const cookieHeader = request.headers.get("cookie");
6
+ const sessionToken = cookieHeader
7
+ ?.split(";")
8
+ .find((c) => c.trim().startsWith("session="))
9
+ ?.split("=")[1];
10
+
11
+ if (sessionToken) {
12
+ await deleteSession(sessionToken);
13
+ }
14
+
15
+ return Response.json(
16
+ { success: true },
17
+ {
18
+ headers: {
19
+ "Set-Cookie":
20
+ "session=; Path=/; HttpOnly; SameSite=Strict; Max-Age=0",
21
+ },
22
+ }
23
+ );
24
+ } catch {
25
+ return Response.json({ error: "Internal server error" }, { status: 500 });
26
+ }
27
+ }
@@ -0,0 +1,34 @@
1
+ import { verifySession, getSession } from "../../../../lib/auth.ts";
2
+ import { getUser } from "../../../../lib/users.ts";
3
+
4
+ export async function GET(request: Request) {
5
+ try {
6
+ const cookieHeader = request.headers.get("cookie");
7
+ if (!cookieHeader) {
8
+ return Response.json({ error: "Not authenticated" }, { status: 401 });
9
+ }
10
+
11
+ const sessionToken = cookieHeader
12
+ .split(";")
13
+ .find((c) => c.trim().startsWith("session="))
14
+ ?.split("=")[1];
15
+
16
+ if (!sessionToken) {
17
+ return Response.json({ error: "Not authenticated" }, { status: 401 });
18
+ }
19
+
20
+ const session = await verifySession(sessionToken);
21
+ if (!session) {
22
+ return Response.json({ error: "Invalid session" }, { status: 401 });
23
+ }
24
+
25
+ const user = await getUser(session.userId);
26
+ if (!user) {
27
+ return Response.json({ error: "User not found" }, { status: 404 });
28
+ }
29
+
30
+ return Response.json({ user });
31
+ } catch {
32
+ return Response.json({ error: "Internal server error" }, { status: 500 });
33
+ }
34
+ }
@@ -0,0 +1,42 @@
1
+ import { z } from "zod";
2
+ import { createUser } from "../../../../lib/users.ts";
3
+ import { createSession } from "../../../../lib/auth.ts";
4
+ import { getEnv } from "veryfront/platform";
5
+
6
+ const registerSchema = z.object({
7
+ email: z.string().email(),
8
+ name: z.string().min(2).max(100),
9
+ password: z.string().min(8).max(100),
10
+ });
11
+
12
+ export async function POST(request: Request) {
13
+ try {
14
+ const body = await request.json();
15
+ const { email, name, password } = registerSchema.parse(body);
16
+
17
+ const user = await createUser({ email, name, password });
18
+ const session = await createSession(user as any);
19
+
20
+ const isProduction = getEnv("NODE_ENV") === "production";
21
+ const secureFlag = isProduction ? "; Secure" : "";
22
+
23
+ return Response.json(
24
+ { user, token: session.token },
25
+ {
26
+ status: 201,
27
+ headers: {
28
+ "Set-Cookie": `session=${session.token}; Path=/; HttpOnly; SameSite=Strict${secureFlag}`,
29
+ },
30
+ }
31
+ );
32
+ } catch (error) {
33
+ if (error instanceof z.ZodError) {
34
+ return Response.json(
35
+ { error: "Invalid input", details: error.errors },
36
+ { status: 400 }
37
+ );
38
+ }
39
+
40
+ return Response.json({ error: "Internal server error" }, { status: 500 });
41
+ }
42
+ }
@@ -0,0 +1,21 @@
1
+ import { requireAuth } from "../../../middleware/auth.ts";
2
+ import { getStats } from "../../../lib/stats.ts";
3
+
4
+ export async function GET(request: Request) {
5
+ const auth = await requireAuth(request);
6
+ if (!auth.ok) return auth.response;
7
+
8
+ const url = new URL(request.url);
9
+ const userId = url.searchParams.get("userId");
10
+
11
+ if (!userId) {
12
+ return Response.json(
13
+ { error: "userId parameter required" },
14
+ { status: 400 }
15
+ );
16
+ }
17
+
18
+ const stats = await getStats(userId);
19
+
20
+ return Response.json({ stats });
21
+ }
@@ -0,0 +1,42 @@
1
+ import { z } from "zod";
2
+ import { requireAuth } from "../../../middleware/auth.ts";
3
+ import { getUsers, createUser } from "../../../lib/users.ts";
4
+
5
+ const userSchema = z.object({
6
+ name: z.string().min(1),
7
+ email: z.string().email(),
8
+ role: z.enum(["user", "admin"]).default("user"),
9
+ });
10
+
11
+ export async function GET(request: Request) {
12
+ const auth = await requireAuth(request);
13
+ if (!auth.ok) return auth.response;
14
+
15
+ const users = await getUsers();
16
+ return Response.json({ users });
17
+ }
18
+
19
+ export async function POST(request: Request) {
20
+ const auth = await requireAuth(request);
21
+ if (!auth.ok) return auth.response;
22
+
23
+ try {
24
+ const body = await request.json();
25
+ const data = userSchema.parse(body);
26
+
27
+ const user = await createUser(data);
28
+ return Response.json({ user }, { status: 201 });
29
+ } catch (error) {
30
+ if (error instanceof z.ZodError) {
31
+ return Response.json(
32
+ { error: "Invalid input", details: error.errors },
33
+ { status: 400 }
34
+ );
35
+ }
36
+
37
+ return Response.json(
38
+ { error: "Internal server error" },
39
+ { status: 500 }
40
+ );
41
+ }
42
+ }
@@ -0,0 +1,29 @@
1
+ import { redirect } from "veryfront";
2
+ import { getSession } from "../../lib/auth.ts";
3
+ import { DashboardLayout } from "../../components/DashboardLayout.tsx";
4
+ import { StatsGrid } from "../../components/StatsGrid.tsx";
5
+ import { RecentActivity } from "../../components/RecentActivity.tsx";
6
+
7
+ export default async function DashboardPage() {
8
+ const session = await getSession();
9
+
10
+ if (!session) {
11
+ redirect("/login");
12
+ }
13
+
14
+ return (
15
+ <DashboardLayout>
16
+ <div className="space-y-8">
17
+ <div className="bg-white dark:bg-slate-800 rounded-2xl p-8 shadow-sm border border-slate-200 dark:border-slate-700">
18
+ <h1 className="text-3xl font-bold text-slate-900 dark:text-white">Dashboard</h1>
19
+ <p className="text-slate-600 dark:text-slate-400 mt-2">
20
+ Welcome back, <span className="font-semibold text-indigo-600 dark:text-indigo-400">{session.user.name}</span>! Here's what's happening with your projects.
21
+ </p>
22
+ </div>
23
+
24
+ <StatsGrid userId={session.user.id} />
25
+ <RecentActivity userId={session.user.id} />
26
+ </div>
27
+ </DashboardLayout>
28
+ );
29
+ }
@@ -0,0 +1,45 @@
1
+ import * as React from "react";
2
+ import { AuthProvider } from "../components/AuthProvider.tsx";
3
+ import { Toaster } from "../components/Toaster.tsx";
4
+
5
+ export const metadata = {
6
+ title: "My App",
7
+ description: "A full-stack app built with Veryfront",
8
+ };
9
+
10
+ export default function RootLayout({
11
+ children
12
+ }: {
13
+ children: React.ReactNode
14
+ }) {
15
+ return (
16
+ <html lang="en">
17
+ <head>
18
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
19
+ <link
20
+ rel="stylesheet"
21
+ href="https://cdn.jsdelivr.net/npm/tailwindcss@3/dist/tailwind.min.css"
22
+ />
23
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
24
+ <style>{`
25
+ body { font-family: 'Inter', sans-serif; }
26
+ .animate-blob { animation: blob 7s infinite; }
27
+ .animation-delay-2000 { animation-delay: 2s; }
28
+ .animation-delay-4000 { animation-delay: 4s; }
29
+ @keyframes blob {
30
+ 0% { transform: translate(0px, 0px) scale(1); }
31
+ 33% { transform: translate(30px, -50px) scale(1.1); }
32
+ 66% { transform: translate(-20px, 20px) scale(0.9); }
33
+ 100% { transform: translate(0px, 0px) scale(1); }
34
+ }
35
+ `}</style>
36
+ </head>
37
+ <body className="bg-slate-50 text-slate-900 antialiased">
38
+ <AuthProvider>
39
+ {children}
40
+ <Toaster />
41
+ </AuthProvider>
42
+ </body>
43
+ </html>
44
+ );
45
+ }