@base44-preview/cli 0.0.44-pr.410.d6ad399 → 0.0.44-pr.411.fe4049c
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/dist/assets/templates/backend-and-client/README.md +7 -5
- package/dist/assets/templates/backend-and-client/base44/agents/task_manager.jsonc +11 -0
- package/dist/assets/templates/backend-and-client/components.json +16 -0
- package/dist/assets/templates/backend-and-client/index.html +2 -2
- package/dist/assets/templates/backend-and-client/jsconfig.json +13 -0
- package/dist/assets/templates/backend-and-client/package.json +7 -6
- package/dist/assets/templates/backend-and-client/postcss.config.js +6 -0
- package/dist/assets/templates/backend-and-client/src/App.jsx +148 -0
- package/dist/assets/templates/backend-and-client/src/components/Base44Logo.jsx +15 -0
- package/dist/assets/templates/backend-and-client/src/components/ui/button.jsx +23 -0
- package/dist/assets/templates/backend-and-client/src/components/ui/checkbox.jsx +20 -0
- package/dist/assets/templates/backend-and-client/src/components/ui/input.jsx +13 -0
- package/dist/assets/templates/backend-and-client/src/index.css +34 -5
- package/dist/assets/templates/backend-and-client/src/main.jsx +6 -0
- package/dist/assets/templates/backend-and-client/tailwind.config.js +41 -0
- package/dist/assets/templates/backend-and-client/vite.config.js +12 -0
- package/dist/cli/index.js +99 -6
- package/dist/cli/index.js.map +5 -4
- package/package.json +1 -1
- package/dist/assets/templates/backend-and-client/src/App.tsx +0 -74
- package/dist/assets/templates/backend-and-client/src/main.tsx +0 -10
- package/dist/assets/templates/backend-and-client/tsconfig.app.json +0 -32
- package/dist/assets/templates/backend-and-client/tsconfig.json +0 -7
- package/dist/assets/templates/backend-and-client/tsconfig.node.json +0 -24
- package/dist/assets/templates/backend-and-client/vite.config.ts +0 -15
- /package/dist/assets/templates/backend-and-client/src/api/{base44Client.ts.ejs → base44Client.js.ejs} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Todo App
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
A simple todo list app built with React and Base44 backend.
|
|
4
4
|
|
|
5
5
|
## Structure
|
|
6
6
|
|
|
@@ -11,8 +11,10 @@ base44/ # Backend configuration
|
|
|
11
11
|
└── task.jsonc # Task entity
|
|
12
12
|
|
|
13
13
|
src/ # Frontend code
|
|
14
|
-
├── App.
|
|
15
|
-
|
|
14
|
+
├── App.jsx # Main todo app
|
|
15
|
+
├── api/ # Base44 client
|
|
16
|
+
├── components/ui/ # UI components
|
|
17
|
+
└── lib/ # Utilities
|
|
16
18
|
```
|
|
17
19
|
|
|
18
20
|
## Development
|
|
@@ -27,7 +29,7 @@ npm run dev
|
|
|
27
29
|
| Command | Description |
|
|
28
30
|
|---------|-------------|
|
|
29
31
|
| `npm run dev` | Start dev server |
|
|
30
|
-
| `npm run build` |
|
|
32
|
+
| `npm run build` | Build for production |
|
|
31
33
|
| `npm run preview` | Preview production build |
|
|
32
34
|
|
|
33
35
|
## Base44 CLI
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "task_manager",
|
|
3
|
+
"description": "An AI agent that helps you manage and change your tasks",
|
|
4
|
+
"instructions": "You are a helpful task management assistant. You can help users create, update, mark as completed, and delete tasks using the entity tool. When a user asks to change a task, help them modify it by updating the appropriate fields. Always be conversational and helpful.",
|
|
5
|
+
"tool_configs": [
|
|
6
|
+
{
|
|
7
|
+
"entity_name": "Task",
|
|
8
|
+
"allowed_operations": ["read", "create", "update", "delete"]
|
|
9
|
+
}
|
|
10
|
+
]
|
|
11
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema.json",
|
|
3
|
+
"style": "new-york",
|
|
4
|
+
"rsc": false,
|
|
5
|
+
"tsx": false,
|
|
6
|
+
"tailwind": {
|
|
7
|
+
"config": "tailwind.config.js",
|
|
8
|
+
"css": "src/index.css",
|
|
9
|
+
"baseColor": "slate",
|
|
10
|
+
"cssVariables": true
|
|
11
|
+
},
|
|
12
|
+
"aliases": {
|
|
13
|
+
"components": "@/components",
|
|
14
|
+
"ui": "@/components/ui"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<link rel="icon" type="image/svg+xml" href="https://base44.com/logo_v2.svg" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
-
<title>
|
|
7
|
+
<title>Todo App</title>
|
|
8
8
|
</head>
|
|
9
9
|
<body>
|
|
10
10
|
<div id="root"></div>
|
|
11
|
-
<script type="module" src="/src/main.
|
|
11
|
+
<script type="module" src="/src/main.jsx"></script>
|
|
12
12
|
</body>
|
|
13
13
|
</html>
|
|
@@ -5,19 +5,20 @@
|
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"dev": "vite",
|
|
8
|
-
"build": "
|
|
8
|
+
"build": "vite build",
|
|
9
9
|
"preview": "vite preview"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@base44/sdk": "^0.8.3",
|
|
13
|
-
"react": "^
|
|
14
|
-
"react
|
|
13
|
+
"lucide-react": "^0.475.0",
|
|
14
|
+
"react": "^18.2.0",
|
|
15
|
+
"react-dom": "^18.2.0"
|
|
15
16
|
},
|
|
16
17
|
"devDependencies": {
|
|
17
|
-
"@types/react": "^18.3.1",
|
|
18
|
-
"@types/react-dom": "^18.3.1",
|
|
19
18
|
"@vitejs/plugin-react": "^4.3.4",
|
|
20
|
-
"
|
|
19
|
+
"autoprefixer": "^10.4.20",
|
|
20
|
+
"postcss": "^8.5.3",
|
|
21
|
+
"tailwindcss": "^3.4.17",
|
|
21
22
|
"vite": "^6.1.0"
|
|
22
23
|
}
|
|
23
24
|
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { useState, useEffect } from "react";
|
|
2
|
+
import { base44 } from "@/api/base44Client";
|
|
3
|
+
import { Button } from "@/components/ui/button";
|
|
4
|
+
import { Checkbox } from "@/components/ui/checkbox";
|
|
5
|
+
import { Input } from "@/components/ui/input";
|
|
6
|
+
import { Base44Logo } from "@/components/Base44Logo";
|
|
7
|
+
import { Plus, Trash2, CheckCircle2 } from "lucide-react";
|
|
8
|
+
|
|
9
|
+
const Task = base44.entities.Task;
|
|
10
|
+
|
|
11
|
+
export default function App() {
|
|
12
|
+
const [tasks, setTasks] = useState([]);
|
|
13
|
+
const [newTaskTitle, setNewTaskTitle] = useState("");
|
|
14
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
15
|
+
|
|
16
|
+
const fetchTasks = async () => {
|
|
17
|
+
const data = await Task.list();
|
|
18
|
+
setTasks(data);
|
|
19
|
+
setIsLoading(false);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
fetchTasks();
|
|
24
|
+
}, []);
|
|
25
|
+
|
|
26
|
+
const handleSubmit = async (e) => {
|
|
27
|
+
e.preventDefault();
|
|
28
|
+
if (!newTaskTitle.trim()) return;
|
|
29
|
+
await Task.create({ title: newTaskTitle.trim(), completed: false });
|
|
30
|
+
setNewTaskTitle("");
|
|
31
|
+
fetchTasks();
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const toggleTask = async (id, completed) => {
|
|
35
|
+
await Task.update(id, { completed });
|
|
36
|
+
fetchTasks();
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const deleteTask = async (id) => {
|
|
40
|
+
await Task.delete(id);
|
|
41
|
+
fetchTasks();
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const clearCompleted = async () => {
|
|
45
|
+
await Promise.all(
|
|
46
|
+
tasks.filter((t) => t.completed).map((t) => Task.delete(t.id))
|
|
47
|
+
);
|
|
48
|
+
fetchTasks();
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const completedCount = tasks.filter((t) => t.completed).length;
|
|
52
|
+
const totalCount = tasks.length;
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<div className="min-h-screen bg-gradient-to-br from-slate-50 via-white to-orange-50/30">
|
|
56
|
+
<div className="max-w-lg mx-auto px-6 py-16">
|
|
57
|
+
{/* Header */}
|
|
58
|
+
<div className="text-center mb-12">
|
|
59
|
+
<h1 className="text-3xl font-semibold text-slate-900 tracking-tight">
|
|
60
|
+
<span className="inline-flex items-center gap-2 align-middle">
|
|
61
|
+
<Base44Logo className="w-9 h-9" />
|
|
62
|
+
<span className="font-bold">Base44</span>
|
|
63
|
+
<span>Tasks</span>
|
|
64
|
+
</span>
|
|
65
|
+
</h1>
|
|
66
|
+
{totalCount > 0 && (
|
|
67
|
+
<p className="text-slate-500 mt-2 text-sm">
|
|
68
|
+
{completedCount} of {totalCount} completed
|
|
69
|
+
</p>
|
|
70
|
+
)}
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
{/* Add Task Form */}
|
|
74
|
+
<form onSubmit={handleSubmit} className="mb-8">
|
|
75
|
+
<div className="flex gap-3">
|
|
76
|
+
<Input
|
|
77
|
+
type="text"
|
|
78
|
+
value={newTaskTitle}
|
|
79
|
+
onChange={(e) => setNewTaskTitle(e.target.value)}
|
|
80
|
+
placeholder="What needs to be done?"
|
|
81
|
+
className="flex-1 h-12 bg-white border-slate-200 rounded-xl shadow-sm"
|
|
82
|
+
/>
|
|
83
|
+
<Button
|
|
84
|
+
type="submit"
|
|
85
|
+
disabled={!newTaskTitle.trim()}
|
|
86
|
+
className="h-12 px-5 rounded-xl bg-slate-900 hover:bg-slate-800 shadow-sm"
|
|
87
|
+
>
|
|
88
|
+
<Plus className="w-5 h-5" />
|
|
89
|
+
</Button>
|
|
90
|
+
</div>
|
|
91
|
+
</form>
|
|
92
|
+
|
|
93
|
+
{/* Task List */}
|
|
94
|
+
<div className="space-y-2">
|
|
95
|
+
{isLoading ? (
|
|
96
|
+
<div className="flex items-center justify-center py-12">
|
|
97
|
+
<div className="w-6 h-6 border-2 border-slate-200 border-t-orange-500 rounded-full animate-spin" />
|
|
98
|
+
</div>
|
|
99
|
+
) : tasks.length === 0 ? (
|
|
100
|
+
<div className="text-center py-12">
|
|
101
|
+
<p className="text-slate-400">No tasks yet. Add one above!</p>
|
|
102
|
+
</div>
|
|
103
|
+
) : (
|
|
104
|
+
tasks.map((task) => (
|
|
105
|
+
<div
|
|
106
|
+
key={task.id}
|
|
107
|
+
className="group flex items-center gap-4 p-4 bg-white rounded-xl border border-slate-100 shadow-sm hover:shadow-md transition-all duration-200"
|
|
108
|
+
>
|
|
109
|
+
<Checkbox
|
|
110
|
+
checked={task.completed}
|
|
111
|
+
onCheckedChange={(checked) => toggleTask(task.id, checked)}
|
|
112
|
+
className="w-5 h-5 rounded-md border-slate-300 data-[state=checked]:bg-orange-500 data-[state=checked]:border-orange-500"
|
|
113
|
+
/>
|
|
114
|
+
<span
|
|
115
|
+
className={`flex-1 text-slate-700 transition-all ${
|
|
116
|
+
task.completed ? "line-through text-slate-400" : ""
|
|
117
|
+
}`}
|
|
118
|
+
>
|
|
119
|
+
{task.title}
|
|
120
|
+
</span>
|
|
121
|
+
<Button
|
|
122
|
+
variant="ghost"
|
|
123
|
+
size="icon"
|
|
124
|
+
onClick={() => deleteTask(task.id)}
|
|
125
|
+
className="opacity-0 group-hover:opacity-100 h-8 w-8 text-slate-400 hover:text-red-500 hover:bg-red-50 transition-all"
|
|
126
|
+
>
|
|
127
|
+
<Trash2 className="w-4 h-4" />
|
|
128
|
+
</Button>
|
|
129
|
+
</div>
|
|
130
|
+
))
|
|
131
|
+
)}
|
|
132
|
+
</div>
|
|
133
|
+
|
|
134
|
+
{/* Footer */}
|
|
135
|
+
{completedCount > 0 && (
|
|
136
|
+
<div className="mt-8 text-center">
|
|
137
|
+
<button
|
|
138
|
+
onClick={clearCompleted}
|
|
139
|
+
className="text-sm text-slate-400 hover:text-slate-600 transition-colors"
|
|
140
|
+
>
|
|
141
|
+
Clear completed
|
|
142
|
+
</button>
|
|
143
|
+
</div>
|
|
144
|
+
)}
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
);
|
|
148
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function Base44Logo({ className = "w-8 h-8" }) {
|
|
2
|
+
return (
|
|
3
|
+
<svg
|
|
4
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
5
|
+
fill="none"
|
|
6
|
+
viewBox="0 0 31 31"
|
|
7
|
+
className={className}
|
|
8
|
+
>
|
|
9
|
+
<path
|
|
10
|
+
fill="#FF631F"
|
|
11
|
+
d="M24.16 26.904c.04 0 .057.05.026.075a14.97 14.97 0 0 1-9.147 3.1c-3.44 0-6.612-1.156-9.146-3.1-.032-.024-.014-.075.026-.075zm3.923-4.373a15 15 0 0 1-1.842 2.544.14.14 0 0 1-.104.046H3.942a.14.14 0 0 1-.104-.046 15 15 0 0 1-1.842-2.544.056.056 0 0 1 .049-.083h25.99c.043 0 .07.046.048.083m1.698-4.5a15 15 0 0 1-.762 2.564.11.11 0 0 1-.103.07H1.163a.11.11 0 0 1-.104-.07 15 15 0 0 1-.762-2.564.056.056 0 0 1 .055-.067h29.375c.035 0 .061.032.054.067M14.938 0C23.29-.056 30.078 6.7 30.078 15.04q0 .55-.038 1.09a.056.056 0 0 1-.056.051H.094a.056.056 0 0 1-.055-.052A15 15 0 0 1 0 15.054C-.007 6.87 6.755.055 14.938 0"
|
|
12
|
+
></path>
|
|
13
|
+
</svg>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { forwardRef } from 'react';
|
|
2
|
+
|
|
3
|
+
const Button = forwardRef(({ className = '', variant, size, ...props }, ref) => {
|
|
4
|
+
const baseStyles = 'inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50';
|
|
5
|
+
|
|
6
|
+
const variantStyles = variant === 'ghost'
|
|
7
|
+
? 'hover:bg-slate-100'
|
|
8
|
+
: 'bg-slate-900 text-white shadow hover:bg-slate-800';
|
|
9
|
+
|
|
10
|
+
const sizeStyles = size === 'icon' ? 'h-9 w-9' : 'h-9 px-4 py-2';
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<button
|
|
14
|
+
ref={ref}
|
|
15
|
+
className={`${baseStyles} ${variantStyles} ${sizeStyles} ${className}`}
|
|
16
|
+
{...props}
|
|
17
|
+
/>
|
|
18
|
+
);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
Button.displayName = 'Button';
|
|
22
|
+
|
|
23
|
+
export { Button };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { forwardRef } from 'react';
|
|
2
|
+
import { Check } from 'lucide-react';
|
|
3
|
+
|
|
4
|
+
const Checkbox = forwardRef(({ className = '', checked, onCheckedChange, ...props }, ref) => (
|
|
5
|
+
<button
|
|
6
|
+
ref={ref}
|
|
7
|
+
type="button"
|
|
8
|
+
role="checkbox"
|
|
9
|
+
aria-checked={checked}
|
|
10
|
+
onClick={() => onCheckedChange?.(!checked)}
|
|
11
|
+
className={`h-4 w-4 shrink-0 rounded-sm border border-slate-300 shadow-sm flex items-center justify-center focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-slate-400 disabled:cursor-not-allowed disabled:opacity-50 ${checked ? 'bg-slate-900 text-white border-slate-900' : 'bg-white'} ${className}`}
|
|
12
|
+
{...props}
|
|
13
|
+
>
|
|
14
|
+
{checked && <Check className="h-3 w-3" />}
|
|
15
|
+
</button>
|
|
16
|
+
));
|
|
17
|
+
|
|
18
|
+
Checkbox.displayName = 'Checkbox';
|
|
19
|
+
|
|
20
|
+
export { Checkbox };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { forwardRef } from 'react';
|
|
2
|
+
|
|
3
|
+
const Input = forwardRef(({ className = '', ...props }, ref) => (
|
|
4
|
+
<input
|
|
5
|
+
ref={ref}
|
|
6
|
+
className={`flex h-9 w-full rounded-md border border-slate-200 bg-white px-3 py-1 text-sm shadow-sm transition-colors placeholder:text-slate-400 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-slate-400 disabled:cursor-not-allowed disabled:opacity-50 ${className}`}
|
|
7
|
+
{...props}
|
|
8
|
+
/>
|
|
9
|
+
));
|
|
10
|
+
|
|
11
|
+
Input.displayName = 'Input';
|
|
12
|
+
|
|
13
|
+
export { Input };
|
|
@@ -1,8 +1,37 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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
|
+
}
|
|
3
28
|
}
|
|
4
29
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
30
|
+
@layer base {
|
|
31
|
+
* {
|
|
32
|
+
@apply border-border;
|
|
33
|
+
}
|
|
34
|
+
body {
|
|
35
|
+
@apply bg-background text-foreground antialiased;
|
|
36
|
+
}
|
|
8
37
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/** @type {import('tailwindcss').Config} */
|
|
2
|
+
export default {
|
|
3
|
+
content: ['./index.html', './src/**/*.{js,jsx}'],
|
|
4
|
+
theme: {
|
|
5
|
+
extend: {
|
|
6
|
+
borderRadius: {
|
|
7
|
+
lg: 'var(--radius)',
|
|
8
|
+
md: 'calc(var(--radius) - 2px)',
|
|
9
|
+
sm: 'calc(var(--radius) - 4px)',
|
|
10
|
+
},
|
|
11
|
+
colors: {
|
|
12
|
+
background: 'hsl(var(--background))',
|
|
13
|
+
foreground: 'hsl(var(--foreground))',
|
|
14
|
+
primary: {
|
|
15
|
+
DEFAULT: 'hsl(var(--primary))',
|
|
16
|
+
foreground: 'hsl(var(--primary-foreground))',
|
|
17
|
+
},
|
|
18
|
+
secondary: {
|
|
19
|
+
DEFAULT: 'hsl(var(--secondary))',
|
|
20
|
+
foreground: 'hsl(var(--secondary-foreground))',
|
|
21
|
+
},
|
|
22
|
+
muted: {
|
|
23
|
+
DEFAULT: 'hsl(var(--muted))',
|
|
24
|
+
foreground: 'hsl(var(--muted-foreground))',
|
|
25
|
+
},
|
|
26
|
+
accent: {
|
|
27
|
+
DEFAULT: 'hsl(var(--accent))',
|
|
28
|
+
foreground: 'hsl(var(--accent-foreground))',
|
|
29
|
+
},
|
|
30
|
+
destructive: {
|
|
31
|
+
DEFAULT: 'hsl(var(--destructive))',
|
|
32
|
+
foreground: 'hsl(var(--destructive-foreground))',
|
|
33
|
+
},
|
|
34
|
+
border: 'hsl(var(--border))',
|
|
35
|
+
input: 'hsl(var(--input))',
|
|
36
|
+
ring: 'hsl(var(--ring))',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
plugins: [],
|
|
41
|
+
};
|
package/dist/cli/index.js
CHANGED
|
@@ -214782,7 +214782,7 @@ var require_dist5 = __commonJS((exports, module) => {
|
|
|
214782
214782
|
});
|
|
214783
214783
|
|
|
214784
214784
|
// src/cli/index.ts
|
|
214785
|
-
import { dirname as
|
|
214785
|
+
import { dirname as dirname16, join as join20 } from "node:path";
|
|
214786
214786
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
214787
214787
|
|
|
214788
214788
|
// ../../node_modules/commander/esm.mjs
|
|
@@ -251167,6 +251167,98 @@ function getEjectCommand(context) {
|
|
|
251167
251167
|
});
|
|
251168
251168
|
}
|
|
251169
251169
|
|
|
251170
|
+
// src/cli/commands/project/validate.ts
|
|
251171
|
+
import { dirname as dirname14, join as join19, relative as relative7 } from "node:path";
|
|
251172
|
+
async function validateFiles(dir, glob, schema9, projectRoot) {
|
|
251173
|
+
if (!await pathExists(dir)) {
|
|
251174
|
+
return [];
|
|
251175
|
+
}
|
|
251176
|
+
const files = await globby(glob, { cwd: dir, absolute: true });
|
|
251177
|
+
const results = [];
|
|
251178
|
+
for (const filePath of files) {
|
|
251179
|
+
const relativePath = relative7(projectRoot, filePath);
|
|
251180
|
+
try {
|
|
251181
|
+
const parsed = await readJsonFile(filePath);
|
|
251182
|
+
const result = schema9.safeParse(parsed);
|
|
251183
|
+
if (result.success) {
|
|
251184
|
+
results.push({ relativePath, valid: true });
|
|
251185
|
+
} else {
|
|
251186
|
+
results.push({
|
|
251187
|
+
relativePath,
|
|
251188
|
+
valid: false,
|
|
251189
|
+
errorText: exports_external.prettifyError(result.error)
|
|
251190
|
+
});
|
|
251191
|
+
}
|
|
251192
|
+
} catch (error48) {
|
|
251193
|
+
results.push({
|
|
251194
|
+
relativePath,
|
|
251195
|
+
valid: false,
|
|
251196
|
+
errorText: error48 instanceof Error ? error48.message : String(error48)
|
|
251197
|
+
});
|
|
251198
|
+
}
|
|
251199
|
+
}
|
|
251200
|
+
return results;
|
|
251201
|
+
}
|
|
251202
|
+
function printResults(results) {
|
|
251203
|
+
for (const result of results) {
|
|
251204
|
+
if (result.valid) {
|
|
251205
|
+
R2.success(result.relativePath);
|
|
251206
|
+
} else {
|
|
251207
|
+
const indented = result.errorText?.split(`
|
|
251208
|
+
`).map((line3) => ` ${line3}`).join(`
|
|
251209
|
+
`);
|
|
251210
|
+
R2.error(`${result.relativePath}
|
|
251211
|
+
${indented ?? ""}`);
|
|
251212
|
+
}
|
|
251213
|
+
}
|
|
251214
|
+
}
|
|
251215
|
+
async function validateAction() {
|
|
251216
|
+
const found = await findProjectRoot();
|
|
251217
|
+
if (!found) {
|
|
251218
|
+
throw new ConfigNotFoundError;
|
|
251219
|
+
}
|
|
251220
|
+
const { root: root2, configPath } = found;
|
|
251221
|
+
const relConfigPath = relative7(root2, configPath);
|
|
251222
|
+
const allResults = [];
|
|
251223
|
+
const configParsed = await readJsonFile(configPath);
|
|
251224
|
+
const configResult = ProjectConfigSchema.safeParse(configParsed);
|
|
251225
|
+
if (!configResult.success) {
|
|
251226
|
+
allResults.push({
|
|
251227
|
+
relativePath: relConfigPath,
|
|
251228
|
+
valid: false,
|
|
251229
|
+
errorText: exports_external.prettifyError(configResult.error)
|
|
251230
|
+
});
|
|
251231
|
+
printResults(allResults);
|
|
251232
|
+
process.exitCode = 1;
|
|
251233
|
+
return { outroMessage: "1 file checked — 0 passed, 1 failed" };
|
|
251234
|
+
}
|
|
251235
|
+
allResults.push({ relativePath: relConfigPath, valid: true });
|
|
251236
|
+
const config10 = configResult.data;
|
|
251237
|
+
const configDir = dirname14(configPath);
|
|
251238
|
+
const [entityResults, agentResults, connectorResults, functionResults] = await Promise.all([
|
|
251239
|
+
validateFiles(join19(configDir, config10.entitiesDir), `*.${CONFIG_FILE_EXTENSION_GLOB}`, EntitySchema, root2),
|
|
251240
|
+
validateFiles(join19(configDir, config10.agentsDir), `*.${CONFIG_FILE_EXTENSION_GLOB}`, AgentConfigSchema, root2),
|
|
251241
|
+
validateFiles(join19(configDir, config10.connectorsDir), `*.${CONFIG_FILE_EXTENSION_GLOB}`, ConnectorResourceSchema, root2),
|
|
251242
|
+
validateFiles(join19(configDir, config10.functionsDir), FUNCTION_CONFIG_GLOB, FunctionConfigSchema, root2)
|
|
251243
|
+
]);
|
|
251244
|
+
allResults.push(...entityResults, ...agentResults, ...connectorResults, ...functionResults);
|
|
251245
|
+
printResults(allResults);
|
|
251246
|
+
const failCount = allResults.filter((r5) => !r5.valid).length;
|
|
251247
|
+
const passCount = allResults.length - failCount;
|
|
251248
|
+
const total = allResults.length;
|
|
251249
|
+
if (failCount > 0) {
|
|
251250
|
+
process.exitCode = 1;
|
|
251251
|
+
}
|
|
251252
|
+
return {
|
|
251253
|
+
outroMessage: failCount > 0 ? `${total} file${total !== 1 ? "s" : ""} checked — ${passCount} passed, ${failCount} failed` : `All ${passCount} file${passCount !== 1 ? "s" : ""} valid`
|
|
251254
|
+
};
|
|
251255
|
+
}
|
|
251256
|
+
function getValidateCommand(context) {
|
|
251257
|
+
return new Command("validate").description("Validate all resource config files in the project (entities, functions, agents, connectors)").action(async () => {
|
|
251258
|
+
await runCommand(validateAction, { requireAuth: false, requireAppConfig: false }, context);
|
|
251259
|
+
});
|
|
251260
|
+
}
|
|
251261
|
+
|
|
251170
251262
|
// src/cli/program.ts
|
|
251171
251263
|
function createProgram(context) {
|
|
251172
251264
|
const program2 = new Command;
|
|
@@ -251182,6 +251274,7 @@ function createProgram(context) {
|
|
|
251182
251274
|
program2.addCommand(getDeployCommand(context));
|
|
251183
251275
|
program2.addCommand(getLinkCommand(context));
|
|
251184
251276
|
program2.addCommand(getEjectCommand(context));
|
|
251277
|
+
program2.addCommand(getValidateCommand(context));
|
|
251185
251278
|
program2.addCommand(getEntitiesPushCommand(context));
|
|
251186
251279
|
program2.addCommand(getAgentsCommand(context));
|
|
251187
251280
|
program2.addCommand(getConnectorsCommand(context));
|
|
@@ -251199,7 +251292,7 @@ var import_detect_agent = __toESM(require_dist5(), 1);
|
|
|
251199
251292
|
import { release, type } from "node:os";
|
|
251200
251293
|
|
|
251201
251294
|
// ../../node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
|
|
251202
|
-
import { dirname as
|
|
251295
|
+
import { dirname as dirname15, posix, sep } from "path";
|
|
251203
251296
|
function createModulerModifier() {
|
|
251204
251297
|
const getModuleFromFileName = createGetModuleFromFilename();
|
|
251205
251298
|
return async (frames) => {
|
|
@@ -251208,7 +251301,7 @@ function createModulerModifier() {
|
|
|
251208
251301
|
return frames;
|
|
251209
251302
|
};
|
|
251210
251303
|
}
|
|
251211
|
-
function createGetModuleFromFilename(basePath = process.argv[1] ?
|
|
251304
|
+
function createGetModuleFromFilename(basePath = process.argv[1] ? dirname15(process.argv[1]) : process.cwd(), isWindows5 = sep === "\\") {
|
|
251212
251305
|
const normalizedBase = isWindows5 ? normalizeWindowsPath2(basePath) : basePath;
|
|
251213
251306
|
return (filename) => {
|
|
251214
251307
|
if (!filename)
|
|
@@ -255397,9 +255490,9 @@ function addCommandInfoToErrorReporter(program2, errorReporter) {
|
|
|
255397
255490
|
});
|
|
255398
255491
|
}
|
|
255399
255492
|
// src/cli/index.ts
|
|
255400
|
-
var __dirname4 =
|
|
255493
|
+
var __dirname4 = dirname16(fileURLToPath6(import.meta.url));
|
|
255401
255494
|
async function runCLI(options8) {
|
|
255402
|
-
ensureNpmAssets(
|
|
255495
|
+
ensureNpmAssets(join20(__dirname4, "../assets"));
|
|
255403
255496
|
const errorReporter = new ErrorReporter;
|
|
255404
255497
|
errorReporter.registerProcessErrorHandlers();
|
|
255405
255498
|
const isNonInteractive = !process.stdin.isTTY || !process.stdout.isTTY;
|
|
@@ -255432,4 +255525,4 @@ export {
|
|
|
255432
255525
|
CLIExitError
|
|
255433
255526
|
};
|
|
255434
255527
|
|
|
255435
|
-
//# debugId=
|
|
255528
|
+
//# debugId=0DE0087568D02AA264756E2164756E21
|