@outwalk/create-firefly 0.15.0 → 0.16.0
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/index.js +207 -214
- package/package.json +5 -11
- package/templates/javascript/jsconfig.json.template +2 -0
- package/templates/javascript/package.json.template +1 -1
- package/templates/typescript/package.json.template +1 -1
- package/templates/typescript/tsconfig.json.template +3 -2
- package/templates/snippets/hono/define-platform.template +0 -2
- package/templates/snippets/hono/import-platform.template +0 -1
package/dist/index.js
CHANGED
|
@@ -1,231 +1,224 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import yargs from
|
|
3
|
-
import prompts from
|
|
4
|
-
import path from
|
|
5
|
-
import fs from
|
|
6
|
-
import chalk from
|
|
7
|
-
import { exec, spawnSync } from
|
|
8
|
-
import path$1 from
|
|
9
|
-
import url from
|
|
10
|
-
|
|
2
|
+
import yargs from "yargs-parser";
|
|
3
|
+
import prompts from "prompts";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import fs from "node:fs";
|
|
6
|
+
import chalk from "chalk";
|
|
7
|
+
import { exec, spawnSync } from "node:child_process";
|
|
8
|
+
import path$1 from "path";
|
|
9
|
+
import url from "url";
|
|
10
|
+
//#region src/utils/logging.js
|
|
11
11
|
const firefly = chalk.hex("#ADFF2F");
|
|
12
12
|
const logger = {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
log: (...message) => console.log(`${firefly("[firefly]")} - `, ...message),
|
|
14
|
+
warn: (...message) => console.log(`${chalk.yellow("[firefly]")} - `, ...message),
|
|
15
|
+
error: (...message) => console.log(`${chalk.red("[firefly]")} - `, ...message)
|
|
16
16
|
};
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (path.extname(originalPath) == ".template") {
|
|
77
|
-
fs.writeFileSync(newPath, render(fs.readFileSync(originalPath, "utf8")));
|
|
78
|
-
} else {
|
|
79
|
-
fs.writeFileSync(newPath, fs.readFileSync(originalPath));
|
|
80
|
-
}
|
|
81
|
-
} else if (stats.isDirectory()) {
|
|
82
|
-
TemplateBuilder.createDirectory(newPath);
|
|
83
|
-
TemplateBuilder.copyTemplate(originalPath, newPath, values);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region src/utils/template.js
|
|
19
|
+
var TemplateBuilder = class TemplateBuilder {
|
|
20
|
+
constructor(src, dest) {
|
|
21
|
+
this.src = src;
|
|
22
|
+
this.dest = dest;
|
|
23
|
+
this.values = {};
|
|
24
|
+
}
|
|
25
|
+
inject(marker, value) {
|
|
26
|
+
this.values[marker] = value;
|
|
27
|
+
return this;
|
|
28
|
+
}
|
|
29
|
+
snippet(marker, snippet) {
|
|
30
|
+
this.values[marker] = fs.readFileSync(snippet, "utf8");
|
|
31
|
+
return this;
|
|
32
|
+
}
|
|
33
|
+
build() {
|
|
34
|
+
TemplateBuilder.createDirectory(this.dest);
|
|
35
|
+
TemplateBuilder.copyTemplate(this.src, this.dest, this.values);
|
|
36
|
+
return this;
|
|
37
|
+
}
|
|
38
|
+
static createDirectory(directory) {
|
|
39
|
+
if (!fs.existsSync(directory)) fs.mkdirSync(directory, { recursive: true });
|
|
40
|
+
}
|
|
41
|
+
static deleteDirectory(directory) {
|
|
42
|
+
if (fs.existsSync(directory)) {
|
|
43
|
+
const files = fs.readdirSync(directory);
|
|
44
|
+
for (let file of files) {
|
|
45
|
+
const filepath = path.join(directory, file);
|
|
46
|
+
if (fs.statSync(filepath).isDirectory()) TemplateBuilder.deleteDirectory(filepath);
|
|
47
|
+
else fs.unlinkSync(filepath);
|
|
48
|
+
}
|
|
49
|
+
fs.rmdirSync(directory);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
static copyTemplate(src, dest, values) {
|
|
53
|
+
const filesToCreate = fs.readdirSync(src);
|
|
54
|
+
const render = (content) => {
|
|
55
|
+
const keys = Object.keys(values);
|
|
56
|
+
for (let key of keys) content = content.replace(new RegExp(`{{${key}}}`, "g"), values[key]);
|
|
57
|
+
return content.replace(/\n{3,}/g, "\n\n");
|
|
58
|
+
};
|
|
59
|
+
for (let file of filesToCreate) {
|
|
60
|
+
const originalPath = path.join(src, file);
|
|
61
|
+
if (file.endsWith(".template")) file = file.replace(/.template$/, "");
|
|
62
|
+
const newPath = path.join(dest, file);
|
|
63
|
+
const stats = fs.statSync(originalPath);
|
|
64
|
+
if (stats.isFile()) {
|
|
65
|
+
if (path.extname(originalPath) == ".template") fs.writeFileSync(newPath, render(fs.readFileSync(originalPath, "utf8")));
|
|
66
|
+
else fs.writeFileSync(newPath, fs.readFileSync(originalPath));
|
|
67
|
+
} else if (stats.isDirectory()) {
|
|
68
|
+
TemplateBuilder.createDirectory(newPath);
|
|
69
|
+
TemplateBuilder.copyTemplate(originalPath, newPath, values);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
//#endregion
|
|
75
|
+
//#region src/utils/dependencies.js
|
|
89
76
|
function installDependencies(dependencies, directory) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
77
|
+
return new Promise((resolve, reject) => {
|
|
78
|
+
logger.log("installing dependencies...");
|
|
79
|
+
const command = /^win/.test(process.platform) ? "npm.cmd" : "npm";
|
|
80
|
+
const spawnProcess = (command, args) => {
|
|
81
|
+
const { status, error } = spawnSync(command, args, {
|
|
82
|
+
cwd: directory,
|
|
83
|
+
stdio: "ignore"
|
|
84
|
+
});
|
|
85
|
+
if (status != 0) throw new Error("failed to install project dependencies.");
|
|
86
|
+
if (error) throw error;
|
|
87
|
+
};
|
|
88
|
+
try {
|
|
89
|
+
spawnProcess(command, ["install", "--save"].concat(dependencies));
|
|
90
|
+
resolve();
|
|
91
|
+
} catch (error) {
|
|
92
|
+
reject(error);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
105
95
|
}
|
|
106
96
|
function intitializeGitRepository(directory) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
97
|
+
return new Promise((resolve, reject) => {
|
|
98
|
+
logger.log("initializing git repository...");
|
|
99
|
+
try {
|
|
100
|
+
exec("git init", { cwd: directory });
|
|
101
|
+
resolve();
|
|
102
|
+
} catch {
|
|
103
|
+
reject(/* @__PURE__ */ new Error("failed to initialize the git repository."));
|
|
104
|
+
}
|
|
105
|
+
});
|
|
116
106
|
}
|
|
117
|
-
|
|
107
|
+
//#endregion
|
|
108
|
+
//#region src/utils/files.js
|
|
118
109
|
const Module = {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
110
|
+
__filename: (fileUrl) => {
|
|
111
|
+
return import.meta.url ? url.fileURLToPath(fileUrl) : __filename;
|
|
112
|
+
},
|
|
113
|
+
__dirname: (fileUrl) => {
|
|
114
|
+
return import.meta.url ? path$1.dirname(Module.__filename(fileUrl)) : __dirname;
|
|
115
|
+
}
|
|
125
116
|
};
|
|
126
|
-
|
|
117
|
+
//#endregion
|
|
118
|
+
//#region src/index.js
|
|
127
119
|
const args = yargs(process.argv.slice(2));
|
|
128
120
|
prompts.override({
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
121
|
+
name: args._[0],
|
|
122
|
+
language: args.l ?? args.language,
|
|
123
|
+
platform: args.p ?? args.platform
|
|
132
124
|
});
|
|
133
|
-
const express = { template: "express", dependencies: ["express"] };
|
|
134
|
-
const hono = { template: "hono", dependencies: ["hono", "@hono/node-server"] };
|
|
135
125
|
const questions = [
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
126
|
+
{
|
|
127
|
+
type: "text",
|
|
128
|
+
name: "name",
|
|
129
|
+
message: "Project name:",
|
|
130
|
+
validate: (name) => name != name.toLowerCase() ? "your project name must be lowercase." : true
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
type: "select",
|
|
134
|
+
name: "language",
|
|
135
|
+
message: "Select a language:",
|
|
136
|
+
choices: [{
|
|
137
|
+
title: "JavaScript",
|
|
138
|
+
value: "javascript"
|
|
139
|
+
}, {
|
|
140
|
+
title: "TypeScript",
|
|
141
|
+
value: "typescript"
|
|
142
|
+
}]
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
type: "select",
|
|
146
|
+
name: "platform",
|
|
147
|
+
message: "Select a platform:",
|
|
148
|
+
choices: [{
|
|
149
|
+
title: "Express",
|
|
150
|
+
value: JSON.stringify({
|
|
151
|
+
template: "express",
|
|
152
|
+
dependencies: ["express"]
|
|
153
|
+
})
|
|
154
|
+
}, {
|
|
155
|
+
title: "None",
|
|
156
|
+
value: null
|
|
157
|
+
}]
|
|
158
|
+
}
|
|
161
159
|
];
|
|
162
160
|
(async () => {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
if (!settings.useCurrentDirectory) {
|
|
226
|
-
console.log(firefly(` > cd ./${path.relative(process.cwd(), config.name)} `));
|
|
227
|
-
}
|
|
228
|
-
if (skipInstall) console.log(firefly(" > npm install"));
|
|
229
|
-
console.log(firefly(" > npm run dev"));
|
|
230
|
-
console.log("----------------------------------");
|
|
161
|
+
const config = await prompts(questions, { onCancel: () => process.exit() });
|
|
162
|
+
const skipInstall = args["skip-install"];
|
|
163
|
+
const skipGit = args["skip-git"];
|
|
164
|
+
const force = args["force"];
|
|
165
|
+
const platform = JSON.parse(config.platform);
|
|
166
|
+
const settings = { useCurrentDirectory: false };
|
|
167
|
+
const dependencies = ["@outwalk/firefly", ...platform?.dependencies ?? []];
|
|
168
|
+
if (config.language != "javascript") dependencies.push(config.language);
|
|
169
|
+
if (config.name == ".") {
|
|
170
|
+
if (!force && fs.readdirSync(config.name).length > 0) {
|
|
171
|
+
if (!(await prompts({
|
|
172
|
+
type: "confirm",
|
|
173
|
+
name: "continue",
|
|
174
|
+
message: "The current directory is not empty. Continue?",
|
|
175
|
+
initial: true
|
|
176
|
+
})).continue) return;
|
|
177
|
+
}
|
|
178
|
+
config.name = path.basename(process.cwd());
|
|
179
|
+
settings.useCurrentDirectory = true;
|
|
180
|
+
}
|
|
181
|
+
if (fs.existsSync(config.name)) {
|
|
182
|
+
if (force && !settings.useCurrentDirectory) TemplateBuilder.deleteDirectory(config.name);
|
|
183
|
+
else {
|
|
184
|
+
logger.error(`${config.name} already exists.`);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
console.log("\n");
|
|
189
|
+
logger.log(`creating ${config.name}...`);
|
|
190
|
+
const templatePath = path.join(Module.__dirname(import.meta.url), "../templates/", config.language);
|
|
191
|
+
const snippetPath = path.join(Module.__dirname(import.meta.url), "../templates/snippets");
|
|
192
|
+
const projectPath = !settings.useCurrentDirectory ? config.name : ".";
|
|
193
|
+
try {
|
|
194
|
+
const template = new TemplateBuilder(templatePath, projectPath);
|
|
195
|
+
template.inject("project-name", config.name);
|
|
196
|
+
template.inject("options", !platform ? "" : "{ platform }");
|
|
197
|
+
if (platform) {
|
|
198
|
+
template.snippet("import-platform", path.join(snippetPath, platform.template, "import-platform.template"));
|
|
199
|
+
template.snippet("define-platform", path.join(snippetPath, platform.template, "define-platform.template"));
|
|
200
|
+
} else {
|
|
201
|
+
template.inject("import-platform", "");
|
|
202
|
+
template.inject("define-platform", "");
|
|
203
|
+
}
|
|
204
|
+
template.build();
|
|
205
|
+
} catch (error) {
|
|
206
|
+
logger.error(error.message);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
try {
|
|
210
|
+
if (!skipInstall) await installDependencies(dependencies, projectPath);
|
|
211
|
+
if (!skipGit) await intitializeGitRepository(projectPath);
|
|
212
|
+
} catch (error) {
|
|
213
|
+
logger.error(error.message);
|
|
214
|
+
if (!settings.useCurrentDirectory) TemplateBuilder.deleteDirectory(config.name);
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
console.log("\n----------------------------------");
|
|
218
|
+
console.log("Get started with your new project!\n");
|
|
219
|
+
if (!settings.useCurrentDirectory) console.log(firefly(` > cd ./${path.relative(process.cwd(), config.name)} `));
|
|
220
|
+
if (skipInstall) console.log(firefly(" > npm install"));
|
|
221
|
+
console.log(firefly(" > npm run dev"));
|
|
222
|
+
console.log("----------------------------------");
|
|
231
223
|
})();
|
|
224
|
+
//#endregion
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@outwalk/create-firefly",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.16.0",
|
|
5
5
|
"description": "Firefly - a modern scalable web framework.",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
@@ -13,13 +13,12 @@
|
|
|
13
13
|
"create-firefly": "dist/index.js"
|
|
14
14
|
},
|
|
15
15
|
"scripts": {
|
|
16
|
-
"build": "
|
|
16
|
+
"build": "rolldown -c",
|
|
17
17
|
"lint": "eslint src",
|
|
18
18
|
"prepublishOnly": "npm run lint && npm run build"
|
|
19
19
|
},
|
|
20
20
|
"keywords": [
|
|
21
21
|
"express",
|
|
22
|
-
"hono",
|
|
23
22
|
"decorators",
|
|
24
23
|
"project",
|
|
25
24
|
"generator",
|
|
@@ -48,13 +47,8 @@
|
|
|
48
47
|
},
|
|
49
48
|
"devDependencies": {
|
|
50
49
|
"@eslint/js": "^10.0.1",
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"esbuild": "^0.28.0",
|
|
55
|
-
"eslint": "^10.2.0",
|
|
56
|
-
"globals": "^17.4.0",
|
|
57
|
-
"rollup": "^4.60.1",
|
|
58
|
-
"rollup-plugin-esbuild": "^6.2.1"
|
|
50
|
+
"eslint": "^10.10.0",
|
|
51
|
+
"globals": "^17.12.0",
|
|
52
|
+
"rolldown": "^1.2.8"
|
|
59
53
|
}
|
|
60
54
|
}
|
|
@@ -7,10 +7,11 @@
|
|
|
7
7
|
"useDefineForClassFields": true,
|
|
8
8
|
|
|
9
9
|
/* syntax */
|
|
10
|
-
"target": "
|
|
10
|
+
"target": "ES2024",
|
|
11
11
|
"module": "ESNext",
|
|
12
|
-
"lib": ["
|
|
12
|
+
"lib": ["ES2024"],
|
|
13
13
|
"jsx": "preserve",
|
|
14
|
+
"types": ["node"],
|
|
14
15
|
"skipLibCheck": true,
|
|
15
16
|
|
|
16
17
|
/* bundler mode */
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import { HonoPlatform } from "@outwalk/firefly/hono";
|