@base44-preview/cli 0.0.1-pr.16.5e81288 → 0.0.1-pr.16.6c1f17f

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/cli/index.js CHANGED
@@ -4,7 +4,7 @@ import chalk from "chalk";
4
4
  import { cancel, group, intro, log, select, spinner, text } from "@clack/prompts";
5
5
  import pWaitFor from "p-wait-for";
6
6
  import { z } from "zod";
7
- import { dirname, join, resolve } from "node:path";
7
+ import { dirname, isAbsolute, join, resolve } from "node:path";
8
8
  import { homedir } from "node:os";
9
9
  import { fileURLToPath } from "node:url";
10
10
  import { config } from "dotenv";
@@ -13,6 +13,7 @@ import { access, copyFile, mkdir, readFile, unlink, writeFile } from "node:fs/pr
13
13
  import { parse, printParseErrorCode } from "jsonc-parser";
14
14
  import ky from "ky";
15
15
  import ejs from "ejs";
16
+ import kebabCase from "lodash.kebabcase";
16
17
 
17
18
  //#region src/core/auth/schema.ts
18
19
  const AuthDataSchema = z.object({
@@ -467,6 +468,7 @@ async function listTemplates() {
467
468
  * - All other files are copied directly
468
469
  */
469
470
  async function renderTemplate(template, destPath, data) {
471
+ if (template.path.includes("..") || isAbsolute(template.path)) throw new Error(`Invalid template path: ${template.path}`);
470
472
  const templateDir = join(getTemplatesDir(), template.path);
471
473
  const files = await globby("**/*", {
472
474
  cwd: templateDir,
@@ -475,8 +477,13 @@ async function renderTemplate(template, destPath, data) {
475
477
  });
476
478
  for (const file of files) {
477
479
  const srcPath = join(templateDir, file);
478
- if (file.endsWith(".ejs")) await writeFile$1(join(destPath, file.slice(0, -4)), await ejs.renderFile(srcPath, data));
479
- else await copyFile$1(srcPath, join(destPath, file));
480
+ try {
481
+ if (file.endsWith(".ejs")) await writeFile$1(join(destPath, file.replace(/\.ejs$/, "")), await ejs.renderFile(srcPath, data));
482
+ else await copyFile$1(srcPath, join(destPath, file));
483
+ } catch (error) {
484
+ const message = error instanceof Error ? error.message : String(error);
485
+ throw new Error(`Failed to process template file "${file}": ${message}`);
486
+ }
480
487
  }
481
488
  }
482
489
 
@@ -846,13 +853,16 @@ async function create() {
846
853
  message: "Project description (optional)",
847
854
  placeholder: "A brief description of your project"
848
855
  }),
849
- projectPath: () => text({
850
- message: "Where should we create the base44 folder?",
851
- placeholder: "./",
852
- initialValue: "./"
853
- })
856
+ projectPath: async ({ results }) => {
857
+ const suggestedPath = `./${kebabCase(results.name)}`;
858
+ return text({
859
+ message: "Where should we create the base44 folder?",
860
+ placeholder: suggestedPath,
861
+ initialValue: suggestedPath
862
+ });
863
+ }
854
864
  }, { onCancel: onPromptCancel });
855
- const resolvedPath = resolve(projectPath || "./");
865
+ const resolvedPath = resolve(projectPath);
856
866
  await runTask("Creating project...", async () => {
857
867
  return await createProjectFiles({
858
868
  name: name.trim(),
@@ -1,15 +1,16 @@
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 { Plus, Trash2, CheckCircle2 } from 'lucide-react';
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";
7
8
 
8
9
  const Task = base44.entities.Task;
9
10
 
10
11
  export default function App() {
11
12
  const [tasks, setTasks] = useState([]);
12
- const [newTaskTitle, setNewTaskTitle] = useState('');
13
+ const [newTaskTitle, setNewTaskTitle] = useState("");
13
14
  const [isLoading, setIsLoading] = useState(true);
14
15
 
15
16
  const fetchTasks = async () => {
@@ -26,7 +27,7 @@ export default function App() {
26
27
  e.preventDefault();
27
28
  if (!newTaskTitle.trim()) return;
28
29
  await Task.create({ title: newTaskTitle.trim(), completed: false });
29
- setNewTaskTitle('');
30
+ setNewTaskTitle("");
30
31
  fetchTasks();
31
32
  };
32
33
 
@@ -41,7 +42,9 @@ export default function App() {
41
42
  };
42
43
 
43
44
  const clearCompleted = async () => {
44
- await Promise.all(tasks.filter((t) => t.completed).map((t) => Task.delete(t.id)));
45
+ await Promise.all(
46
+ tasks.filter((t) => t.completed).map((t) => Task.delete(t.id))
47
+ );
45
48
  fetchTasks();
46
49
  };
47
50
 
@@ -53,10 +56,13 @@ export default function App() {
53
56
  <div className="max-w-lg mx-auto px-6 py-16">
54
57
  {/* Header */}
55
58
  <div className="text-center mb-12">
56
- <div className="inline-flex items-center justify-center w-14 h-14 rounded-2xl bg-gradient-to-br from-orange-500 to-orange-600 shadow-lg shadow-orange-500/25 mb-6">
57
- <CheckCircle2 className="w-7 h-7 text-white" />
58
- </div>
59
- <h1 className="text-3xl font-semibold text-slate-900 tracking-tight">Tasks</h1>
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>
60
66
  {totalCount > 0 && (
61
67
  <p className="text-slate-500 mt-2 text-sm">
62
68
  {completedCount} of {totalCount} completed
@@ -105,7 +111,11 @@ export default function App() {
105
111
  onCheckedChange={(checked) => toggleTask(task.id, checked)}
106
112
  className="w-5 h-5 rounded-md border-slate-300 data-[state=checked]:bg-orange-500 data-[state=checked]:border-orange-500"
107
113
  />
108
- <span className={`flex-1 text-slate-700 transition-all ${task.completed ? 'line-through text-slate-400' : ''}`}>
114
+ <span
115
+ className={`flex-1 text-slate-700 transition-all ${
116
+ task.completed ? "line-through text-slate-400" : ""
117
+ }`}
118
+ >
109
119
  {task.title}
110
120
  </span>
111
121
  <Button
@@ -124,7 +134,10 @@ export default function App() {
124
134
  {/* Footer */}
125
135
  {completedCount > 0 && (
126
136
  <div className="mt-8 text-center">
127
- <button onClick={clearCompleted} className="text-sm text-slate-400 hover:text-slate-600 transition-colors">
137
+ <button
138
+ onClick={clearCompleted}
139
+ className="text-sm text-slate-400 hover:text-slate-600 transition-colors"
140
+ >
128
141
  Clear completed
129
142
  </button>
130
143
  </div>
@@ -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
+ }
@@ -8,8 +8,8 @@
8
8
  },
9
9
  {
10
10
  "id": "backend-and-client",
11
- "name": "Backend + Client",
12
- "description": "Full-stack project with Base44 backend and a React client application",
11
+ "name": "Backend & Client",
12
+ "description": "Full-stack project with Base44 backend, Vite and a React client application",
13
13
  "path": "backend-and-client"
14
14
  }
15
15
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@base44-preview/cli",
3
- "version": "0.0.1-pr.16.5e81288",
3
+ "version": "0.0.1-pr.16.6c1f17f",
4
4
  "description": "Base44 CLI - Unified interface for managing Base44 applications",
5
5
  "type": "module",
6
6
  "main": "./dist/cli/index.js",
@@ -41,12 +41,14 @@
41
41
  "globby": "^16.1.0",
42
42
  "jsonc-parser": "^3.3.1",
43
43
  "ky": "^1.14.2",
44
+ "lodash.kebabcase": "^4.1.1",
44
45
  "p-wait-for": "^6.0.0",
45
46
  "zod": "^4.3.5"
46
47
  },
47
48
  "devDependencies": {
48
49
  "@stylistic/eslint-plugin": "^5.6.1",
49
50
  "@types/ejs": "^3.1.5",
51
+ "@types/lodash.kebabcase": "^4.1.9",
50
52
  "@types/node": "^22.10.5",
51
53
  "@typescript-eslint/eslint-plugin": "^8.51.0",
52
54
  "@typescript-eslint/parser": "^8.51.0",