@mandujs/cli 0.9.21 → 0.9.23

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 (40) hide show
  1. package/README.ko.md +57 -4
  2. package/README.md +62 -15
  3. package/package.json +2 -2
  4. package/src/commands/check.ts +41 -5
  5. package/src/commands/contract.ts +135 -9
  6. package/src/commands/dev.ts +155 -95
  7. package/src/commands/guard-arch.ts +39 -9
  8. package/src/commands/guard-check.ts +3 -3
  9. package/src/commands/init.ts +264 -9
  10. package/src/commands/monitor.ts +301 -0
  11. package/src/main.ts +421 -361
  12. package/templates/default/app/globals.css +37 -0
  13. package/templates/default/app/layout.tsx +27 -0
  14. package/templates/default/app/page.tsx +27 -49
  15. package/templates/default/package.json +20 -11
  16. package/templates/default/postcss.config.js +6 -0
  17. package/templates/default/src/client/app/index.ts +1 -0
  18. package/templates/default/src/client/entities/index.ts +1 -0
  19. package/templates/default/src/client/features/index.ts +1 -0
  20. package/templates/default/src/client/pages/index.ts +1 -0
  21. package/templates/default/src/client/shared/index.ts +1 -0
  22. package/templates/default/src/client/shared/lib/utils.ts +16 -0
  23. package/templates/default/src/client/shared/ui/button.tsx +57 -0
  24. package/templates/default/src/client/shared/ui/card.tsx +78 -0
  25. package/templates/default/src/client/shared/ui/index.ts +21 -0
  26. package/templates/default/src/client/shared/ui/input.tsx +24 -0
  27. package/templates/default/src/client/widgets/index.ts +1 -0
  28. package/templates/default/src/server/api/index.ts +1 -0
  29. package/templates/default/src/server/application/index.ts +1 -0
  30. package/templates/default/src/server/core/index.ts +1 -0
  31. package/templates/default/src/server/domain/index.ts +1 -0
  32. package/templates/default/src/server/infra/index.ts +1 -0
  33. package/templates/default/src/shared/contracts/index.ts +1 -0
  34. package/templates/default/src/shared/env/index.ts +1 -0
  35. package/templates/default/src/shared/schema/index.ts +1 -0
  36. package/templates/default/src/shared/types/index.ts +1 -0
  37. package/templates/default/src/shared/utils/client/index.ts +1 -0
  38. package/templates/default/src/shared/utils/server/index.ts +1 -0
  39. package/templates/default/tailwind.config.ts +64 -0
  40. package/templates/default/tsconfig.json +14 -3
@@ -0,0 +1,37 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ @layer base {
6
+ :root {
7
+ --background: 0 0% 100%;
8
+ --foreground: 222.2 84% 4.9%;
9
+ --card: 0 0% 100%;
10
+ --card-foreground: 222.2 84% 4.9%;
11
+ --popover: 0 0% 100%;
12
+ --popover-foreground: 222.2 84% 4.9%;
13
+ --primary: 222.2 47.4% 11.2%;
14
+ --primary-foreground: 210 40% 98%;
15
+ --secondary: 210 40% 96.1%;
16
+ --secondary-foreground: 222.2 47.4% 11.2%;
17
+ --muted: 210 40% 96.1%;
18
+ --muted-foreground: 215.4 16.3% 46.9%;
19
+ --accent: 210 40% 96.1%;
20
+ --accent-foreground: 222.2 47.4% 11.2%;
21
+ --destructive: 0 84.2% 60.2%;
22
+ --destructive-foreground: 210 40% 98%;
23
+ --border: 214.3 31.8% 91.4%;
24
+ --input: 214.3 31.8% 91.4%;
25
+ --ring: 222.2 84% 4.9%;
26
+ --radius: 0.5rem;
27
+ }
28
+ }
29
+
30
+ @layer base {
31
+ * {
32
+ @apply border-border;
33
+ }
34
+ body {
35
+ @apply bg-background text-foreground;
36
+ }
37
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Root Layout
3
+ *
4
+ * 모든 페이지의 공통 레이아웃
5
+ * globals.css를 여기서 임포트
6
+ */
7
+
8
+ import "./globals.css";
9
+
10
+ interface RootLayoutProps {
11
+ children: React.ReactNode;
12
+ }
13
+
14
+ export default function RootLayout({ children }: RootLayoutProps) {
15
+ return (
16
+ <html lang="ko">
17
+ <head>
18
+ <meta charSet="UTF-8" />
19
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
20
+ <title>{{PROJECT_NAME}}</title>
21
+ </head>
22
+ <body className="min-h-screen bg-background font-sans antialiased">
23
+ {children}
24
+ </body>
25
+ </html>
26
+ );
27
+ }
@@ -4,57 +4,35 @@
4
4
  * Edit this file and see changes at http://localhost:3000
5
5
  */
6
6
 
7
+ import { Button } from "@/client/shared/ui/button";
8
+ import { Card, CardHeader, CardTitle, CardDescription, CardContent } from "@/client/shared/ui/card";
9
+
7
10
  export default function HomePage() {
8
11
  return (
9
- <html lang="ko">
10
- <head>
11
- <meta charSet="UTF-8" />
12
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
13
- <title>Mandu App</title>
14
- <style>{`
15
- body {
16
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
17
- display: flex;
18
- justify-content: center;
19
- align-items: center;
20
- min-height: 100vh;
21
- margin: 0;
22
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
23
- color: white;
24
- }
25
- .container {
26
- text-align: center;
27
- padding: 2rem;
28
- }
29
- h1 {
30
- font-size: 3rem;
31
- margin-bottom: 1rem;
32
- }
33
- p {
34
- font-size: 1.2rem;
35
- opacity: 0.9;
36
- }
37
- code {
38
- background: rgba(255,255,255,0.2);
39
- padding: 0.2rem 0.5rem;
40
- border-radius: 4px;
41
- }
42
- a {
43
- color: white;
44
- text-decoration: underline;
45
- }
46
- `}</style>
47
- </head>
48
- <body>
49
- <div className="container">
50
- <h1>🥟 Mandu</h1>
51
- <p>Welcome to your new Mandu project!</p>
52
- <p>Edit <code>app/page.tsx</code> to get started.</p>
53
- <p>
54
- <a href="/api/health">Check API Health →</a>
12
+ <main className="flex min-h-screen flex-col items-center justify-center bg-gradient-to-br from-indigo-500 to-purple-600 p-8">
13
+ <Card className="w-full max-w-md">
14
+ <CardHeader className="text-center">
15
+ <CardTitle className="text-4xl">🥟 Mandu</CardTitle>
16
+ <CardDescription>
17
+ Welcome to your new Mandu project!
18
+ </CardDescription>
19
+ </CardHeader>
20
+ <CardContent className="flex flex-col gap-4">
21
+ <p className="text-center text-muted-foreground">
22
+ Edit <code className="rounded bg-muted px-1.5 py-0.5 text-sm">app/page.tsx</code> to get started.
55
23
  </p>
56
- </div>
57
- </body>
58
- </html>
24
+ <div className="flex justify-center gap-2">
25
+ <Button asChild variant="default">
26
+ <a href="/api/health">API Health →</a>
27
+ </Button>
28
+ <Button asChild variant="outline">
29
+ <a href="https://mandujs.dev/docs" target="_blank" rel="noopener noreferrer">
30
+ Documentation
31
+ </a>
32
+ </Button>
33
+ </div>
34
+ </CardContent>
35
+ </Card>
36
+ </main>
59
37
  );
60
38
  }
@@ -2,20 +2,29 @@
2
2
  "name": "{{PROJECT_NAME}}",
3
3
  "version": "0.1.0",
4
4
  "type": "module",
5
- "scripts": {
6
- "dev": "mandu dev",
7
- "build": "mandu build",
8
- "test": "bun test"
9
- },
5
+ "scripts": {
6
+ "dev": "mandu dev",
7
+ "build": "mandu build",
8
+ "check": "mandu check",
9
+ "guard": "mandu guard",
10
+ "test": "bun test"
11
+ },
10
12
  "dependencies": {
11
- "@mandujs/core": "^0.9.38",
12
- "react": "^18.2.0",
13
- "react-dom": "^18.2.0"
13
+ "@mandujs/core": "^0.9.39",
14
+ "@radix-ui/react-slot": "^1.1.0",
15
+ "class-variance-authority": "^0.7.0",
16
+ "clsx": "^2.1.1",
17
+ "react": "^19.2.0",
18
+ "react-dom": "^19.2.0",
19
+ "tailwind-merge": "^2.5.2"
14
20
  },
15
21
  "devDependencies": {
16
- "@mandujs/cli": "^0.9.20",
17
- "@types/react": "^18.2.0",
18
- "@types/react-dom": "^18.2.0",
22
+ "@mandujs/cli": "^0.9.21",
23
+ "@types/react": "^19.2.0",
24
+ "@types/react-dom": "^19.2.0",
25
+ "autoprefixer": "^10.4.20",
26
+ "postcss": "^8.4.47",
27
+ "tailwindcss": "^3.4.14",
19
28
  "typescript": "^5.0.0"
20
29
  }
21
30
  }
@@ -0,0 +1,6 @@
1
+ export default {
2
+ plugins: {
3
+ tailwindcss: {},
4
+ autoprefixer: {},
5
+ },
6
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,16 @@
1
+ import { type ClassValue, clsx } from "clsx";
2
+ import { twMerge } from "tailwind-merge";
3
+
4
+ /**
5
+ * cn - Tailwind CSS 클래스 병합 유틸리티
6
+ *
7
+ * clsx로 조건부 클래스를 결합하고
8
+ * tailwind-merge로 충돌하는 클래스를 스마트하게 병합
9
+ *
10
+ * @example
11
+ * cn("px-4 py-2", isActive && "bg-primary", className)
12
+ * cn("text-sm", "text-lg") // → "text-lg" (충돌 해결)
13
+ */
14
+ export function cn(...inputs: ClassValue[]) {
15
+ return twMerge(clsx(inputs));
16
+ }
@@ -0,0 +1,57 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import { Slot } from "@radix-ui/react-slot";
5
+ import { cva, type VariantProps } from "class-variance-authority";
6
+ import { cn } from "@/client/shared/lib/utils";
7
+
8
+ const buttonVariants = cva(
9
+ "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
10
+ {
11
+ variants: {
12
+ variant: {
13
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
14
+ destructive:
15
+ "bg-destructive text-destructive-foreground hover:bg-destructive/90",
16
+ outline:
17
+ "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
18
+ secondary:
19
+ "bg-secondary text-secondary-foreground hover:bg-secondary/80",
20
+ ghost: "hover:bg-accent hover:text-accent-foreground",
21
+ link: "text-primary underline-offset-4 hover:underline",
22
+ },
23
+ size: {
24
+ default: "h-10 px-4 py-2",
25
+ sm: "h-9 rounded-md px-3",
26
+ lg: "h-11 rounded-md px-8",
27
+ icon: "h-10 w-10",
28
+ },
29
+ },
30
+ defaultVariants: {
31
+ variant: "default",
32
+ size: "default",
33
+ },
34
+ }
35
+ );
36
+
37
+ export interface ButtonProps
38
+ extends React.ButtonHTMLAttributes<HTMLButtonElement>,
39
+ VariantProps<typeof buttonVariants> {
40
+ asChild?: boolean;
41
+ }
42
+
43
+ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
44
+ ({ className, variant, size, asChild = false, ...props }, ref) => {
45
+ const Comp = asChild ? Slot : "button";
46
+ return (
47
+ <Comp
48
+ className={cn(buttonVariants({ variant, size, className }))}
49
+ ref={ref}
50
+ {...props}
51
+ />
52
+ );
53
+ }
54
+ );
55
+ Button.displayName = "Button";
56
+
57
+ export { Button, buttonVariants };
@@ -0,0 +1,78 @@
1
+ import * as React from "react";
2
+ import { cn } from "@/client/shared/lib/utils";
3
+
4
+ const Card = React.forwardRef<
5
+ HTMLDivElement,
6
+ React.HTMLAttributes<HTMLDivElement>
7
+ >(({ className, ...props }, ref) => (
8
+ <div
9
+ ref={ref}
10
+ className={cn(
11
+ "rounded-lg border bg-card text-card-foreground shadow-sm",
12
+ className
13
+ )}
14
+ {...props}
15
+ />
16
+ ));
17
+ Card.displayName = "Card";
18
+
19
+ const CardHeader = React.forwardRef<
20
+ HTMLDivElement,
21
+ React.HTMLAttributes<HTMLDivElement>
22
+ >(({ className, ...props }, ref) => (
23
+ <div
24
+ ref={ref}
25
+ className={cn("flex flex-col space-y-1.5 p-6", className)}
26
+ {...props}
27
+ />
28
+ ));
29
+ CardHeader.displayName = "CardHeader";
30
+
31
+ const CardTitle = React.forwardRef<
32
+ HTMLParagraphElement,
33
+ React.HTMLAttributes<HTMLHeadingElement>
34
+ >(({ className, ...props }, ref) => (
35
+ <h3
36
+ ref={ref}
37
+ className={cn(
38
+ "text-2xl font-semibold leading-none tracking-tight",
39
+ className
40
+ )}
41
+ {...props}
42
+ />
43
+ ));
44
+ CardTitle.displayName = "CardTitle";
45
+
46
+ const CardDescription = React.forwardRef<
47
+ HTMLParagraphElement,
48
+ React.HTMLAttributes<HTMLParagraphElement>
49
+ >(({ className, ...props }, ref) => (
50
+ <p
51
+ ref={ref}
52
+ className={cn("text-sm text-muted-foreground", className)}
53
+ {...props}
54
+ />
55
+ ));
56
+ CardDescription.displayName = "CardDescription";
57
+
58
+ const CardContent = React.forwardRef<
59
+ HTMLDivElement,
60
+ React.HTMLAttributes<HTMLDivElement>
61
+ >(({ className, ...props }, ref) => (
62
+ <div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
63
+ ));
64
+ CardContent.displayName = "CardContent";
65
+
66
+ const CardFooter = React.forwardRef<
67
+ HTMLDivElement,
68
+ React.HTMLAttributes<HTMLDivElement>
69
+ >(({ className, ...props }, ref) => (
70
+ <div
71
+ ref={ref}
72
+ className={cn("flex items-center p-6 pt-0", className)}
73
+ {...props}
74
+ />
75
+ ));
76
+ CardFooter.displayName = "CardFooter";
77
+
78
+ export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent };
@@ -0,0 +1,21 @@
1
+ /**
2
+ * UI Components
3
+ *
4
+ * shadcn/ui 스타일의 컴포넌트 라이브러리
5
+ * Radix UI primitives + Tailwind CSS + cva 기반
6
+ */
7
+
8
+ export { Button, buttonVariants } from "./button";
9
+ export type { ButtonProps } from "./button";
10
+
11
+ export {
12
+ Card,
13
+ CardHeader,
14
+ CardFooter,
15
+ CardTitle,
16
+ CardDescription,
17
+ CardContent,
18
+ } from "./card";
19
+
20
+ export { Input } from "./input";
21
+ export type { InputProps } from "./input";
@@ -0,0 +1,24 @@
1
+ import * as React from "react";
2
+ import { cn } from "@/client/shared/lib/utils";
3
+
4
+ export interface InputProps
5
+ extends React.InputHTMLAttributes<HTMLInputElement> {}
6
+
7
+ const Input = React.forwardRef<HTMLInputElement, InputProps>(
8
+ ({ className, type, ...props }, ref) => {
9
+ return (
10
+ <input
11
+ type={type}
12
+ className={cn(
13
+ "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
14
+ className
15
+ )}
16
+ ref={ref}
17
+ {...props}
18
+ />
19
+ );
20
+ }
21
+ );
22
+ Input.displayName = "Input";
23
+
24
+ export { Input };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,64 @@
1
+ import type { Config } from "tailwindcss";
2
+
3
+ const config: Config = {
4
+ content: [
5
+ "./app/**/*.{ts,tsx,mdx}",
6
+ "./src/**/*.{ts,tsx,mdx}",
7
+ ],
8
+ theme: {
9
+ extend: {
10
+ colors: {
11
+ background: "hsl(var(--background))",
12
+ foreground: "hsl(var(--foreground))",
13
+ card: {
14
+ DEFAULT: "hsl(var(--card))",
15
+ foreground: "hsl(var(--card-foreground))",
16
+ },
17
+ popover: {
18
+ DEFAULT: "hsl(var(--popover))",
19
+ foreground: "hsl(var(--popover-foreground))",
20
+ },
21
+ primary: {
22
+ DEFAULT: "hsl(var(--primary))",
23
+ foreground: "hsl(var(--primary-foreground))",
24
+ },
25
+ secondary: {
26
+ DEFAULT: "hsl(var(--secondary))",
27
+ foreground: "hsl(var(--secondary-foreground))",
28
+ },
29
+ muted: {
30
+ DEFAULT: "hsl(var(--muted))",
31
+ foreground: "hsl(var(--muted-foreground))",
32
+ },
33
+ accent: {
34
+ DEFAULT: "hsl(var(--accent))",
35
+ foreground: "hsl(var(--accent-foreground))",
36
+ },
37
+ destructive: {
38
+ DEFAULT: "hsl(var(--destructive))",
39
+ foreground: "hsl(var(--destructive-foreground))",
40
+ },
41
+ border: "hsl(var(--border))",
42
+ input: "hsl(var(--input))",
43
+ ring: "hsl(var(--ring))",
44
+ },
45
+ borderRadius: {
46
+ lg: "var(--radius)",
47
+ md: "calc(var(--radius) - 2px)",
48
+ sm: "calc(var(--radius) - 4px)",
49
+ },
50
+ fontFamily: {
51
+ sans: [
52
+ "-apple-system",
53
+ "BlinkMacSystemFont",
54
+ "Segoe UI",
55
+ "Roboto",
56
+ "sans-serif",
57
+ ],
58
+ },
59
+ },
60
+ },
61
+ plugins: [],
62
+ };
63
+
64
+ export default config;
@@ -7,8 +7,19 @@
7
7
  "strict": true,
8
8
  "skipLibCheck": true,
9
9
  "jsx": "react-jsx",
10
- "types": ["bun-types"]
11
- },
12
- "include": ["apps/**/*.ts", "apps/**/*.tsx"],
10
+ "types": ["bun-types"],
11
+ "baseUrl": ".",
12
+ "paths": {
13
+ "@/*": ["./src/*"]
14
+ }
15
+ },
16
+ "include": [
17
+ "app/**/*.ts",
18
+ "app/**/*.tsx",
19
+ "src/**/*.ts",
20
+ "src/**/*.tsx",
21
+ "apps/**/*.ts",
22
+ "apps/**/*.tsx"
23
+ ],
13
24
  "exclude": ["node_modules"]
14
25
  }