@base44-preview/cli 0.0.1-pr.16.c796b32 → 0.0.1-pr.17.16cb029

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";
@@ -27,14 +27,12 @@ const DeviceCodeResponseSchema = z.object({
27
27
  device_code: z.string().min(1, "Device code cannot be empty"),
28
28
  user_code: z.string().min(1, "User code cannot be empty"),
29
29
  verification_uri: z.url("Invalid verification URL"),
30
- verification_uri_complete: z.url("Invalid complete verification URL"),
31
30
  expires_in: z.number().int().positive("Expires in must be a positive integer"),
32
31
  interval: z.number().int().positive("Interval in must be a positive integer")
33
32
  }).transform((data) => ({
34
33
  deviceCode: data.device_code,
35
34
  userCode: data.user_code,
36
35
  verificationUri: data.verification_uri,
37
- verificationUriComplete: data.verification_uri_complete,
38
36
  expiresIn: data.expires_in,
39
37
  interval: data.interval
40
38
  }));
@@ -468,6 +466,7 @@ async function listTemplates() {
468
466
  * - All other files are copied directly
469
467
  */
470
468
  async function renderTemplate(template, destPath, data) {
469
+ if (template.path.includes("..") || isAbsolute(template.path)) throw new Error(`Invalid template path: ${template.path}`);
471
470
  const templateDir = join(getTemplatesDir(), template.path);
472
471
  const files = await globby("**/*", {
473
472
  cwd: templateDir,
@@ -476,8 +475,13 @@ async function renderTemplate(template, destPath, data) {
476
475
  });
477
476
  for (const file of files) {
478
477
  const srcPath = join(templateDir, file);
479
- if (file.endsWith(".ejs")) await writeFile$1(join(destPath, file.slice(0, -4)), await ejs.renderFile(srcPath, data));
480
- else await copyFile$1(srcPath, join(destPath, file));
478
+ try {
479
+ if (file.endsWith(".ejs")) await writeFile$1(join(destPath, file.replace(/\.ejs$/, "")), await ejs.renderFile(srcPath, data));
480
+ else await copyFile$1(srcPath, join(destPath, file));
481
+ } catch (error) {
482
+ const message = error instanceof Error ? error.message : String(error);
483
+ throw new Error(`Failed to process template file "${file}": ${message}`);
484
+ }
481
485
  }
482
486
  }
483
487
 
@@ -711,13 +715,13 @@ async function generateAndDisplayDeviceCode() {
711
715
  successMessage: "Device code generated",
712
716
  errorMessage: "Failed to generate device code"
713
717
  });
714
- log.info(`Your code is: ${chalk.bold(deviceCodeResponse.userCode)}\nPlease visit: ${deviceCodeResponse.verificationUriComplete}`);
718
+ log.info(`Verification code: ${chalk.bold(deviceCodeResponse.userCode)}\nPlease confirm this code at: ${deviceCodeResponse.verificationUri}`);
715
719
  return deviceCodeResponse;
716
720
  }
717
721
  async function waitForAuthentication(deviceCode, expiresIn, interval) {
718
722
  let tokenResponse;
719
723
  try {
720
- await runTask("Waiting for you to complete authentication...", async () => {
724
+ await runTask("Waiting for authentication...", async () => {
721
725
  await pWaitFor(async () => {
722
726
  const result = await getTokenFromDeviceCode(deviceCode);
723
727
  if (result !== null) {
@@ -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,7 +8,7 @@
8
8
  },
9
9
  {
10
10
  "id": "backend-and-client",
11
- "name": "To Do App - Backend + Client",
11
+ "name": "Backend & Client",
12
12
  "description": "Full-stack project with Base44 backend, Vite and a React client application",
13
13
  "path": "backend-and-client"
14
14
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@base44-preview/cli",
3
- "version": "0.0.1-pr.16.c796b32",
3
+ "version": "0.0.1-pr.17.16cb029",
4
4
  "description": "Base44 CLI - Unified interface for managing Base44 applications",
5
5
  "type": "module",
6
6
  "main": "./dist/cli/index.js",