@component-hook/create-app 1.4.0 → 1.4.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/index.mjs +71 -22
- package/package.json +1 -1
- package/template-react/README.md.art +1 -1
- package/template-vue/README.md.art +1 -1
package/dist/index.mjs
CHANGED
|
@@ -14,6 +14,11 @@ const DEFAULT_PROJECT_NAME = "basic-project";
|
|
|
14
14
|
const TEMPLATES = ["vue", "react"];
|
|
15
15
|
const GITHUB_ACTIONS = "GitHub Actions";
|
|
16
16
|
const GITLAB_CI = "GitLab CI";
|
|
17
|
+
const CI = [
|
|
18
|
+
"github-actions",
|
|
19
|
+
"gitlab-ci",
|
|
20
|
+
"none"
|
|
21
|
+
];
|
|
17
22
|
|
|
18
23
|
//#endregion
|
|
19
24
|
//#region src/utils.ts
|
|
@@ -56,19 +61,30 @@ function clearFolder(dir) {
|
|
|
56
61
|
const files = readdirSync(dir).filter((file) => file !== ".git");
|
|
57
62
|
return Promise.all(files.map((file) => remove(path.resolve(dir, file))));
|
|
58
63
|
}
|
|
64
|
+
function getCiArtContent(ci = "") {
|
|
65
|
+
const ciName = {
|
|
66
|
+
"github-actions": GITHUB_ACTIONS,
|
|
67
|
+
"gitlab-ci": GITLAB_CI
|
|
68
|
+
}[ci];
|
|
69
|
+
if (!ciName) return "";
|
|
70
|
+
return `- **CI/CD**: Integrates \`${ciName}\` for automated testing and deployment.`;
|
|
71
|
+
}
|
|
59
72
|
|
|
60
73
|
//#endregion
|
|
61
74
|
//#region src/prompts.ts
|
|
62
75
|
function builtinTemplate(template) {
|
|
63
76
|
return template && TEMPLATES.includes(template);
|
|
64
77
|
}
|
|
78
|
+
function checkCi(ci) {
|
|
79
|
+
return ci && CI.includes(ci);
|
|
80
|
+
}
|
|
65
81
|
function onCancel() {
|
|
66
82
|
throw new Error(`${colors.red("✖")} Operation cancelled`);
|
|
67
83
|
}
|
|
68
84
|
function styleTitle(title) {
|
|
69
85
|
return colors.bold(colors.magenta(title));
|
|
70
86
|
}
|
|
71
|
-
function operationPrompts({ targetDir, template }) {
|
|
87
|
+
function operationPrompts({ targetDir, template, ci }) {
|
|
72
88
|
return prompts([
|
|
73
89
|
{
|
|
74
90
|
type: targetDir ? null : "text",
|
|
@@ -78,11 +94,13 @@ function operationPrompts({ targetDir, template }) {
|
|
|
78
94
|
},
|
|
79
95
|
{
|
|
80
96
|
type: (nameAnswer) => {
|
|
81
|
-
|
|
97
|
+
const dir = nameAnswer ?? targetDir;
|
|
98
|
+
return existsSync(dir) && !isEmptyFolder(dir) ? "select" : null;
|
|
82
99
|
},
|
|
83
100
|
name: "overwrite",
|
|
84
101
|
message: (nameAnswer) => {
|
|
85
|
-
|
|
102
|
+
const dirName = nameAnswer ?? targetDir;
|
|
103
|
+
return styleTitle(`${dirName === "." ? "current directory" : `Target directory "${dirName}"`} is not empty. Please choose how to proceed:`);
|
|
86
104
|
},
|
|
87
105
|
initial: 0,
|
|
88
106
|
choices: [
|
|
@@ -109,11 +127,13 @@ function operationPrompts({ targetDir, template }) {
|
|
|
109
127
|
},
|
|
110
128
|
{
|
|
111
129
|
type: (_, { projectName: nameAnswer }) => {
|
|
112
|
-
return isValidPackageName(getProjectName(nameAnswer)) ? null : "text";
|
|
130
|
+
return isValidPackageName(getProjectName(nameAnswer ?? targetDir)) ? null : "text";
|
|
113
131
|
},
|
|
114
132
|
name: "packageName",
|
|
115
133
|
message: styleTitle("Package name:"),
|
|
116
|
-
initial: (_, { projectName: nameAnswer }) =>
|
|
134
|
+
initial: (_, { projectName: nameAnswer }) => {
|
|
135
|
+
return toValidPackageName(getProjectName(nameAnswer ?? targetDir));
|
|
136
|
+
},
|
|
117
137
|
validate: (name) => {
|
|
118
138
|
return isValidPackageName(name) || "Invalid package.json name";
|
|
119
139
|
}
|
|
@@ -130,6 +150,26 @@ function operationPrompts({ targetDir, template }) {
|
|
|
130
150
|
title: colors.blue("React"),
|
|
131
151
|
value: "react"
|
|
132
152
|
}]
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
type: checkCi(ci) ? null : "select",
|
|
156
|
+
name: "ci",
|
|
157
|
+
message: ci ? styleTitle(`${colors.red(ci)} isn't a valid CI/CD. Please choose from below:`) : styleTitle("Choose CI/CD:"),
|
|
158
|
+
choices: [
|
|
159
|
+
{
|
|
160
|
+
title: "GitHub Actions",
|
|
161
|
+
value: "github-actions"
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
title: "GitLab CI",
|
|
165
|
+
value: "gitlab-ci"
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
title: "None",
|
|
169
|
+
value: "none"
|
|
170
|
+
}
|
|
171
|
+
],
|
|
172
|
+
initial: 0
|
|
133
173
|
}
|
|
134
174
|
], { onCancel });
|
|
135
175
|
}
|
|
@@ -138,10 +178,7 @@ function operationPrompts({ targetDir, template }) {
|
|
|
138
178
|
//#region src/index.ts
|
|
139
179
|
const cwd = process.cwd();
|
|
140
180
|
const argv = minimist(process.argv.slice(2), {
|
|
141
|
-
default: {
|
|
142
|
-
gitlab: false,
|
|
143
|
-
help: false
|
|
144
|
-
},
|
|
181
|
+
default: { help: false },
|
|
145
182
|
alias: {
|
|
146
183
|
t: "template",
|
|
147
184
|
l: "gitlab",
|
|
@@ -153,6 +190,15 @@ const renameFiles = {
|
|
|
153
190
|
_gitignore: ".gitignore",
|
|
154
191
|
"_gitlab-ci.yml": ".gitlab-ci.yml"
|
|
155
192
|
};
|
|
193
|
+
const ciFilters = {
|
|
194
|
+
"github-actions": [".gitlab", "_gitlab-ci.yml"],
|
|
195
|
+
"gitlab-ci": [".github"],
|
|
196
|
+
none: [
|
|
197
|
+
".github",
|
|
198
|
+
".gitlab",
|
|
199
|
+
"_gitlab-ci.yml"
|
|
200
|
+
]
|
|
201
|
+
};
|
|
156
202
|
const helpMessage = `
|
|
157
203
|
Usage: create-component-hook [project name] [options]
|
|
158
204
|
|
|
@@ -161,7 +207,7 @@ With no arguments, start the CLI in interactive mode.
|
|
|
161
207
|
|
|
162
208
|
Options:
|
|
163
209
|
-t, --template [name] Choose a framework template
|
|
164
|
-
-
|
|
210
|
+
-c, --ci [name] Choose CI/CD (options: github-actions, gitlab-ci, none). Defaults to "none".
|
|
165
211
|
-h, --help Display this help message
|
|
166
212
|
|
|
167
213
|
Available templates:
|
|
@@ -175,11 +221,10 @@ async function writePackageJson(root, dir, packageName) {
|
|
|
175
221
|
pkg.name = packageName;
|
|
176
222
|
return writeFile(targetPath, `${JSON.stringify(pkg, null, 2)}\n`);
|
|
177
223
|
}
|
|
178
|
-
async function copyFolder(root, dir, packageName) {
|
|
179
|
-
const
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
});
|
|
224
|
+
async function copyFolder(root, dir, packageName, ci) {
|
|
225
|
+
const files = await readdir(dir);
|
|
226
|
+
const ignoreFiles = new Set(["package.json", ...ciFilters[ci] || ciFilters.none]);
|
|
227
|
+
const filterFiles = files.filter((file) => !ignoreFiles.has(file));
|
|
183
228
|
const rewriteOrCopyFile = (file) => {
|
|
184
229
|
const targetPath = path.join(root, renameFiles?.[file] ?? file);
|
|
185
230
|
const templatePath = path.join(dir, file);
|
|
@@ -188,7 +233,7 @@ async function copyFolder(root, dir, packageName) {
|
|
|
188
233
|
const replacedPath = targetPath.replace(".art", "");
|
|
189
234
|
const renderedResult = artTemplate(templatePath, {
|
|
190
235
|
projectName: name,
|
|
191
|
-
|
|
236
|
+
ciContent: getCiArtContent(ci)
|
|
192
237
|
});
|
|
193
238
|
ensureDirSync(path.dirname(replacedPath));
|
|
194
239
|
return writeFile(replacedPath, renderedResult);
|
|
@@ -207,13 +252,17 @@ async function createApp() {
|
|
|
207
252
|
}
|
|
208
253
|
const targetDir = formatTargetDir(argv._[0]);
|
|
209
254
|
const template = argv.t || argv.template;
|
|
255
|
+
const ci = argv.c || argv.ci;
|
|
210
256
|
const result = await operationPrompts({
|
|
211
257
|
targetDir,
|
|
212
|
-
template
|
|
258
|
+
template,
|
|
259
|
+
ci
|
|
213
260
|
});
|
|
214
|
-
const
|
|
261
|
+
const projectName = result.projectName ?? targetDir;
|
|
262
|
+
const packageName = result.packageName || getProjectName(projectName);
|
|
215
263
|
const framework = result.framework || template;
|
|
216
|
-
const
|
|
264
|
+
const ciName = result.ci || ci;
|
|
265
|
+
const root = path.join(cwd, projectName);
|
|
217
266
|
const pkgManager = getPkgManagerInfo()?.name ?? "npm";
|
|
218
267
|
const spinner = ora();
|
|
219
268
|
console.log();
|
|
@@ -224,14 +273,14 @@ async function createApp() {
|
|
|
224
273
|
const sharedDir = path.resolve(filePath, "../..", "template-shared");
|
|
225
274
|
const templateDir = path.resolve(filePath, "../..", `template-${framework}`);
|
|
226
275
|
Promise.all([
|
|
227
|
-
copyFolder(root, sharedDir, packageName),
|
|
228
|
-
copyFolder(root, templateDir, packageName),
|
|
276
|
+
copyFolder(root, sharedDir, packageName, ciName),
|
|
277
|
+
copyFolder(root, templateDir, packageName, ciName),
|
|
229
278
|
writePackageJson(root, templateDir, packageName),
|
|
230
279
|
new Promise((resolve) => setTimeout(resolve, 300))
|
|
231
280
|
]).then(() => {
|
|
232
281
|
const cdProjectName = path.relative(cwd, root);
|
|
233
282
|
const formattedCdProjectName = cdProjectName.includes(" ") ? `"${cdProjectName}"` : cdProjectName;
|
|
234
|
-
spinner.succeed(`${colors.green("Scaffolded project in")} ${root}`);
|
|
283
|
+
spinner.succeed(`${colors.green("Scaffolded project in")} ${colors.yellow(root)}`);
|
|
235
284
|
console.log(`\n${colors.green("Done. Now run:")}\n`);
|
|
236
285
|
console.log(colors.cyan(` cd ${formattedCdProjectName}`));
|
|
237
286
|
if (pkgManager === "yarn") {
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@ This project is built with [react](https://react.dev/) + [vite](https://vite.dev
|
|
|
9
9
|
- **Code Quality**: Enforces standards with [eslint](https://eslint.org/) and [prettier](https://prettier.io/), with [husky](https://www.npmjs.com/package/husky), [commitlint](https://commitlint.js.org/#/), and [lint-staged](https://github.com/okonet/lint-staged) for commit validation.
|
|
10
10
|
- **Testing**: Uses [vitest](https://vitest.dev/) + [testing-library](https://testing-library.com/) for unit testing and [playwright](https://playwright.dev/) for E2E testing.
|
|
11
11
|
- **Optimization**: Compresses CSS with [cssnano](https://cssnano.github.io/cssnano/), converts units with [postcss-pxtorem](https://www.npmjs.com/package/postcss-pxtorem), convert modern CSS into something most browsers can understand with [postcss-preset-env](https://www.npmjs.com/package/postcss-preset-env), and analyzes assets with [rollup-plugin-visualizer](https://github.com/btd/rollup-plugin-visualizer).
|
|
12
|
-
|
|
12
|
+
{{ciContent}}
|
|
13
13
|
|
|
14
14
|
## Code Features / Opinions
|
|
15
15
|
|
|
@@ -9,7 +9,7 @@ This project is built with [vue3](https://vuejs.org/) + [vite](https://vite.dev/
|
|
|
9
9
|
- **Code Quality**: Enforces standards with [eslint](https://eslint.org/) and [prettier](https://prettier.io/), with [husky](https://www.npmjs.com/package/husky), [commitlint](https://commitlint.js.org/#/), and [lint-staged](https://github.com/okonet/lint-staged) for commit validation.
|
|
10
10
|
- **Testing**: Uses [vitest](https://vitest.dev/) + [testing-library](https://testing-library.com/) for unit testing and [playwright](https://playwright.dev/) for E2E testing.
|
|
11
11
|
- **Optimization**: Compresses CSS with [cssnano](https://cssnano.github.io/cssnano/), converts units with [postcss-pxtorem](https://www.npmjs.com/package/postcss-pxtorem), convert modern CSS into something most browsers can understand with [postcss-preset-env](https://www.npmjs.com/package/postcss-preset-env), and analyzes assets with [rollup-plugin-visualizer](https://github.com/btd/rollup-plugin-visualizer).
|
|
12
|
-
|
|
12
|
+
{{ciContent}}
|
|
13
13
|
|
|
14
14
|
## Code Features / Opinions
|
|
15
15
|
|