create-veap 0.1.3 → 0.3.0
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.
- package/bin/veap.js +1 -0
- package/dist/commands/init.js +4 -5
- package/dist/package-manager.js +3 -5
- package/dist/scaffold.d.ts +5 -3
- package/dist/scaffold.js +45 -5
- package/package.json +1 -1
- package/stubs/docker/.dockerignore.stub +39 -39
- package/stubs/docker/Dockerfile.stub +49 -49
- package/stubs/docker/compose.yml.stub +58 -58
- package/stubs/overlay-full/AGENTS.md.stub +1 -1
- package/stubs/overlay-full/app/(site)/layout.tsx.stub +10 -0
- package/stubs/overlay-full/app/[[...catchAll]]/page.tsx.stub +47 -47
- package/stubs/overlay-full/app/api/[...catchAll]/route.ts.stub +111 -111
- package/stubs/overlay-full/app/error.tsx.stub +34 -34
- package/stubs/overlay-full/app/globals.css.stub +123 -123
- package/stubs/overlay-full/app/layout.tsx.stub +71 -71
- package/stubs/overlay-full/app/storage/[...path]/route.ts.stub +61 -61
- package/stubs/overlay-full/components/footer.tsx.stub +25 -0
- package/stubs/overlay-full/components/navbar.tsx.stub +61 -0
- package/stubs/overlay-full/components/site-layout.tsx.stub +22 -0
- package/stubs/overlay-full/lib/plugins.gen.ts.stub +6 -6
- package/stubs/overlay-full/lib/veap.ts.stub +27 -26
- package/stubs/overlay-full/next.config.ts.stub +34 -34
- package/stubs/overlay-full/proxy.ts.stub +27 -27
|
@@ -1,71 +1,71 @@
|
|
|
1
|
-
import type { Metadata } from "next";
|
|
2
|
-
import { Geist, Geist_Mono } from "next/font/google";
|
|
3
|
-
import "./globals.css";
|
|
4
|
-
import { I18nProvider } from "@veap/framework/intl/server";
|
|
5
|
-
import { ExtensionPoint, getPathPrefix } from "@veap/framework/plugins/server";
|
|
6
|
-
import { AppProvider } from "@veap/framework/react";
|
|
7
|
-
import { cookies } from "next/headers";
|
|
8
|
-
import { initializeSystem } from "@/lib/veap";
|
|
9
|
-
import {
|
|
10
|
-
getCurrentSession,
|
|
11
|
-
isSystemInstalled,
|
|
12
|
-
} from "@veap/framework/auth/server";
|
|
13
|
-
|
|
14
|
-
const geistSans = Geist({
|
|
15
|
-
variable: "--font-geist-sans",
|
|
16
|
-
subsets: ["latin"],
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
const geistMono = Geist_Mono({
|
|
20
|
-
variable: "--font-geist-mono",
|
|
21
|
-
subsets: ["latin"],
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
export const metadata: Metadata = {
|
|
25
|
-
title: "Veap App",
|
|
26
|
-
description: "Built with Veap framework",
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
// The whole layout is request-time work: it boots Veap (providers + plugin
|
|
30
|
-
// context), reads cookies and renders plugin extension points. Without this,
|
|
31
|
-
// Next.js prerenders /_not-found during `next build` while
|
|
32
|
-
// NEXT_PHASE=phase-production-build - in which `Application.bootstrap()`
|
|
33
|
-
// intentionally skips provider boot - and context-bound helpers (e.g.
|
|
34
|
-
// getPathPrefix()) throw "Context is not bound".
|
|
35
|
-
export const dynamic = "force-dynamic";
|
|
36
|
-
|
|
37
|
-
export default async function RootLayout({
|
|
38
|
-
children,
|
|
39
|
-
}: Readonly<{
|
|
40
|
-
children: React.ReactNode;
|
|
41
|
-
}>) {
|
|
42
|
-
await initializeSystem();
|
|
43
|
-
const installed = await isSystemInstalled();
|
|
44
|
-
|
|
45
|
-
const session = installed
|
|
46
|
-
? await getCurrentSession()
|
|
47
|
-
: { session: null, user: null };
|
|
48
|
-
|
|
49
|
-
const pathPrefix = await getPathPrefix();
|
|
50
|
-
|
|
51
|
-
const cookieStore = await cookies();
|
|
52
|
-
const locale = cookieStore.get("VEAP_LOCALE")?.value || "en";
|
|
53
|
-
|
|
54
|
-
return (
|
|
55
|
-
<html lang={locale} suppressHydrationWarning>
|
|
56
|
-
<body
|
|
57
|
-
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
|
58
|
-
>
|
|
59
|
-
<I18nProvider>
|
|
60
|
-
<AppProvider initialSession={session} prefix={pathPrefix}>
|
|
61
|
-
<div className="min-h-screen relative bg-background">
|
|
62
|
-
<ExtensionPoint target="app" point="before-content" />
|
|
63
|
-
{children}
|
|
64
|
-
<ExtensionPoint target="app" point="after-content" />
|
|
65
|
-
</div>
|
|
66
|
-
</AppProvider>
|
|
67
|
-
</I18nProvider>
|
|
68
|
-
</body>
|
|
69
|
-
</html>
|
|
70
|
-
);
|
|
71
|
-
}
|
|
1
|
+
import type { Metadata } from "next";
|
|
2
|
+
import { Geist, Geist_Mono } from "next/font/google";
|
|
3
|
+
import "./globals.css";
|
|
4
|
+
import { I18nProvider } from "@veap/framework/intl/server";
|
|
5
|
+
import { ExtensionPoint, getPathPrefix } from "@veap/framework/plugins/server";
|
|
6
|
+
import { AppProvider } from "@veap/framework/react";
|
|
7
|
+
import { cookies } from "next/headers";
|
|
8
|
+
import { initializeSystem } from "@/lib/veap";
|
|
9
|
+
import {
|
|
10
|
+
getCurrentSession,
|
|
11
|
+
isSystemInstalled,
|
|
12
|
+
} from "@veap/framework/auth/server";
|
|
13
|
+
|
|
14
|
+
const geistSans = Geist({
|
|
15
|
+
variable: "--font-geist-sans",
|
|
16
|
+
subsets: ["latin"],
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const geistMono = Geist_Mono({
|
|
20
|
+
variable: "--font-geist-mono",
|
|
21
|
+
subsets: ["latin"],
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
export const metadata: Metadata = {
|
|
25
|
+
title: "Veap App",
|
|
26
|
+
description: "Built with Veap framework",
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// The whole layout is request-time work: it boots Veap (providers + plugin
|
|
30
|
+
// context), reads cookies and renders plugin extension points. Without this,
|
|
31
|
+
// Next.js prerenders /_not-found during `next build` while
|
|
32
|
+
// NEXT_PHASE=phase-production-build - in which `Application.bootstrap()`
|
|
33
|
+
// intentionally skips provider boot - and context-bound helpers (e.g.
|
|
34
|
+
// getPathPrefix()) throw "Context is not bound".
|
|
35
|
+
export const dynamic = "force-dynamic";
|
|
36
|
+
|
|
37
|
+
export default async function RootLayout({
|
|
38
|
+
children,
|
|
39
|
+
}: Readonly<{
|
|
40
|
+
children: React.ReactNode;
|
|
41
|
+
}>) {
|
|
42
|
+
await initializeSystem();
|
|
43
|
+
const installed = await isSystemInstalled();
|
|
44
|
+
|
|
45
|
+
const session = installed
|
|
46
|
+
? await getCurrentSession()
|
|
47
|
+
: { session: null, user: null };
|
|
48
|
+
|
|
49
|
+
const pathPrefix = await getPathPrefix();
|
|
50
|
+
|
|
51
|
+
const cookieStore = await cookies();
|
|
52
|
+
const locale = cookieStore.get("VEAP_LOCALE")?.value || "en";
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<html lang={locale} suppressHydrationWarning>
|
|
56
|
+
<body
|
|
57
|
+
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
|
58
|
+
>
|
|
59
|
+
<I18nProvider>
|
|
60
|
+
<AppProvider initialSession={session} prefix={pathPrefix}>
|
|
61
|
+
<div className="min-h-screen relative bg-background">
|
|
62
|
+
<ExtensionPoint target="app" point="before-content" />
|
|
63
|
+
{children}
|
|
64
|
+
<ExtensionPoint target="app" point="after-content" />
|
|
65
|
+
</div>
|
|
66
|
+
</AppProvider>
|
|
67
|
+
</I18nProvider>
|
|
68
|
+
</body>
|
|
69
|
+
</html>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { type NextRequest, NextResponse } from "next/server";
|
|
4
|
-
|
|
5
|
-
export const dynamic = "force-dynamic";
|
|
6
|
-
|
|
7
|
-
export async function GET(
|
|
8
|
-
request: NextRequest,
|
|
9
|
-
context: { params: Promise<{ path: string[] }> },
|
|
10
|
-
) {
|
|
11
|
-
const resolvedParams = await context.params;
|
|
12
|
-
const filePath = path.join(
|
|
13
|
-
/*turbopackIgnore: true*/ process.cwd(),
|
|
14
|
-
"public",
|
|
15
|
-
"storage",
|
|
16
|
-
...resolvedParams.path,
|
|
17
|
-
);
|
|
18
|
-
|
|
19
|
-
// Prevent Directory Traversal Attacks!
|
|
20
|
-
const safePath = path.normalize(filePath);
|
|
21
|
-
const baseStoragePath = path.join(
|
|
22
|
-
/*turbopackIgnore: true*/ process.cwd(),
|
|
23
|
-
"public",
|
|
24
|
-
"storage",
|
|
25
|
-
);
|
|
26
|
-
if (!safePath.startsWith(baseStoragePath)) {
|
|
27
|
-
return new NextResponse("Forbidden", { status: 403 });
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
if (
|
|
31
|
-
!fs.existsSync(/*turbopackIgnore: true*/ safePath) ||
|
|
32
|
-
fs.statSync(/*turbopackIgnore: true*/ safePath).isDirectory()
|
|
33
|
-
) {
|
|
34
|
-
return new NextResponse("Not Found", { status: 404 });
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const fileBuffer = fs.readFileSync(/*turbopackIgnore: true*/ safePath);
|
|
38
|
-
|
|
39
|
-
// Determine Content-Type
|
|
40
|
-
const ext = path.extname(safePath).toLowerCase();
|
|
41
|
-
let contentType = "application/octet-stream";
|
|
42
|
-
if (ext === ".png") contentType = "image/png";
|
|
43
|
-
else if (ext === ".jpg" || ext === ".jpeg") contentType = "image/jpeg";
|
|
44
|
-
else if (ext === ".gif") contentType = "image/gif";
|
|
45
|
-
else if (ext === ".svg") contentType = "image/svg+xml";
|
|
46
|
-
else if (ext === ".webp") contentType = "image/webp";
|
|
47
|
-
else if (ext === ".md" || ext === ".mdx")
|
|
48
|
-
contentType = "text/markdown; charset=utf-8";
|
|
49
|
-
else if (ext === ".json") contentType = "application/json";
|
|
50
|
-
else if (ext === ".txt") contentType = "text/plain; charset=utf-8";
|
|
51
|
-
else if (ext === ".pdf") contentType = "application/pdf";
|
|
52
|
-
else if (ext === ".css") contentType = "text/css";
|
|
53
|
-
else if (ext === ".js") contentType = "application/javascript";
|
|
54
|
-
|
|
55
|
-
return new NextResponse(fileBuffer, {
|
|
56
|
-
headers: {
|
|
57
|
-
"Content-Type": contentType,
|
|
58
|
-
"Cache-Control": "public, max-age=31536000, immutable",
|
|
59
|
-
},
|
|
60
|
-
});
|
|
61
|
-
}
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { type NextRequest, NextResponse } from "next/server";
|
|
4
|
+
|
|
5
|
+
export const dynamic = "force-dynamic";
|
|
6
|
+
|
|
7
|
+
export async function GET(
|
|
8
|
+
request: NextRequest,
|
|
9
|
+
context: { params: Promise<{ path: string[] }> },
|
|
10
|
+
) {
|
|
11
|
+
const resolvedParams = await context.params;
|
|
12
|
+
const filePath = path.join(
|
|
13
|
+
/*turbopackIgnore: true*/ process.cwd(),
|
|
14
|
+
"public",
|
|
15
|
+
"storage",
|
|
16
|
+
...resolvedParams.path,
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
// Prevent Directory Traversal Attacks!
|
|
20
|
+
const safePath = path.normalize(filePath);
|
|
21
|
+
const baseStoragePath = path.join(
|
|
22
|
+
/*turbopackIgnore: true*/ process.cwd(),
|
|
23
|
+
"public",
|
|
24
|
+
"storage",
|
|
25
|
+
);
|
|
26
|
+
if (!safePath.startsWith(baseStoragePath)) {
|
|
27
|
+
return new NextResponse("Forbidden", { status: 403 });
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (
|
|
31
|
+
!fs.existsSync(/*turbopackIgnore: true*/ safePath) ||
|
|
32
|
+
fs.statSync(/*turbopackIgnore: true*/ safePath).isDirectory()
|
|
33
|
+
) {
|
|
34
|
+
return new NextResponse("Not Found", { status: 404 });
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const fileBuffer = fs.readFileSync(/*turbopackIgnore: true*/ safePath);
|
|
38
|
+
|
|
39
|
+
// Determine Content-Type
|
|
40
|
+
const ext = path.extname(safePath).toLowerCase();
|
|
41
|
+
let contentType = "application/octet-stream";
|
|
42
|
+
if (ext === ".png") contentType = "image/png";
|
|
43
|
+
else if (ext === ".jpg" || ext === ".jpeg") contentType = "image/jpeg";
|
|
44
|
+
else if (ext === ".gif") contentType = "image/gif";
|
|
45
|
+
else if (ext === ".svg") contentType = "image/svg+xml";
|
|
46
|
+
else if (ext === ".webp") contentType = "image/webp";
|
|
47
|
+
else if (ext === ".md" || ext === ".mdx")
|
|
48
|
+
contentType = "text/markdown; charset=utf-8";
|
|
49
|
+
else if (ext === ".json") contentType = "application/json";
|
|
50
|
+
else if (ext === ".txt") contentType = "text/plain; charset=utf-8";
|
|
51
|
+
else if (ext === ".pdf") contentType = "application/pdf";
|
|
52
|
+
else if (ext === ".css") contentType = "text/css";
|
|
53
|
+
else if (ext === ".js") contentType = "application/javascript";
|
|
54
|
+
|
|
55
|
+
return new NextResponse(fileBuffer, {
|
|
56
|
+
headers: {
|
|
57
|
+
"Content-Type": contentType,
|
|
58
|
+
"Cache-Control": "public, max-age=31536000, immutable",
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import Link from "next/link";
|
|
2
|
+
|
|
3
|
+
export function Footer() {
|
|
4
|
+
return (
|
|
5
|
+
<footer className="w-full border-t bg-muted/40 py-10 mt-16 text-sm text-muted-foreground">
|
|
6
|
+
<div className="mx-auto flex max-w-6xl flex-col items-center justify-between gap-4 px-4 sm:flex-row sm:px-6">
|
|
7
|
+
<div className="flex flex-col items-center gap-1 sm:items-start">
|
|
8
|
+
<p className="font-semibold text-foreground">Veap Application</p>
|
|
9
|
+
<p className="text-xs">
|
|
10
|
+
Powered by Next.js 16 App Router & @veap/framework modular architecture.
|
|
11
|
+
</p>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
<div className="flex items-center gap-6 text-xs">
|
|
15
|
+
<Link href="/" className="hover:underline">
|
|
16
|
+
Home
|
|
17
|
+
</Link>
|
|
18
|
+
<Link href="/app" className="hover:underline">
|
|
19
|
+
Panel
|
|
20
|
+
</Link>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
</footer>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import Link from "next/link";
|
|
2
|
+
import { getCurrentSession } from "@veap/framework/auth/server";
|
|
3
|
+
|
|
4
|
+
export async function Navbar() {
|
|
5
|
+
const { session, user } = await getCurrentSession();
|
|
6
|
+
|
|
7
|
+
return (
|
|
8
|
+
<header className="sticky top-0 z-40 w-full border-b bg-background/80 backdrop-blur-md">
|
|
9
|
+
<div className="mx-auto flex h-16 max-w-6xl items-center justify-between px-4 sm:px-6">
|
|
10
|
+
<div className="flex items-center gap-6">
|
|
11
|
+
<Link href="/" className="flex items-center gap-2 font-bold text-xl tracking-tight">
|
|
12
|
+
<span className="flex h-8 w-8 items-center justify-center rounded-lg bg-primary text-primary-foreground font-mono text-sm font-bold shadow-xs">
|
|
13
|
+
V
|
|
14
|
+
</span>
|
|
15
|
+
<span>Veap</span>
|
|
16
|
+
</Link>
|
|
17
|
+
|
|
18
|
+
<nav className="hidden md:flex items-center gap-6 text-sm font-medium text-muted-foreground">
|
|
19
|
+
<Link href="/" className="transition hover:text-foreground">
|
|
20
|
+
Home
|
|
21
|
+
</Link>
|
|
22
|
+
<Link href="/app" className="transition hover:text-foreground">
|
|
23
|
+
Panel
|
|
24
|
+
</Link>
|
|
25
|
+
</nav>
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
<div className="flex items-center gap-3">
|
|
29
|
+
{session && user ? (
|
|
30
|
+
<div className="flex items-center gap-3">
|
|
31
|
+
<span className="hidden sm:inline-block text-xs text-muted-foreground font-medium">
|
|
32
|
+
{user.email}
|
|
33
|
+
</span>
|
|
34
|
+
<Link
|
|
35
|
+
href="/app"
|
|
36
|
+
className="inline-flex h-9 items-center justify-center rounded-md bg-secondary px-3 text-xs font-medium text-secondary-foreground shadow-xs transition hover:bg-secondary/80"
|
|
37
|
+
>
|
|
38
|
+
Panel
|
|
39
|
+
</Link>
|
|
40
|
+
</div>
|
|
41
|
+
) : (
|
|
42
|
+
<div className="flex items-center gap-2">
|
|
43
|
+
<Link
|
|
44
|
+
href="/signin"
|
|
45
|
+
className="inline-flex h-9 items-center justify-center rounded-md border border-input bg-background px-3 text-xs font-medium shadow-xs transition hover:bg-accent hover:text-accent-foreground"
|
|
46
|
+
>
|
|
47
|
+
Sign In
|
|
48
|
+
</Link>
|
|
49
|
+
<Link
|
|
50
|
+
href="/signup"
|
|
51
|
+
className="inline-flex h-9 items-center justify-center rounded-md bg-primary px-3 text-xs font-medium text-primary-foreground shadow-xs transition hover:bg-primary/90"
|
|
52
|
+
>
|
|
53
|
+
Get Started
|
|
54
|
+
</Link>
|
|
55
|
+
</div>
|
|
56
|
+
)}
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
</header>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ExtensionPoint } from "@veap/framework/plugins/server";
|
|
2
|
+
import { Navbar } from "@/components/navbar";
|
|
3
|
+
import { Footer } from "@/components/footer";
|
|
4
|
+
import type { ReactNode } from "react";
|
|
5
|
+
|
|
6
|
+
export function SiteLayout({ children }: { children: ReactNode }) {
|
|
7
|
+
return (
|
|
8
|
+
<div className="bg-background relative min-h-screen flex flex-col justify-between">
|
|
9
|
+
{/* App Shell Slot for Navbar: single mode resolves plugin with highest priority, fallback to host Navbar */}
|
|
10
|
+
<ExtensionPoint target="app" point="navbar" mode="single">
|
|
11
|
+
<Navbar />
|
|
12
|
+
</ExtensionPoint>
|
|
13
|
+
|
|
14
|
+
<main className="flex-1 w-full">{children}</main>
|
|
15
|
+
|
|
16
|
+
{/* App Shell Slot for Footer */}
|
|
17
|
+
<ExtensionPoint target="app" point="footer" mode="single">
|
|
18
|
+
<Footer />
|
|
19
|
+
</ExtensionPoint>
|
|
20
|
+
</div>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* FILE AUTOMATICALLY GENERATED BY veap/cli
|
|
3
|
-
* DO NOT EDIT THIS FILE MANUALLY!
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export const plugins = [];
|
|
1
|
+
/**
|
|
2
|
+
* FILE AUTOMATICALLY GENERATED BY veap/cli
|
|
3
|
+
* DO NOT EDIT THIS FILE MANUALLY!
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export const plugins = [];
|
|
@@ -1,26 +1,27 @@
|
|
|
1
|
-
import { cache } from "react";
|
|
2
|
-
import { Application } from "@veap/framework/core/server";
|
|
3
|
-
|
|
4
|
-
import { appMigrations } from "../migrations";
|
|
5
|
-
import { plugins } from "./plugins.gen";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
.
|
|
10
|
-
.
|
|
11
|
-
.
|
|
12
|
-
.
|
|
13
|
-
.
|
|
14
|
-
.
|
|
15
|
-
.
|
|
16
|
-
.
|
|
17
|
-
.
|
|
18
|
-
.
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
*
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
1
|
+
import { cache } from "react";
|
|
2
|
+
import { Application } from "@veap/framework/core/server";
|
|
3
|
+
|
|
4
|
+
import { appMigrations } from "../migrations";
|
|
5
|
+
import { plugins } from "./plugins.gen";
|
|
6
|
+
import { SiteLayout } from "../components/site-layout";
|
|
7
|
+
|
|
8
|
+
export const app = Application.configure()
|
|
9
|
+
.withDatabase()
|
|
10
|
+
.withAuth()
|
|
11
|
+
.withStorage()
|
|
12
|
+
.withCommunication()
|
|
13
|
+
.withIntl()
|
|
14
|
+
.withRouter()
|
|
15
|
+
.withSiteLayout(SiteLayout)
|
|
16
|
+
.withSettings()
|
|
17
|
+
.withMigrations(appMigrations)
|
|
18
|
+
.withPlugins(plugins)
|
|
19
|
+
.create();
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Main system bootstrap function.
|
|
23
|
+
* Called automatically in root layout/pages.
|
|
24
|
+
*/
|
|
25
|
+
export const initializeSystem = cache(async () => {
|
|
26
|
+
return app.bootstrap();
|
|
27
|
+
});
|
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
import type { NextConfig } from "next";
|
|
2
|
-
|
|
3
|
-
const nextConfig: NextConfig = {
|
|
4
|
-
serverExternalPackages: ["knex", "pg", "better-sqlite3"],
|
|
5
|
-
// Output for standalone build in docker (disabled on Vercel to avoid build crash)
|
|
6
|
-
output: process.env.VERCEL ? undefined : "standalone",
|
|
7
|
-
|
|
8
|
-
transpilePackages: ["@veap/framework", "@veap/ui"],
|
|
9
|
-
|
|
10
|
-
reactCompiler: true,
|
|
11
|
-
|
|
12
|
-
experimental: {
|
|
13
|
-
turbopackFileSystemCacheForBuild: true,
|
|
14
|
-
turbopackRustReactCompiler: true
|
|
15
|
-
},
|
|
16
|
-
|
|
17
|
-
outputFileTracingIncludes: {
|
|
18
|
-
"/**/*": ["veap.config.ts"],
|
|
19
|
-
},
|
|
20
|
-
|
|
21
|
-
typescript: {
|
|
22
|
-
// !! WARN !!
|
|
23
|
-
// Dangerously allow production builds to successfully complete even if
|
|
24
|
-
// your project has type errors.
|
|
25
|
-
// !! WARN !!
|
|
26
|
-
ignoreBuildErrors: true,
|
|
27
|
-
},
|
|
28
|
-
|
|
29
|
-
images: {
|
|
30
|
-
unoptimized: true,
|
|
31
|
-
},
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export default nextConfig;
|
|
1
|
+
import type { NextConfig } from "next";
|
|
2
|
+
|
|
3
|
+
const nextConfig: NextConfig = {
|
|
4
|
+
serverExternalPackages: ["knex", "pg", "better-sqlite3"],
|
|
5
|
+
// Output for standalone build in docker (disabled on Vercel to avoid build crash)
|
|
6
|
+
output: process.env.VERCEL ? undefined : "standalone",
|
|
7
|
+
|
|
8
|
+
transpilePackages: ["@veap/framework", "@veap/ui"],
|
|
9
|
+
|
|
10
|
+
reactCompiler: true,
|
|
11
|
+
|
|
12
|
+
experimental: {
|
|
13
|
+
turbopackFileSystemCacheForBuild: true,
|
|
14
|
+
turbopackRustReactCompiler: true
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
outputFileTracingIncludes: {
|
|
18
|
+
"/**/*": ["veap.config.ts"],
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
typescript: {
|
|
22
|
+
// !! WARN !!
|
|
23
|
+
// Dangerously allow production builds to successfully complete even if
|
|
24
|
+
// your project has type errors.
|
|
25
|
+
// !! WARN !!
|
|
26
|
+
ignoreBuildErrors: true,
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
images: {
|
|
30
|
+
unoptimized: true,
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export default nextConfig;
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import type { NextRequest } from "next/server";
|
|
2
|
-
import { NextResponse } from "next/server";
|
|
3
|
-
|
|
4
|
-
export function proxy(request: NextRequest) {
|
|
5
|
-
const url = new URL(request.url);
|
|
6
|
-
const requestHeaders = new Headers(request.headers);
|
|
7
|
-
requestHeaders.set("x-pathname", url.pathname);
|
|
8
|
-
|
|
9
|
-
return NextResponse.next({
|
|
10
|
-
request: {
|
|
11
|
-
headers: requestHeaders,
|
|
12
|
-
},
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export const config = {
|
|
17
|
-
matcher: [
|
|
18
|
-
/*
|
|
19
|
-
* Match all request paths except for the ones starting with:
|
|
20
|
-
* - api (API routes)
|
|
21
|
-
* - _next/static (static files)
|
|
22
|
-
* - _next/image (image optimization files)
|
|
23
|
-
* - favicon.ico (favicon file)
|
|
24
|
-
*/
|
|
25
|
-
"/((?!api|_next/static|_next/image|favicon.ico).*)",
|
|
26
|
-
],
|
|
27
|
-
};
|
|
1
|
+
import type { NextRequest } from "next/server";
|
|
2
|
+
import { NextResponse } from "next/server";
|
|
3
|
+
|
|
4
|
+
export function proxy(request: NextRequest) {
|
|
5
|
+
const url = new URL(request.url);
|
|
6
|
+
const requestHeaders = new Headers(request.headers);
|
|
7
|
+
requestHeaders.set("x-pathname", url.pathname);
|
|
8
|
+
|
|
9
|
+
return NextResponse.next({
|
|
10
|
+
request: {
|
|
11
|
+
headers: requestHeaders,
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const config = {
|
|
17
|
+
matcher: [
|
|
18
|
+
/*
|
|
19
|
+
* Match all request paths except for the ones starting with:
|
|
20
|
+
* - api (API routes)
|
|
21
|
+
* - _next/static (static files)
|
|
22
|
+
* - _next/image (image optimization files)
|
|
23
|
+
* - favicon.ico (favicon file)
|
|
24
|
+
*/
|
|
25
|
+
"/((?!api|_next/static|_next/image|favicon.ico).*)",
|
|
26
|
+
],
|
|
27
|
+
};
|