@fireberry/cli 0.2.5-beta.1 → 0.2.5

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.
@@ -13,13 +13,7 @@ const program = new Command();
13
13
  program
14
14
  .name("fireberry")
15
15
  .description("Fireberry developer CLI")
16
- .version(packageJson.version)
17
- .configureOutput({
18
- outputError: (str, write) => {
19
- const formatted = str.replace(/^error:/i, 'Error:');
20
- write(chalk.red(formatted));
21
- }
22
- });
16
+ .version(packageJson.version);
23
17
  program
24
18
  .command("init")
25
19
  .argument("[tokenid]", "Fireberry token id")
@@ -29,9 +23,10 @@ program
29
23
  });
30
24
  program
31
25
  .command("create")
32
- .argument("[name]", "App name")
33
- .description("Create a new Fireberry app with a component")
34
- .action(async (name) => {
26
+ .argument("[name...]", "App name")
27
+ .description("Create a new Fireberry app")
28
+ .action(async (nameArgs) => {
29
+ const name = nameArgs ? nameArgs.join("-") : undefined;
35
30
  await runCreate({ name });
36
31
  });
37
32
  program
@@ -13,12 +13,6 @@ import { HEIGHT_OPTIONS } from "../constants/height-options.js";
13
13
  const __filename = fileURLToPath(import.meta.url);
14
14
  const __dirname = path.dirname(__filename);
15
15
  const VALID_COMPONENT_TYPES = Object.values(COMPONENT_TYPE);
16
- function sanitizeComponentName(name) {
17
- return name
18
- .toLowerCase()
19
- .replace(/[^a-z0-9]+/g, "-")
20
- .replace(/^-+|-+$/g, "");
21
- }
22
16
  function validateComponentType(type) {
23
17
  if (!VALID_COMPONENT_TYPES.includes(type)) {
24
18
  throw new Error(`Invalid component type: "${type}". Valid types are: ${VALID_COMPONENT_TYPES.join(", ")}`);
@@ -124,17 +118,17 @@ export async function runCreateComponent({ type, name, }) {
124
118
  throw new Error(`Component with name "${componentName}" already exists in manifest.yml`);
125
119
  }
126
120
  const validatedType = validateComponentType(componentType);
127
- const sanitizedName = sanitizeComponentName(componentName);
128
121
  const spinner = ora();
129
122
  try {
130
123
  const componentSettings = await promptForSettings(validatedType);
131
124
  spinner.text = chalk.cyan(`Creating Vite React app for "${chalk.cyan(componentName)}"...`);
132
125
  spinner.start();
133
- const componentDir = path.join(process.cwd(), componentName);
126
+ const componentDir = path.join(process.cwd(), "static", componentName);
134
127
  await fs.ensureDir(componentDir);
128
+ // Create Vite app with React template
135
129
  spinner.text = `Running npm create vite@latest...`;
136
- const viteResult = spawnSync(`npm create vite@latest ${sanitizedName} -- --template react --no-interactive`, {
137
- cwd: process.cwd(),
130
+ const viteResult = spawnSync(`npm create vite@latest ${componentName} -- --template react --no-interactive`, {
131
+ cwd: path.join(process.cwd(), "static"),
138
132
  stdio: "inherit",
139
133
  shell: true,
140
134
  });
@@ -183,7 +177,7 @@ export async function runCreateComponent({ type, name, }) {
183
177
  type: validatedType,
184
178
  title: componentName,
185
179
  id: componentId,
186
- path: `${componentName}/dist`,
180
+ path: `static/${componentName}/dist`,
187
181
  settings: componentSettings,
188
182
  };
189
183
  if (!manifest.components) {
@@ -199,9 +193,9 @@ export async function runCreateComponent({ type, name, }) {
199
193
  spinner.succeed(`Successfully created component "${chalk.cyan(componentName)}"!`);
200
194
  console.log(chalk.gray(`Component ID: ${componentId}`));
201
195
  console.log(chalk.gray(`Type: ${validatedType}`));
202
- console.log(chalk.gray(`Path: ${sanitizedName}/dist`));
203
- console.log(chalk.green(`\nYour component "${chalk.cyan(componentName)}" is ready!`));
204
- console.log(chalk.white(` cd ${sanitizedName}`));
196
+ console.log(chalk.gray(`Path: static/${componentName}/dist`));
197
+ console.log(chalk.green("\nšŸŽ‰ Your component is ready!"));
198
+ console.log(chalk.white(` cd static/${componentName}`));
205
199
  console.log(chalk.white(` npm run dev # Start development server`));
206
200
  console.log(chalk.white(` npm run build # Build for production`));
207
201
  }
@@ -2,12 +2,13 @@ import inquirer from "inquirer";
2
2
  import path from "node:path";
3
3
  import fs from "fs-extra";
4
4
  import { v4 as uuidv4 } from "uuid";
5
- import yaml from "js-yaml";
5
+ import { fileURLToPath } from "node:url";
6
6
  import ora from "ora";
7
7
  import chalk from "chalk";
8
8
  import { createApp } from "../api/requests.js";
9
9
  import { getManifest } from "../utils/components.utils.js";
10
- import { runCreateComponent } from "./create-component.js";
10
+ const __filename = fileURLToPath(import.meta.url);
11
+ const __dirname = path.dirname(__filename);
11
12
  function slugifyName(name) {
12
13
  const validPattern = /^[a-zA-Z0-9_-]+$/;
13
14
  if (!validPattern.test(name)) {
@@ -19,55 +20,44 @@ export async function runCreate({ name }) {
19
20
  let appName = name;
20
21
  if (!appName) {
21
22
  const answers = await inquirer.prompt([
22
- {
23
- type: "input",
24
- name: "name",
25
- message: "App name:",
26
- },
23
+ { type: "input", name: "name", message: "App name" },
27
24
  ]);
28
25
  appName = (answers.name || "").trim();
29
26
  }
30
27
  if (!appName) {
31
- throw new Error("Missing app name.");
28
+ throw new Error("Missing name.");
32
29
  }
33
30
  const slug = slugifyName(appName);
34
31
  const appId = uuidv4();
32
+ const componentId = uuidv4();
35
33
  const appDir = path.resolve(process.cwd(), slug);
36
- const componentName = `${slug}-component`;
37
34
  if (await fs.pathExists(appDir)) {
38
35
  throw new Error(`Already exists. ${chalk.yellow(slug)}`);
39
36
  }
40
37
  const spinner = ora(`Creating app "${chalk.cyan(appName)}"...`).start();
41
- const originalCwd = process.cwd();
42
38
  try {
43
39
  await fs.ensureDir(appDir);
44
- const initialManifest = {
45
- app: {
46
- id: appId,
47
- name: appName,
48
- description: "",
49
- },
50
- components: [],
51
- };
52
- await fs.writeFile(path.join(appDir, "manifest.yml"), yaml.dump(initialManifest, { indent: 2, lineWidth: -1, noRefs: true }), "utf-8");
53
- spinner.succeed(`App directory "${chalk.cyan(appName)}" created!`);
40
+ const templatesDir = path.join(__dirname, "..", "..", "src", "templates");
41
+ const manifestTemplate = await fs.readFile(path.join(templatesDir, "manifest.yml"), "utf-8");
42
+ const htmlTemplate = await fs.readFile(path.join(templatesDir, "index.html"), "utf-8");
43
+ const manifestContent = manifestTemplate
44
+ .replace(/{{appName}}/g, appName)
45
+ .replace(/{{appId}}/g, appId)
46
+ .replace(/{{componentId}}/g, componentId);
47
+ const htmlContent = htmlTemplate.replace(/{{appName}}/g, appName);
48
+ await fs.writeFile(path.join(appDir, "manifest.yml"), manifestContent);
49
+ await fs.writeFile(path.join(appDir, "index.html"), htmlContent);
50
+ const manifest = await getManifest(appDir);
51
+ await createApp(manifest);
52
+ spinner.succeed(`Successfully created "${chalk.cyan(appName)}" app!`);
54
53
  console.log(chalk.gray(`šŸ“ Location: ${appDir}`));
55
54
  console.log(chalk.gray(`App ID: ${appId}`));
56
- process.chdir(appDir);
57
- console.log(chalk.cyan(`\nAdding component "${componentName}"...`));
58
- await runCreateComponent({ name: componentName });
59
- spinner.start();
60
- spinner.text = `Registering app with Fireberry...`;
61
- await createApp(await getManifest());
62
- spinner.succeed(`App registered with Fireberry!`);
63
- console.log(chalk.green(`\nšŸŽ‰ Your app is ready!`));
64
- console.log(chalk.white(`\nNext steps:`));
55
+ console.log(chalk.green("\nšŸŽ‰ Your app is ready! Next steps:"));
65
56
  console.log(chalk.white(` cd ${slug}`));
66
- console.log(chalk.white(` fireberry push # Push to Fireberry`));
57
+ console.log(chalk.white(" # Start developing your Fireberry app"));
67
58
  }
68
59
  catch (error) {
69
60
  spinner.fail(`Failed to create app "${chalk.cyan(appName)}"`);
70
- process.chdir(originalCwd);
71
61
  throw error;
72
62
  }
73
63
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fireberry/cli",
3
- "version": "0.2.5-beta.1",
3
+ "version": "0.2.5",
4
4
  "description": "Fireberry CLI tool",
5
5
  "type": "module",
6
6
  "author": "",
@@ -41,8 +41,6 @@
41
41
  "access": "public"
42
42
  },
43
43
  "dependencies": {
44
- "@fireberry/ds": "^0.0.151",
45
- "@fireberry/sdk": "^0.0.5",
46
44
  "axios": "^1.12.2",
47
45
  "chalk": "^5.3.0",
48
46
  "commander": "^12.1.0",
@@ -15,13 +15,7 @@ const program = new Command();
15
15
  program
16
16
  .name("fireberry")
17
17
  .description("Fireberry developer CLI")
18
- .version(packageJson.version)
19
- .configureOutput({
20
- outputError: (str, write) => {
21
- const formatted = str.replace(/^error:/i, 'Error:');
22
- write(chalk.red(formatted));
23
- }
24
- });
18
+ .version(packageJson.version);
25
19
 
26
20
  program
27
21
  .command("init")
@@ -33,10 +27,11 @@ program
33
27
 
34
28
  program
35
29
  .command("create")
36
- .argument("[name]", "App name")
37
- .description("Create a new Fireberry app with a component")
38
- .action(async (name?: string) => {
39
- await runCreate({ name });
30
+ .argument("[name...]", "App name")
31
+ .description("Create a new Fireberry app")
32
+ .action(async (nameArgs?: string[]) => {
33
+ const name = nameArgs ? nameArgs.join("-") : undefined;
34
+ await runCreate({ name });
40
35
  });
41
36
 
42
37
  program
@@ -22,13 +22,6 @@ interface CreateComponentOptions {
22
22
 
23
23
  const VALID_COMPONENT_TYPES = Object.values(COMPONENT_TYPE);
24
24
 
25
- function sanitizeComponentName(name: string): string {
26
- return name
27
- .toLowerCase()
28
- .replace(/[^a-z0-9]+/g, "-")
29
- .replace(/^-+|-+$/g, "");
30
- }
31
-
32
25
  function validateComponentType(type: string): ComponentType {
33
26
  if (!VALID_COMPONENT_TYPES.includes(type as ComponentType)) {
34
27
  throw new Error(
@@ -163,8 +156,6 @@ export async function runCreateComponent({
163
156
 
164
157
  const validatedType = validateComponentType(componentType);
165
158
 
166
- const sanitizedName = sanitizeComponentName(componentName);
167
-
168
159
  const spinner = ora();
169
160
 
170
161
  try {
@@ -175,14 +166,15 @@ export async function runCreateComponent({
175
166
  );
176
167
  spinner.start();
177
168
 
178
- const componentDir = path.join(process.cwd(), componentName);
169
+ const componentDir = path.join(process.cwd(), "static", componentName);
179
170
  await fs.ensureDir(componentDir);
180
171
 
172
+ // Create Vite app with React template
181
173
  spinner.text = `Running npm create vite@latest...`;
182
174
  const viteResult = spawnSync(
183
- `npm create vite@latest ${sanitizedName} -- --template react --no-interactive`,
175
+ `npm create vite@latest ${componentName} -- --template react --no-interactive`,
184
176
  {
185
- cwd: process.cwd(),
177
+ cwd: path.join(process.cwd(), "static"),
186
178
  stdio: "inherit",
187
179
  shell: true,
188
180
  }
@@ -255,7 +247,7 @@ export async function runCreateComponent({
255
247
  type: validatedType,
256
248
  title: componentName,
257
249
  id: componentId,
258
- path: `${componentName}/dist`,
250
+ path: `static/${componentName}/dist`,
259
251
  settings: componentSettings,
260
252
  };
261
253
 
@@ -278,15 +270,11 @@ export async function runCreateComponent({
278
270
  spinner.succeed(
279
271
  `Successfully created component "${chalk.cyan(componentName)}"!`
280
272
  );
281
-
282
273
  console.log(chalk.gray(`Component ID: ${componentId}`));
283
274
  console.log(chalk.gray(`Type: ${validatedType}`));
284
- console.log(chalk.gray(`Path: ${sanitizedName}/dist`));
285
-
286
- console.log(
287
- chalk.green(`\nYour component "${chalk.cyan(componentName)}" is ready!`)
288
- );
289
- console.log(chalk.white(` cd ${sanitizedName}`));
275
+ console.log(chalk.gray(`Path: static/${componentName}/dist`));
276
+ console.log(chalk.green("\nšŸŽ‰ Your component is ready!"));
277
+ console.log(chalk.white(` cd static/${componentName}`));
290
278
  console.log(chalk.white(` npm run dev # Start development server`));
291
279
  console.log(chalk.white(` npm run build # Build for production`));
292
280
  } catch (error) {
@@ -2,12 +2,14 @@ import inquirer from "inquirer";
2
2
  import path from "node:path";
3
3
  import fs from "fs-extra";
4
4
  import { v4 as uuidv4 } from "uuid";
5
- import yaml from "js-yaml";
5
+ import { fileURLToPath } from "node:url";
6
6
  import ora from "ora";
7
7
  import chalk from "chalk";
8
8
  import { createApp } from "../api/requests.js";
9
9
  import { getManifest } from "../utils/components.utils.js";
10
- import { runCreateComponent } from "./create-component.js";
10
+
11
+ const __filename = fileURLToPath(import.meta.url);
12
+ const __dirname = path.dirname(__filename);
11
13
 
12
14
  interface CreateOptions {
13
15
  name?: string;
@@ -29,70 +31,59 @@ export async function runCreate({ name }: CreateOptions): Promise<void> {
29
31
 
30
32
  if (!appName) {
31
33
  const answers = await inquirer.prompt([
32
- {
33
- type: "input",
34
- name: "name",
35
- message: "App name:",
36
- },
34
+ { type: "input", name: "name", message: "App name" },
37
35
  ]);
38
36
  appName = (answers.name || "").trim();
39
37
  }
40
-
41
38
  if (!appName) {
42
- throw new Error("Missing app name.");
39
+ throw new Error("Missing name.");
43
40
  }
44
41
 
45
42
  const slug = slugifyName(appName);
46
43
  const appId = uuidv4();
44
+ const componentId = uuidv4();
47
45
  const appDir = path.resolve(process.cwd(), slug);
48
- const componentName = `${slug}-component`;
49
46
 
50
47
  if (await fs.pathExists(appDir)) {
51
48
  throw new Error(`Already exists. ${chalk.yellow(slug)}`);
52
49
  }
53
50
 
54
51
  const spinner = ora(`Creating app "${chalk.cyan(appName)}"...`).start();
55
- const originalCwd = process.cwd();
56
52
 
57
53
  try {
58
54
  await fs.ensureDir(appDir);
59
55
 
60
- const initialManifest = {
61
- app: {
62
- id: appId,
63
- name: appName,
64
- description: "",
65
- },
66
- components: [],
67
- };
68
-
69
- await fs.writeFile(
70
- path.join(appDir, "manifest.yml"),
71
- yaml.dump(initialManifest, { indent: 2, lineWidth: -1, noRefs: true }),
56
+ const templatesDir = path.join(__dirname, "..", "..", "src", "templates");
57
+ const manifestTemplate = await fs.readFile(
58
+ path.join(templatesDir, "manifest.yml"),
59
+ "utf-8"
60
+ );
61
+ const htmlTemplate = await fs.readFile(
62
+ path.join(templatesDir, "index.html"),
72
63
  "utf-8"
73
64
  );
74
65
 
75
- spinner.succeed(`App directory "${chalk.cyan(appName)}" created!`);
76
- console.log(chalk.gray(`šŸ“ Location: ${appDir}`));
77
- console.log(chalk.gray(`App ID: ${appId}`));
66
+ const manifestContent = manifestTemplate
67
+ .replace(/{{appName}}/g, appName)
68
+ .replace(/{{appId}}/g, appId)
69
+ .replace(/{{componentId}}/g, componentId);
78
70
 
79
- process.chdir(appDir);
71
+ const htmlContent = htmlTemplate.replace(/{{appName}}/g, appName);
80
72
 
81
- console.log(chalk.cyan(`\nAdding component "${componentName}"...`));
73
+ await fs.writeFile(path.join(appDir, "manifest.yml"), manifestContent);
74
+ await fs.writeFile(path.join(appDir, "index.html"), htmlContent);
75
+ const manifest = await getManifest(appDir);
82
76
 
83
- await runCreateComponent({ name: componentName });
84
- spinner.start();
85
- spinner.text = `Registering app with Fireberry...`;
86
- await createApp(await getManifest());
87
- spinner.succeed(`App registered with Fireberry!`);
77
+ await createApp(manifest);
88
78
 
89
- console.log(chalk.green(`\nšŸŽ‰ Your app is ready!`));
90
- console.log(chalk.white(`\nNext steps:`));
79
+ spinner.succeed(`Successfully created "${chalk.cyan(appName)}" app!`);
80
+ console.log(chalk.gray(`šŸ“ Location: ${appDir}`));
81
+ console.log(chalk.gray(`App ID: ${appId}`));
82
+ console.log(chalk.green("\nšŸŽ‰ Your app is ready! Next steps:"));
91
83
  console.log(chalk.white(` cd ${slug}`));
92
- console.log(chalk.white(` fireberry push # Push to Fireberry`));
84
+ console.log(chalk.white(" # Start developing your Fireberry app"));
93
85
  } catch (error) {
94
86
  spinner.fail(`Failed to create app "${chalk.cyan(appName)}"`);
95
- process.chdir(originalCwd);
96
87
  throw error;
97
88
  }
98
89
  }
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>{{appName}}</title>
8
+ </head>
9
+
10
+ <body>
11
+ <h1>Hello World</h1>
12
+ <p>Welcome to {{appName}}!</p>
13
+ </body>
14
+
15
+ </html>
@@ -0,0 +1,14 @@
1
+ app:
2
+ id: "{{appId}}"
3
+ name: "{{appName}}"
4
+ description: ""
5
+ components:
6
+ - type: record
7
+ title: my-first-component
8
+ id: "{{componentId}}"
9
+ path: static/comp/build
10
+ settings:
11
+ iconName: "related-single"
12
+ iconColor: "#7aae7f"
13
+ objectType: 0
14
+ height: "M"