@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 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
- return existsSync(nameAnswer) && !isEmptyFolder(nameAnswer) ? "select" : null;
97
+ const dir = nameAnswer ?? targetDir;
98
+ return existsSync(dir) && !isEmptyFolder(dir) ? "select" : null;
82
99
  },
83
100
  name: "overwrite",
84
101
  message: (nameAnswer) => {
85
- return styleTitle(`${nameAnswer === "." ? "current directory" : `Target directory "${targetDir}"`} is not empty. Please choose how to proceed:`);
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 }) => toValidPackageName(getProjectName(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
- -l, --gitlab Use Gitlab CI/CD, default is Github CI/CD
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 isGitlab = argv.l || argv.gitlab;
180
- const filterFiles = (await readdir(dir)).filter((file) => {
181
- return file !== "package.json" && file !== (isGitlab ? ".github" : ".gitlab") && file !== (isGitlab ? "" : "_gitlab-ci.yml");
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
- gitRepository: isGitlab ? GITLAB_CI : GITHUB_ACTIONS
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 packageName = result.packageName || getProjectName(result.projectName);
261
+ const projectName = result.projectName ?? targetDir;
262
+ const packageName = result.packageName || getProjectName(projectName);
215
263
  const framework = result.framework || template;
216
- const root = path.join(cwd, result.projectName);
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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@component-hook/create-app",
3
3
  "type": "module",
4
- "version": "1.4.0",
4
+ "version": "1.4.1",
5
5
  "description": "Scaffolding a basic typescript project",
6
6
  "author": "Tzuyi",
7
7
  "license": "MIT",
@@ -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
- - **CI/CD**: Integrates `{{gitRepository}}` for automated testing and deployment.
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
- - **CI/CD**: Integrates `{{gitRepository}}` for automated testing and deployment.
12
+ {{ciContent}}
13
13
 
14
14
  ## Code Features / Opinions
15
15