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