@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.
- package/dist/bin/fireberry.js +5 -10
- package/dist/commands/create-component.js +8 -14
- package/dist/commands/create.js +21 -31
- package/package.json +1 -3
- package/src/bin/fireberry.ts +6 -11
- package/src/commands/create-component.ts +8 -20
- package/src/commands/create.ts +28 -37
- package/src/templates/index.html +15 -0
- package/src/templates/manifest.yml +14 -0
package/dist/bin/fireberry.js
CHANGED
|
@@ -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
|
|
34
|
-
.action(async (
|
|
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 ${
|
|
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:
|
|
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:
|
|
203
|
-
console.log(chalk.green(
|
|
204
|
-
console.log(chalk.white(` cd
|
|
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
|
}
|
package/dist/commands/create.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
|
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
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
},
|
|
50
|
-
|
|
51
|
-
};
|
|
52
|
-
await fs.writeFile(path.join(appDir, "manifest.yml"),
|
|
53
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
|
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",
|
package/src/bin/fireberry.ts
CHANGED
|
@@ -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
|
|
38
|
-
.action(async (
|
|
39
|
-
|
|
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 ${
|
|
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:
|
|
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:
|
|
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) {
|
package/src/commands/create.ts
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
|
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
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
-
|
|
76
|
-
|
|
77
|
-
|
|
66
|
+
const manifestContent = manifestTemplate
|
|
67
|
+
.replace(/{{appName}}/g, appName)
|
|
68
|
+
.replace(/{{appId}}/g, appId)
|
|
69
|
+
.replace(/{{componentId}}/g, componentId);
|
|
78
70
|
|
|
79
|
-
|
|
71
|
+
const htmlContent = htmlTemplate.replace(/{{appName}}/g, appName);
|
|
80
72
|
|
|
81
|
-
|
|
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
|
|
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
|
-
|
|
90
|
-
console.log(chalk.
|
|
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(
|
|
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"
|