@lightfish/cli 0.0.2 → 0.0.4

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.
@@ -4,9 +4,9 @@
4
4
  import cac from "cac";
5
5
 
6
6
  // src/commands/create.ts
7
- import path3 from "path";
7
+ import path4 from "path";
8
8
  import { execa as execa2 } from "execa";
9
- import fs3 from "fs-extra";
9
+ import fs4 from "fs-extra";
10
10
  import prompts3 from "prompts";
11
11
 
12
12
  // src/utils/download-template.ts
@@ -14,9 +14,8 @@ import path from "path";
14
14
  import { tmpdir } from "os";
15
15
  import { randomUUID } from "crypto";
16
16
  import { execa } from "execa";
17
- import degit from "degit";
18
17
  import fs from "fs-extra";
19
- function parseDegitRepo(repo) {
18
+ function parseRepo(repo) {
20
19
  const [repoPart, branch] = repo.split("#");
21
20
  let url;
22
21
  if (repoPart.startsWith("http://") || repoPart.startsWith("https://")) {
@@ -26,7 +25,7 @@ function parseDegitRepo(repo) {
26
25
  } else {
27
26
  throw new Error(`\u65E0\u6CD5\u89E3\u6790\u4ED3\u5E93\u5730\u5740: ${repo}`);
28
27
  }
29
- return { url, branch };
28
+ return { url, branch: branch || void 0 };
30
29
  }
31
30
  async function gitClone(url, branch, targetDir) {
32
31
  const tmpDir = path.join(tmpdir(), `lightfish-template-${randomUUID()}`);
@@ -56,25 +55,10 @@ async function gitClone(url, branch, targetDir) {
56
55
  }
57
56
  async function downloadTemplate(repo, targetDir) {
58
57
  await fs.ensureDir(targetDir);
59
- const emitter = degit(repo, {
60
- cache: false,
61
- // 禁用缓存,避免使用损坏的本地缓存
62
- force: true,
63
- verbose: true
64
- // 开启详细日志,方便调试
65
- });
66
- try {
67
- console.log(`\u6B63\u5728\u901A\u8FC7 degit \u62C9\u53D6\u6A21\u677F: ${repo}`);
68
- await emitter.clone(targetDir);
69
- console.log("degit \u62C9\u53D6\u5B8C\u6210");
70
- } catch (error) {
71
- const detail = error instanceof Error ? error.message : String(error);
72
- await fs.emptyDir(targetDir);
73
- const { url, branch } = parseDegitRepo(repo);
74
- console.log(`\u6B63\u5728\u901A\u8FC7 git clone \u62C9\u53D6\u6A21\u677F: ${url}${branch ? ` (\u5206\u652F: ${branch})` : ""}`);
75
- await gitClone(url, branch, targetDir);
76
- console.log("git clone \u62C9\u53D6\u5B8C\u6210");
77
- }
58
+ const { url, branch } = parseRepo(repo);
59
+ console.log(`\u6B63\u5728\u62C9\u53D6\u6A21\u677F: ${url}${branch ? ` (\u5206\u652F: ${branch})` : ""}`);
60
+ await gitClone(url, branch, targetDir);
61
+ console.log("\u6A21\u677F\u62C9\u53D6\u5B8C\u6210");
78
62
  const gitDir = path.join(targetDir, ".git");
79
63
  if (await fs.pathExists(gitDir)) {
80
64
  await fs.remove(gitDir);
@@ -147,6 +131,63 @@ function toPackageName(projectName) {
147
131
  return projectName.trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
148
132
  }
149
133
 
134
+ // src/utils/replace-token.ts
135
+ import path3 from "path";
136
+ import fs3 from "fs-extra";
137
+ var SKIP_DIRS = /* @__PURE__ */ new Set([
138
+ ".git",
139
+ "node_modules",
140
+ "dist",
141
+ ".cache",
142
+ "coverage"
143
+ ]);
144
+ var SKIP_EXTS = /* @__PURE__ */ new Set([
145
+ ".png",
146
+ ".jpg",
147
+ ".jpeg",
148
+ ".gif",
149
+ ".svg",
150
+ ".ico",
151
+ ".webp",
152
+ ".woff",
153
+ ".woff2",
154
+ ".ttf",
155
+ ".eot",
156
+ ".otf",
157
+ ".mp4",
158
+ ".webm",
159
+ ".mp3",
160
+ ".wav",
161
+ ".zip",
162
+ ".gz",
163
+ ".tar",
164
+ ".7z",
165
+ ".lock"
166
+ ]);
167
+ async function replaceToken(targetDir, token, value) {
168
+ const entries = await fs3.readdir(targetDir);
169
+ for (const entry of entries) {
170
+ const fullPath = path3.join(targetDir, entry);
171
+ const stat = await fs3.stat(fullPath);
172
+ if (stat.isDirectory()) {
173
+ if (SKIP_DIRS.has(entry)) continue;
174
+ await replaceToken(fullPath, token, value);
175
+ continue;
176
+ }
177
+ const ext = path3.extname(entry).toLowerCase();
178
+ if (SKIP_EXTS.has(ext)) continue;
179
+ try {
180
+ const content = await fs3.readFile(fullPath, "utf8");
181
+ if (content.includes(token)) {
182
+ const replaced = content.replaceAll(token, value);
183
+ await fs3.writeFile(fullPath, replaced, "utf8");
184
+ console.log(` [replace] ${entry}`);
185
+ }
186
+ } catch {
187
+ }
188
+ }
189
+ }
190
+
150
191
  // src/utils/resolve-template.ts
151
192
  import prompts2 from "prompts";
152
193
 
@@ -217,13 +258,13 @@ async function resolveTemplateRepo(options) {
217
258
 
218
259
  // src/commands/create.ts
219
260
  async function patchPackageJsonName(targetDir, projectName) {
220
- const packageJsonPath = path3.join(targetDir, "package.json");
221
- if (!await fs3.pathExists(packageJsonPath)) {
261
+ const packageJsonPath = path4.join(targetDir, "package.json");
262
+ if (!await fs4.pathExists(packageJsonPath)) {
222
263
  throw new Error("\u6A21\u677F\u7F3A\u5C11 package.json");
223
264
  }
224
- const packageJson = await fs3.readJson(packageJsonPath);
265
+ const packageJson = await fs4.readJson(packageJsonPath);
225
266
  packageJson.name = toPackageName(projectName);
226
- await fs3.writeJson(packageJsonPath, packageJson, { spaces: 2 });
267
+ await fs4.writeJson(packageJsonPath, packageJson, { spaces: 2 });
227
268
  }
228
269
  async function resolveCreateOptions(options) {
229
270
  const cwd = options.cwd ?? process.cwd();
@@ -310,6 +351,9 @@ async function createProject(options = {}) {
310
351
  console.log("[create] \u5F00\u59CB\u4FEE\u6539 package.json...");
311
352
  await patchPackageJsonName(resolvedOptions.targetDir, resolvedOptions.projectName);
312
353
  console.log("[create] package.json \u4FEE\u6539\u5B8C\u6210");
354
+ console.log("[create] \u5F00\u59CB\u66FF\u6362\u9879\u76EE\u540D\u5360\u4F4D\u7B26...");
355
+ await replaceToken(resolvedOptions.targetDir, "__PROJECT_NAME__", resolvedOptions.projectName);
356
+ console.log("[create] \u5360\u4F4D\u7B26\u66FF\u6362\u5B8C\u6210");
313
357
  console.log("[create] \u5F00\u59CB\u5B89\u88C5\u4F9D\u8D56...");
314
358
  await maybeInstall(resolvedOptions);
315
359
  console.log("[create] \u4F9D\u8D56\u5B89\u88C5\u5B8C\u6210");
@@ -320,28 +364,28 @@ async function createProject(options = {}) {
320
364
  }
321
365
 
322
366
  // src/utils/package-info.ts
323
- import fs4 from "fs";
324
- import path4 from "path";
367
+ import fs5 from "fs";
368
+ import path5 from "path";
325
369
  import { fileURLToPath } from "url";
326
- var dirname = path4.dirname(fileURLToPath(import.meta.url));
370
+ var dirname = path5.dirname(fileURLToPath(import.meta.url));
327
371
  function readPackageVersion() {
328
372
  const packageJsonPathCandidates = [
329
373
  // 源码模式:src/utils/package-info.ts -> packages/cli/package.json
330
- path4.resolve(dirname, "../../package.json"),
374
+ path5.resolve(dirname, "../../package.json"),
331
375
  // 构建产物模式:dist/lightfish.js -> packages/cli/package.json
332
- path4.resolve(dirname, "../package.json")
376
+ path5.resolve(dirname, "../package.json")
333
377
  ];
334
- const packageJsonPath = packageJsonPathCandidates.find((candidate) => fs4.existsSync(candidate));
378
+ const packageJsonPath = packageJsonPathCandidates.find((candidate) => fs5.existsSync(candidate));
335
379
  if (!packageJsonPath) {
336
380
  return "0.0.0";
337
381
  }
338
- const packageJson = JSON.parse(fs4.readFileSync(packageJsonPath, "utf8"));
382
+ const packageJson = JSON.parse(fs5.readFileSync(packageJsonPath, "utf8"));
339
383
  return packageJson.version ?? "0.0.0";
340
384
  }
341
385
 
342
386
  // src/create-lightfish.ts
343
387
  var cli = cac("create-lightfish");
344
- cli.command("[projectName]", "\u521B\u5EFA Lightfish React Vite \u9879\u76EE").option("--pm <pm>", "\u5305\u7BA1\u7406\u5668\uFF1Anpm\u3001yarn\u3001pnpm\u3001bun", { default: "pnpm" }).option("--template <id>", "\u5185\u7F6E\u6A21\u677F id\uFF0C\u4F8B\u5982 react-vite").option("--template-repo <repo>", "\u76F4\u63A5\u6307\u5B9A degit \u6E90\uFF0C\u5982 QGtiger/template-vite-server#main\uFF08\u4F18\u5148\u4E8E --template\uFF09").option("--skip-install", "\u8DF3\u8FC7\u4F9D\u8D56\u5B89\u88C5").option("--git", "\u521B\u5EFA\u540E\u521D\u59CB\u5316 git").option("-y, --yes", "\u4F7F\u7528\u9ED8\u8BA4\u9009\u9879\u5E76\u8DF3\u8FC7\u786E\u8BA4").action(async (projectName, options) => {
388
+ cli.command("[projectName]", "\u521B\u5EFA Lightfish React Vite \u9879\u76EE").option("--pm <pm>", "\u5305\u7BA1\u7406\u5668\uFF1Anpm\u3001yarn\u3001pnpm\u3001bun", { default: "pnpm" }).option("--template <id>", "\u5185\u7F6E\u6A21\u677F id\uFF0C\u4F8B\u5982 react-vite").option("--template-repo <repo>", "\u76F4\u63A5\u6307\u5B9A git \u4ED3\u5E93\u6E90\uFF0C\u5982 QGtiger/template-vite-server#main\uFF08\u4F18\u5148\u4E8E --template\uFF09").option("--skip-install", "\u8DF3\u8FC7\u4F9D\u8D56\u5B89\u88C5").option("--git", "\u521B\u5EFA\u540E\u521D\u59CB\u5316 git").option("-y, --yes", "\u4F7F\u7528\u9ED8\u8BA4\u9009\u9879\u5E76\u8DF3\u8FC7\u786E\u8BA4").action(async (projectName, options) => {
345
389
  try {
346
390
  const packageManager = options.pm ?? "pnpm";
347
391
  if (!isPackageManager(packageManager)) {
package/dist/lightfish.js CHANGED
@@ -5,9 +5,9 @@ import cac from "cac";
5
5
  import { execa as execa3 } from "execa";
6
6
 
7
7
  // src/commands/create.ts
8
- import path3 from "path";
8
+ import path4 from "path";
9
9
  import { execa as execa2 } from "execa";
10
- import fs3 from "fs-extra";
10
+ import fs4 from "fs-extra";
11
11
  import prompts3 from "prompts";
12
12
 
13
13
  // src/utils/download-template.ts
@@ -15,9 +15,8 @@ import path from "path";
15
15
  import { tmpdir } from "os";
16
16
  import { randomUUID } from "crypto";
17
17
  import { execa } from "execa";
18
- import degit from "degit";
19
18
  import fs from "fs-extra";
20
- function parseDegitRepo(repo) {
19
+ function parseRepo(repo) {
21
20
  const [repoPart, branch] = repo.split("#");
22
21
  let url;
23
22
  if (repoPart.startsWith("http://") || repoPart.startsWith("https://")) {
@@ -27,7 +26,7 @@ function parseDegitRepo(repo) {
27
26
  } else {
28
27
  throw new Error(`\u65E0\u6CD5\u89E3\u6790\u4ED3\u5E93\u5730\u5740: ${repo}`);
29
28
  }
30
- return { url, branch };
29
+ return { url, branch: branch || void 0 };
31
30
  }
32
31
  async function gitClone(url, branch, targetDir) {
33
32
  const tmpDir = path.join(tmpdir(), `lightfish-template-${randomUUID()}`);
@@ -57,25 +56,10 @@ async function gitClone(url, branch, targetDir) {
57
56
  }
58
57
  async function downloadTemplate(repo, targetDir) {
59
58
  await fs.ensureDir(targetDir);
60
- const emitter = degit(repo, {
61
- cache: false,
62
- // 禁用缓存,避免使用损坏的本地缓存
63
- force: true,
64
- verbose: true
65
- // 开启详细日志,方便调试
66
- });
67
- try {
68
- console.log(`\u6B63\u5728\u901A\u8FC7 degit \u62C9\u53D6\u6A21\u677F: ${repo}`);
69
- await emitter.clone(targetDir);
70
- console.log("degit \u62C9\u53D6\u5B8C\u6210");
71
- } catch (error) {
72
- const detail = error instanceof Error ? error.message : String(error);
73
- await fs.emptyDir(targetDir);
74
- const { url, branch } = parseDegitRepo(repo);
75
- console.log(`\u6B63\u5728\u901A\u8FC7 git clone \u62C9\u53D6\u6A21\u677F: ${url}${branch ? ` (\u5206\u652F: ${branch})` : ""}`);
76
- await gitClone(url, branch, targetDir);
77
- console.log("git clone \u62C9\u53D6\u5B8C\u6210");
78
- }
59
+ const { url, branch } = parseRepo(repo);
60
+ console.log(`\u6B63\u5728\u62C9\u53D6\u6A21\u677F: ${url}${branch ? ` (\u5206\u652F: ${branch})` : ""}`);
61
+ await gitClone(url, branch, targetDir);
62
+ console.log("\u6A21\u677F\u62C9\u53D6\u5B8C\u6210");
79
63
  const gitDir = path.join(targetDir, ".git");
80
64
  if (await fs.pathExists(gitDir)) {
81
65
  await fs.remove(gitDir);
@@ -148,6 +132,63 @@ function toPackageName(projectName) {
148
132
  return projectName.trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
149
133
  }
150
134
 
135
+ // src/utils/replace-token.ts
136
+ import path3 from "path";
137
+ import fs3 from "fs-extra";
138
+ var SKIP_DIRS = /* @__PURE__ */ new Set([
139
+ ".git",
140
+ "node_modules",
141
+ "dist",
142
+ ".cache",
143
+ "coverage"
144
+ ]);
145
+ var SKIP_EXTS = /* @__PURE__ */ new Set([
146
+ ".png",
147
+ ".jpg",
148
+ ".jpeg",
149
+ ".gif",
150
+ ".svg",
151
+ ".ico",
152
+ ".webp",
153
+ ".woff",
154
+ ".woff2",
155
+ ".ttf",
156
+ ".eot",
157
+ ".otf",
158
+ ".mp4",
159
+ ".webm",
160
+ ".mp3",
161
+ ".wav",
162
+ ".zip",
163
+ ".gz",
164
+ ".tar",
165
+ ".7z",
166
+ ".lock"
167
+ ]);
168
+ async function replaceToken(targetDir, token, value) {
169
+ const entries = await fs3.readdir(targetDir);
170
+ for (const entry of entries) {
171
+ const fullPath = path3.join(targetDir, entry);
172
+ const stat = await fs3.stat(fullPath);
173
+ if (stat.isDirectory()) {
174
+ if (SKIP_DIRS.has(entry)) continue;
175
+ await replaceToken(fullPath, token, value);
176
+ continue;
177
+ }
178
+ const ext = path3.extname(entry).toLowerCase();
179
+ if (SKIP_EXTS.has(ext)) continue;
180
+ try {
181
+ const content = await fs3.readFile(fullPath, "utf8");
182
+ if (content.includes(token)) {
183
+ const replaced = content.replaceAll(token, value);
184
+ await fs3.writeFile(fullPath, replaced, "utf8");
185
+ console.log(` [replace] ${entry}`);
186
+ }
187
+ } catch {
188
+ }
189
+ }
190
+ }
191
+
151
192
  // src/utils/resolve-template.ts
152
193
  import prompts2 from "prompts";
153
194
 
@@ -218,13 +259,13 @@ async function resolveTemplateRepo(options) {
218
259
 
219
260
  // src/commands/create.ts
220
261
  async function patchPackageJsonName(targetDir, projectName) {
221
- const packageJsonPath = path3.join(targetDir, "package.json");
222
- if (!await fs3.pathExists(packageJsonPath)) {
262
+ const packageJsonPath = path4.join(targetDir, "package.json");
263
+ if (!await fs4.pathExists(packageJsonPath)) {
223
264
  throw new Error("\u6A21\u677F\u7F3A\u5C11 package.json");
224
265
  }
225
- const packageJson = await fs3.readJson(packageJsonPath);
266
+ const packageJson = await fs4.readJson(packageJsonPath);
226
267
  packageJson.name = toPackageName(projectName);
227
- await fs3.writeJson(packageJsonPath, packageJson, { spaces: 2 });
268
+ await fs4.writeJson(packageJsonPath, packageJson, { spaces: 2 });
228
269
  }
229
270
  async function resolveCreateOptions(options) {
230
271
  const cwd = options.cwd ?? process.cwd();
@@ -311,6 +352,9 @@ async function createProject(options = {}) {
311
352
  console.log("[create] \u5F00\u59CB\u4FEE\u6539 package.json...");
312
353
  await patchPackageJsonName(resolvedOptions.targetDir, resolvedOptions.projectName);
313
354
  console.log("[create] package.json \u4FEE\u6539\u5B8C\u6210");
355
+ console.log("[create] \u5F00\u59CB\u66FF\u6362\u9879\u76EE\u540D\u5360\u4F4D\u7B26...");
356
+ await replaceToken(resolvedOptions.targetDir, "__PROJECT_NAME__", resolvedOptions.projectName);
357
+ console.log("[create] \u5360\u4F4D\u7B26\u66FF\u6362\u5B8C\u6210");
314
358
  console.log("[create] \u5F00\u59CB\u5B89\u88C5\u4F9D\u8D56...");
315
359
  await maybeInstall(resolvedOptions);
316
360
  console.log("[create] \u4F9D\u8D56\u5B89\u88C5\u5B8C\u6210");
@@ -321,22 +365,22 @@ async function createProject(options = {}) {
321
365
  }
322
366
 
323
367
  // src/utils/package-info.ts
324
- import fs4 from "fs";
325
- import path4 from "path";
368
+ import fs5 from "fs";
369
+ import path5 from "path";
326
370
  import { fileURLToPath } from "url";
327
- var dirname = path4.dirname(fileURLToPath(import.meta.url));
371
+ var dirname = path5.dirname(fileURLToPath(import.meta.url));
328
372
  function readPackageVersion() {
329
373
  const packageJsonPathCandidates = [
330
374
  // 源码模式:src/utils/package-info.ts -> packages/cli/package.json
331
- path4.resolve(dirname, "../../package.json"),
375
+ path5.resolve(dirname, "../../package.json"),
332
376
  // 构建产物模式:dist/lightfish.js -> packages/cli/package.json
333
- path4.resolve(dirname, "../package.json")
377
+ path5.resolve(dirname, "../package.json")
334
378
  ];
335
- const packageJsonPath = packageJsonPathCandidates.find((candidate) => fs4.existsSync(candidate));
379
+ const packageJsonPath = packageJsonPathCandidates.find((candidate) => fs5.existsSync(candidate));
336
380
  if (!packageJsonPath) {
337
381
  return "0.0.0";
338
382
  }
339
- const packageJson = JSON.parse(fs4.readFileSync(packageJsonPath, "utf8"));
383
+ const packageJson = JSON.parse(fs5.readFileSync(packageJsonPath, "utf8"));
340
384
  return packageJson.version ?? "0.0.0";
341
385
  }
342
386
 
@@ -349,7 +393,7 @@ async function runBuild() {
349
393
  stdio: "inherit"
350
394
  });
351
395
  }
352
- cli.command("create [projectName]", "\u521B\u5EFA Lightfish React Vite \u9879\u76EE").option("--pm <pm>", "\u5305\u7BA1\u7406\u5668\uFF1Anpm\u3001yarn\u3001pnpm\u3001bun", { default: "pnpm" }).option("--template <id>", "\u5185\u7F6E\u6A21\u677F id\uFF0C\u4F8B\u5982 react-vite").option("--template-repo <repo>", "\u76F4\u63A5\u6307\u5B9A degit \u6E90\uFF0C\u5982 QGtiger/template-vite-server#main\uFF08\u4F18\u5148\u4E8E --template\uFF09").option("--skip-install", "\u8DF3\u8FC7\u4F9D\u8D56\u5B89\u88C5").option("--git", "\u521B\u5EFA\u540E\u521D\u59CB\u5316 git").option("-y, --yes", "\u4F7F\u7528\u9ED8\u8BA4\u9009\u9879\u5E76\u8DF3\u8FC7\u786E\u8BA4").action(async (projectName, options) => {
396
+ cli.command("create [projectName]", "\u521B\u5EFA Lightfish React Vite \u9879\u76EE").option("--pm <pm>", "\u5305\u7BA1\u7406\u5668\uFF1Anpm\u3001yarn\u3001pnpm\u3001bun", { default: "pnpm" }).option("--template <id>", "\u5185\u7F6E\u6A21\u677F id\uFF0C\u4F8B\u5982 react-vite").option("--template-repo <repo>", "\u76F4\u63A5\u6307\u5B9A git \u4ED3\u5E93\u6E90\uFF0C\u5982 QGtiger/template-vite-server#main\uFF08\u4F18\u5148\u4E8E --template\uFF09").option("--skip-install", "\u8DF3\u8FC7\u4F9D\u8D56\u5B89\u88C5").option("--git", "\u521B\u5EFA\u540E\u521D\u59CB\u5316 git").option("-y, --yes", "\u4F7F\u7528\u9ED8\u8BA4\u9009\u9879\u5E76\u8DF3\u8FC7\u786E\u8BA4").action(async (projectName, options) => {
353
397
  try {
354
398
  const packageManager = options.pm ?? "pnpm";
355
399
  if (!isPackageManager(packageManager)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightfish/cli",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -19,7 +19,6 @@
19
19
  },
20
20
  "dependencies": {
21
21
  "cac": "^7.0.0",
22
- "degit": "^2.8.4",
23
22
  "execa": "^9.6.1",
24
23
  "fs-extra": "^11.3.5",
25
24
  "prompts": "^2.4.2"