@icebreakers/monorepo 3.2.1 → 3.2.3

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/cli.cjs CHANGED
@@ -1,4 +1,4 @@
1
- const require_upgrade = require('./upgrade-CEd5cMQ-.cjs');
1
+ const require_upgrade = require('./upgrade-vYYDUbQa.cjs');
2
2
  let node_process = require("node:process");
3
3
  node_process = require_upgrade.__toESM(node_process);
4
4
  let _icebreakers_monorepo_templates = require("@icebreakers/monorepo-templates");
package/dist/cli.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { C as syncSkills, F as generateAgenticTemplate, I as generateAgenticTemplates, L as loadAgenticTasks, M as resolveCommandConfig, N as createTimestampFolderName, O as name, P as defaultAgenticBaseDir, R as logger, S as skillTargets, b as cleanProjects, c as getCreateChoices, i as init, k as version, n as syncNpmMirror, o as createNewProject, r as setVscodeBinaryMirror, s as defaultTemplate, t as upgradeMonorepo } from "./upgrade-Zbej0CnL.mjs";
1
+ import { C as syncSkills, F as generateAgenticTemplate, I as generateAgenticTemplates, L as loadAgenticTasks, M as resolveCommandConfig, N as createTimestampFolderName, O as name, P as defaultAgenticBaseDir, R as logger, S as skillTargets, _ as getCreateChoices, b as cleanProjects, g as defaultTemplate, h as createNewProject, i as init, k as version, n as syncNpmMirror, r as setVscodeBinaryMirror, t as upgradeMonorepo } from "./upgrade-B_Pvjblg.mjs";
2
2
  import process from "node:process";
3
3
  import { input, program, select } from "@icebreakers/monorepo-templates";
4
4
 
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- const require_upgrade = require('./upgrade-CEd5cMQ-.cjs');
1
+ const require_upgrade = require('./upgrade-vYYDUbQa.cjs');
2
2
  let _icebreakers_monorepo_templates = require("@icebreakers/monorepo-templates");
3
3
 
4
4
  exports.GitClient = require_upgrade.GitClient;
package/dist/index.d.cts CHANGED
@@ -1,10 +1,10 @@
1
+ import { TemplateDefinition, assetsDir, isGitignoreFile, templatesDir, toPublishGitignorePath, toWorkspaceGitignorePath } from "@icebreakers/monorepo-templates";
1
2
  import { PackageJson } from "pkg-types";
2
3
  import * as simple_git0 from "simple-git";
3
4
  import { ConfigValues, SimpleGit, SimpleGitOptions } from "simple-git";
4
5
  import * as git_url_parse0 from "git-url-parse";
5
6
  import gitUrlParse from "git-url-parse";
6
7
  import * as _pnpm_types0 from "@pnpm/types";
7
- import { assetsDir, isGitignoreFile, templatesDir, toPublishGitignorePath, toWorkspaceGitignorePath } from "@icebreakers/monorepo-templates";
8
8
  import * as consola0 from "consola";
9
9
  import crypto from "node:crypto";
10
10
 
@@ -113,10 +113,6 @@ declare const templateMap: {
113
113
  };
114
114
  };
115
115
  type CreateNewProjectType = keyof typeof templateMap;
116
- interface TemplateDefinition {
117
- source: string;
118
- target: string;
119
- }
120
116
  interface CreateNewProjectOptions {
121
117
  name?: string;
122
118
  cwd?: string;
package/dist/index.d.mts CHANGED
@@ -3,9 +3,9 @@ import gitUrlParse from "git-url-parse";
3
3
  import * as simple_git0 from "simple-git";
4
4
  import { ConfigValues, SimpleGit, SimpleGitOptions } from "simple-git";
5
5
  import * as consola0 from "consola";
6
- import { assetsDir, isGitignoreFile, templatesDir, toPublishGitignorePath, toWorkspaceGitignorePath } from "@icebreakers/monorepo-templates";
7
- import crypto from "node:crypto";
6
+ import { TemplateDefinition, assetsDir, isGitignoreFile, templatesDir, toPublishGitignorePath, toWorkspaceGitignorePath } from "@icebreakers/monorepo-templates";
8
7
  import * as _pnpm_types0 from "@pnpm/types";
8
+ import crypto from "node:crypto";
9
9
  import { PackageJson } from "pkg-types";
10
10
 
11
11
  //#region src/types/cli.d.ts
@@ -113,10 +113,6 @@ declare const templateMap: {
113
113
  };
114
114
  };
115
115
  type CreateNewProjectType = keyof typeof templateMap;
116
- interface TemplateDefinition {
117
- source: string;
118
- target: string;
119
- }
120
116
  interface CreateNewProjectOptions {
121
117
  name?: string;
122
118
  cwd?: string;
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { A as defineMonorepoConfig, B as getWorkspacePackages, C as syncSkills, D as templatesDir, E as rootDir, F as generateAgenticTemplate, I as generateAgenticTemplates, L as loadAgenticTasks, M as resolveCommandConfig, N as createTimestampFolderName, O as name, P as defaultAgenticBaseDir, R as logger, S as skillTargets, T as packageDir, V as GitClient, _ as toWorkspaceGitignorePath, a as createContext, b as cleanProjects, c as getCreateChoices, d as escapeStringRegexp, f as isMatch, g as toPublishGitignorePath, h as isGitignoreFile, i as init, j as loadMonorepoConfig, k as version, l as getTemplateMap, m as isFileChanged, n as syncNpmMirror, o as createNewProject, p as getFileHash, r as setVscodeBinaryMirror, t as upgradeMonorepo, u as templateMap, v as updateIssueTemplateConfig, w as assetsDir, x as getSkillTargetPaths, y as isIgnorableFsError, z as getWorkspaceData } from "./upgrade-Zbej0CnL.mjs";
1
+ import { A as defineMonorepoConfig, B as getWorkspacePackages, C as syncSkills, D as templatesDir, E as rootDir, F as generateAgenticTemplate, I as generateAgenticTemplates, L as loadAgenticTasks, M as resolveCommandConfig, N as createTimestampFolderName, O as name, P as defaultAgenticBaseDir, R as logger, S as skillTargets, T as packageDir, V as GitClient, _ as getCreateChoices, a as escapeStringRegexp, b as cleanProjects, c as isFileChanged, d as toWorkspaceGitignorePath, f as updateIssueTemplateConfig, h as createNewProject, i as init, j as loadMonorepoConfig, k as version, l as isGitignoreFile, m as createContext, n as syncNpmMirror, o as isMatch, p as isIgnorableFsError, r as setVscodeBinaryMirror, s as getFileHash, t as upgradeMonorepo, u as toPublishGitignorePath, v as getTemplateMap, w as assetsDir, x as getSkillTargetPaths, y as templateMap, z as getWorkspaceData } from "./upgrade-B_Pvjblg.mjs";
2
2
 
3
3
  export { GitClient, assetsDir, cleanProjects, createContext, createNewProject, createTimestampFolderName, defaultAgenticBaseDir, defineMonorepoConfig, escapeStringRegexp, generateAgenticTemplate, generateAgenticTemplates, getCreateChoices, getFileHash, getSkillTargetPaths, getTemplateMap, getWorkspaceData, getWorkspacePackages, init, isFileChanged, isGitignoreFile, isIgnorableFsError, isMatch, loadAgenticTasks, loadMonorepoConfig, logger, name, packageDir, resolveCommandConfig, rootDir, setVscodeBinaryMirror, skillTargets, syncNpmMirror, syncSkills, templateMap, templatesDir, toPublishGitignorePath, toWorkspaceGitignorePath, updateIssueTemplateConfig, upgradeMonorepo, version };
@@ -7,15 +7,15 @@ import path from "pathe";
7
7
  import process from "node:process";
8
8
  import fs from "fs-extra";
9
9
  import { createConsola } from "consola";
10
- import { assetsDir, checkbox, execaCommand, getAssetTargets, isGitignoreFile, shouldSkipTemplatePath, templatesDir, toPublishGitignorePath, toWorkspaceGitignorePath } from "@icebreakers/monorepo-templates";
10
+ import { assetsDir, checkbox, execaCommand, getAssetTargets, isGitignoreFile, scaffoldTemplate, templatesDir, toPublishGitignorePath, toWorkspaceGitignorePath } from "@icebreakers/monorepo-templates";
11
11
  import { loadConfig } from "c12";
12
12
  import os from "node:os";
13
13
  import * as path$1 from "node:path";
14
14
  import { fileURLToPath } from "node:url";
15
15
  import pc from "picocolors";
16
+ import "@pnpm/types";
16
17
  import YAML, { isSeq, parseDocument } from "yaml";
17
18
  import crypto from "node:crypto";
18
- import "@pnpm/types";
19
19
  import { parse, stringify } from "comment-json";
20
20
  import PQueue from "p-queue";
21
21
  import klaw from "klaw";
@@ -559,7 +559,7 @@ async function resolveCommandConfig(name$1, cwd) {
559
559
  //#endregion
560
560
  //#region package.json
561
561
  var name = "@icebreakers/monorepo";
562
- var version = "3.2.1";
562
+ var version = "3.2.3";
563
563
 
564
564
  //#endregion
565
565
  //#region src/constants.ts
@@ -680,94 +680,6 @@ async function cleanProjects(cwd, overrides) {
680
680
  await fs.outputJson(name$1, pkgJson, { spaces: 2 });
681
681
  }
682
682
 
683
- //#endregion
684
- //#region src/utils/fs.ts
685
- /**
686
- * 判断是否为可忽略的文件系统错误。
687
- * - ENOENT: 文件已被删除
688
- * - EBUSY: Windows 中资源被系统占用
689
- */
690
- function isIgnorableFsError(error) {
691
- if (!error) return false;
692
- const code = error.code;
693
- return code === "ENOENT" || code === "EBUSY" || code === "EEXIST";
694
- }
695
-
696
- //#endregion
697
- //#region src/utils/github.ts
698
- /**
699
- * 将 Issue 模版里的 discussions 链接同步为当前仓库的 discussions 地址。
700
- */
701
- function updateIssueTemplateConfig(source, repoName) {
702
- if (!repoName) return source;
703
- let doc;
704
- try {
705
- doc = parseDocument(source);
706
- } catch {
707
- return source;
708
- }
709
- const contactLinks = doc.get("contact_links");
710
- if (!isSeq(contactLinks)) return source;
711
- const nextUrl = `https://github.com/${repoName}/discussions`;
712
- let changed = false;
713
- contactLinks.items.forEach((_, index) => {
714
- const url = doc.getIn([
715
- "contact_links",
716
- index,
717
- "url"
718
- ]);
719
- if (typeof url !== "string") return;
720
- if (!url.includes("/discussions")) return;
721
- if (url === nextUrl) return;
722
- doc.setIn([
723
- "contact_links",
724
- index,
725
- "url"
726
- ], nextUrl);
727
- changed = true;
728
- });
729
- if (!changed) return source;
730
- return doc.toString();
731
- }
732
-
733
- //#endregion
734
- //#region src/utils/hash.ts
735
- /**
736
- * 生成给定二进制内容的 md5 摘要,用于快速比较文件内容。
737
- */
738
- function getFileHash(data) {
739
- const hashSum = crypto.createHash("md5");
740
- hashSum.update(data);
741
- return hashSum.digest("hex");
742
- }
743
- /**
744
- * 对比两个文件的 md5,如果不一致则认为内容有变化。
745
- */
746
- function isFileChanged(src, dest) {
747
- try {
748
- return getFileHash(src) !== getFileHash(dest);
749
- } catch (err) {
750
- logger.error("Error calculating file hash:", err);
751
- return false;
752
- }
753
- }
754
-
755
- //#endregion
756
- //#region src/utils/regexp.ts
757
- /**
758
- * 逃逸正则表达式中所有特殊字符,避免被当做模式解析。
759
- */
760
- function escapeStringRegexp(str) {
761
- return str.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&").replace(/-/g, "\\x2d");
762
- }
763
- /**
764
- * 判断字符串是否命中任意一个正则,用于过滤要同步的资产文件。
765
- */
766
- function isMatch(str, arr) {
767
- for (const reg of arr) if (reg.test(str)) return true;
768
- return false;
769
- }
770
-
771
683
  //#endregion
772
684
  //#region src/commands/create.ts
773
685
  /**
@@ -906,18 +818,14 @@ async function createNewProject(options) {
906
818
  const to = path.join(cwd, targetName);
907
819
  if (await fs.pathExists(to)) throw new Error(`${pc.red("目标目录已存在")}: ${path.relative(cwd, to)}`);
908
820
  await fs.ensureDir(to);
909
- const filelist = await fs.readdir(from);
910
- const shouldSkip = (src) => shouldSkipTemplatePath(from, src);
911
- const copyTasks = filelist.filter((filename) => filename !== "package.json").map(async (filename) => {
912
- const sourcePath = path.resolve(from, filename);
913
- const targetPath = path.resolve(to, toWorkspaceGitignorePath(filename));
914
- await fs.copy(sourcePath, targetPath, { filter(src) {
915
- return !shouldSkip(src);
916
- } });
821
+ const sourceJsonPath = path.resolve(from, "package.json");
822
+ const hasPackageJson = await fs.pathExists(sourceJsonPath);
823
+ await scaffoldTemplate({
824
+ sourceDir: from,
825
+ targetDir: to,
826
+ skipRootBasenames: ["package.json"]
917
827
  });
918
- await Promise.all(copyTasks);
919
- if (filelist.includes("package.json")) {
920
- const sourceJsonPath = path.resolve(from, "package.json");
828
+ if (hasPackageJson) {
921
829
  const sourceJson = await fs.readJson(sourceJsonPath);
922
830
  (0, import_set_value.default)(sourceJson, "version", "0.0.0");
923
831
  (0, import_set_value.default)(sourceJson, "name", name$1?.startsWith("@") ? name$1 : path.basename(targetName));
@@ -967,6 +875,94 @@ async function setChangeset_default(ctx) {
967
875
  }
968
876
  }
969
877
 
878
+ //#endregion
879
+ //#region src/utils/fs.ts
880
+ /**
881
+ * 判断是否为可忽略的文件系统错误。
882
+ * - ENOENT: 文件已被删除
883
+ * - EBUSY: Windows 中资源被系统占用
884
+ */
885
+ function isIgnorableFsError(error) {
886
+ if (!error) return false;
887
+ const code = error.code;
888
+ return code === "ENOENT" || code === "EBUSY" || code === "EEXIST";
889
+ }
890
+
891
+ //#endregion
892
+ //#region src/utils/github.ts
893
+ /**
894
+ * 将 Issue 模版里的 discussions 链接同步为当前仓库的 discussions 地址。
895
+ */
896
+ function updateIssueTemplateConfig(source, repoName) {
897
+ if (!repoName) return source;
898
+ let doc;
899
+ try {
900
+ doc = parseDocument(source);
901
+ } catch {
902
+ return source;
903
+ }
904
+ const contactLinks = doc.get("contact_links");
905
+ if (!isSeq(contactLinks)) return source;
906
+ const nextUrl = `https://github.com/${repoName}/discussions`;
907
+ let changed = false;
908
+ contactLinks.items.forEach((_, index) => {
909
+ const url = doc.getIn([
910
+ "contact_links",
911
+ index,
912
+ "url"
913
+ ]);
914
+ if (typeof url !== "string") return;
915
+ if (!url.includes("/discussions")) return;
916
+ if (url === nextUrl) return;
917
+ doc.setIn([
918
+ "contact_links",
919
+ index,
920
+ "url"
921
+ ], nextUrl);
922
+ changed = true;
923
+ });
924
+ if (!changed) return source;
925
+ return doc.toString();
926
+ }
927
+
928
+ //#endregion
929
+ //#region src/utils/hash.ts
930
+ /**
931
+ * 生成给定二进制内容的 md5 摘要,用于快速比较文件内容。
932
+ */
933
+ function getFileHash(data) {
934
+ const hashSum = crypto.createHash("md5");
935
+ hashSum.update(data);
936
+ return hashSum.digest("hex");
937
+ }
938
+ /**
939
+ * 对比两个文件的 md5,如果不一致则认为内容有变化。
940
+ */
941
+ function isFileChanged(src, dest) {
942
+ try {
943
+ return getFileHash(src) !== getFileHash(dest);
944
+ } catch (err) {
945
+ logger.error("Error calculating file hash:", err);
946
+ return false;
947
+ }
948
+ }
949
+
950
+ //#endregion
951
+ //#region src/utils/regexp.ts
952
+ /**
953
+ * 逃逸正则表达式中所有特殊字符,避免被当做模式解析。
954
+ */
955
+ function escapeStringRegexp(str) {
956
+ return str.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&").replace(/-/g, "\\x2d");
957
+ }
958
+ /**
959
+ * 判断字符串是否命中任意一个正则,用于过滤要同步的资产文件。
960
+ */
961
+ function isMatch(str, arr) {
962
+ for (const reg of arr) if (reg.test(str)) return true;
963
+ return false;
964
+ }
965
+
970
966
  //#endregion
971
967
  //#region src/commands/init/setIssueTemplateConfig.ts
972
968
  /**
@@ -1525,4 +1521,4 @@ async function upgradeMonorepo(opts) {
1525
1521
  }
1526
1522
 
1527
1523
  //#endregion
1528
- export { defineMonorepoConfig as A, getWorkspacePackages as B, syncSkills as C, templatesDir as D, rootDir as E, generateAgenticTemplate as F, generateAgenticTemplates as I, loadAgenticTasks as L, resolveCommandConfig as M, createTimestampFolderName as N, name as O, defaultAgenticBaseDir as P, logger as R, skillTargets as S, packageDir as T, GitClient as V, toWorkspaceGitignorePath as _, createContext as a, cleanProjects as b, getCreateChoices as c, escapeStringRegexp as d, isMatch as f, toPublishGitignorePath as g, isGitignoreFile as h, init as i, loadMonorepoConfig as j, version as k, getTemplateMap as l, isFileChanged as m, syncNpmMirror as n, createNewProject as o, getFileHash as p, setVscodeBinaryMirror as r, defaultTemplate as s, upgradeMonorepo as t, templateMap as u, updateIssueTemplateConfig as v, assetsDir as w, getSkillTargetPaths as x, isIgnorableFsError as y, getWorkspaceData as z };
1524
+ export { defineMonorepoConfig as A, getWorkspacePackages as B, syncSkills as C, templatesDir as D, rootDir as E, generateAgenticTemplate as F, generateAgenticTemplates as I, loadAgenticTasks as L, resolveCommandConfig as M, createTimestampFolderName as N, name as O, defaultAgenticBaseDir as P, logger as R, skillTargets as S, packageDir as T, GitClient as V, getCreateChoices as _, escapeStringRegexp as a, cleanProjects as b, isFileChanged as c, toWorkspaceGitignorePath as d, updateIssueTemplateConfig as f, defaultTemplate as g, createNewProject as h, init as i, loadMonorepoConfig as j, version as k, isGitignoreFile as l, createContext as m, syncNpmMirror as n, isMatch as o, isIgnorableFsError as p, setVscodeBinaryMirror as r, getFileHash as s, upgradeMonorepo as t, toPublishGitignorePath as u, getTemplateMap as v, assetsDir as w, getSkillTargetPaths as x, templateMap as y, getWorkspaceData as z };
@@ -48,11 +48,11 @@ node_path = __toESM(node_path);
48
48
  let node_url = require("node:url");
49
49
  let picocolors = require("picocolors");
50
50
  picocolors = __toESM(picocolors);
51
+ require("@pnpm/types");
51
52
  let yaml = require("yaml");
52
53
  yaml = __toESM(yaml);
53
54
  let node_crypto = require("node:crypto");
54
55
  node_crypto = __toESM(node_crypto);
55
- require("@pnpm/types");
56
56
  let comment_json = require("comment-json");
57
57
  let p_queue = require("p-queue");
58
58
  p_queue = __toESM(p_queue);
@@ -570,7 +570,7 @@ async function resolveCommandConfig(name$1, cwd) {
570
570
  //#endregion
571
571
  //#region package.json
572
572
  var name = "@icebreakers/monorepo";
573
- var version = "3.2.1";
573
+ var version = "3.2.3";
574
574
 
575
575
  //#endregion
576
576
  //#region src/constants.ts
@@ -691,94 +691,6 @@ async function cleanProjects(cwd, overrides) {
691
691
  await fs_extra.default.outputJson(name$1, pkgJson, { spaces: 2 });
692
692
  }
693
693
 
694
- //#endregion
695
- //#region src/utils/fs.ts
696
- /**
697
- * 判断是否为可忽略的文件系统错误。
698
- * - ENOENT: 文件已被删除
699
- * - EBUSY: Windows 中资源被系统占用
700
- */
701
- function isIgnorableFsError(error) {
702
- if (!error) return false;
703
- const code = error.code;
704
- return code === "ENOENT" || code === "EBUSY" || code === "EEXIST";
705
- }
706
-
707
- //#endregion
708
- //#region src/utils/github.ts
709
- /**
710
- * 将 Issue 模版里的 discussions 链接同步为当前仓库的 discussions 地址。
711
- */
712
- function updateIssueTemplateConfig(source, repoName) {
713
- if (!repoName) return source;
714
- let doc;
715
- try {
716
- doc = (0, yaml.parseDocument)(source);
717
- } catch {
718
- return source;
719
- }
720
- const contactLinks = doc.get("contact_links");
721
- if (!(0, yaml.isSeq)(contactLinks)) return source;
722
- const nextUrl = `https://github.com/${repoName}/discussions`;
723
- let changed = false;
724
- contactLinks.items.forEach((_, index) => {
725
- const url = doc.getIn([
726
- "contact_links",
727
- index,
728
- "url"
729
- ]);
730
- if (typeof url !== "string") return;
731
- if (!url.includes("/discussions")) return;
732
- if (url === nextUrl) return;
733
- doc.setIn([
734
- "contact_links",
735
- index,
736
- "url"
737
- ], nextUrl);
738
- changed = true;
739
- });
740
- if (!changed) return source;
741
- return doc.toString();
742
- }
743
-
744
- //#endregion
745
- //#region src/utils/hash.ts
746
- /**
747
- * 生成给定二进制内容的 md5 摘要,用于快速比较文件内容。
748
- */
749
- function getFileHash(data) {
750
- const hashSum = node_crypto.default.createHash("md5");
751
- hashSum.update(data);
752
- return hashSum.digest("hex");
753
- }
754
- /**
755
- * 对比两个文件的 md5,如果不一致则认为内容有变化。
756
- */
757
- function isFileChanged(src, dest) {
758
- try {
759
- return getFileHash(src) !== getFileHash(dest);
760
- } catch (err) {
761
- logger.error("Error calculating file hash:", err);
762
- return false;
763
- }
764
- }
765
-
766
- //#endregion
767
- //#region src/utils/regexp.ts
768
- /**
769
- * 逃逸正则表达式中所有特殊字符,避免被当做模式解析。
770
- */
771
- function escapeStringRegexp(str) {
772
- return str.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&").replace(/-/g, "\\x2d");
773
- }
774
- /**
775
- * 判断字符串是否命中任意一个正则,用于过滤要同步的资产文件。
776
- */
777
- function isMatch(str, arr) {
778
- for (const reg of arr) if (reg.test(str)) return true;
779
- return false;
780
- }
781
-
782
694
  //#endregion
783
695
  //#region src/commands/create.ts
784
696
  /**
@@ -917,18 +829,14 @@ async function createNewProject(options) {
917
829
  const to = pathe.default.join(cwd, targetName);
918
830
  if (await fs_extra.default.pathExists(to)) throw new Error(`${picocolors.default.red("目标目录已存在")}: ${pathe.default.relative(cwd, to)}`);
919
831
  await fs_extra.default.ensureDir(to);
920
- const filelist = await fs_extra.default.readdir(from);
921
- const shouldSkip = (src) => (0, _icebreakers_monorepo_templates.shouldSkipTemplatePath)(from, src);
922
- const copyTasks = filelist.filter((filename) => filename !== "package.json").map(async (filename) => {
923
- const sourcePath = pathe.default.resolve(from, filename);
924
- const targetPath = pathe.default.resolve(to, (0, _icebreakers_monorepo_templates.toWorkspaceGitignorePath)(filename));
925
- await fs_extra.default.copy(sourcePath, targetPath, { filter(src) {
926
- return !shouldSkip(src);
927
- } });
832
+ const sourceJsonPath = pathe.default.resolve(from, "package.json");
833
+ const hasPackageJson = await fs_extra.default.pathExists(sourceJsonPath);
834
+ await (0, _icebreakers_monorepo_templates.scaffoldTemplate)({
835
+ sourceDir: from,
836
+ targetDir: to,
837
+ skipRootBasenames: ["package.json"]
928
838
  });
929
- await Promise.all(copyTasks);
930
- if (filelist.includes("package.json")) {
931
- const sourceJsonPath = pathe.default.resolve(from, "package.json");
839
+ if (hasPackageJson) {
932
840
  const sourceJson = await fs_extra.default.readJson(sourceJsonPath);
933
841
  (0, import_set_value.default)(sourceJson, "version", "0.0.0");
934
842
  (0, import_set_value.default)(sourceJson, "name", name$1?.startsWith("@") ? name$1 : pathe.default.basename(targetName));
@@ -978,6 +886,94 @@ async function setChangeset_default(ctx) {
978
886
  }
979
887
  }
980
888
 
889
+ //#endregion
890
+ //#region src/utils/fs.ts
891
+ /**
892
+ * 判断是否为可忽略的文件系统错误。
893
+ * - ENOENT: 文件已被删除
894
+ * - EBUSY: Windows 中资源被系统占用
895
+ */
896
+ function isIgnorableFsError(error) {
897
+ if (!error) return false;
898
+ const code = error.code;
899
+ return code === "ENOENT" || code === "EBUSY" || code === "EEXIST";
900
+ }
901
+
902
+ //#endregion
903
+ //#region src/utils/github.ts
904
+ /**
905
+ * 将 Issue 模版里的 discussions 链接同步为当前仓库的 discussions 地址。
906
+ */
907
+ function updateIssueTemplateConfig(source, repoName) {
908
+ if (!repoName) return source;
909
+ let doc;
910
+ try {
911
+ doc = (0, yaml.parseDocument)(source);
912
+ } catch {
913
+ return source;
914
+ }
915
+ const contactLinks = doc.get("contact_links");
916
+ if (!(0, yaml.isSeq)(contactLinks)) return source;
917
+ const nextUrl = `https://github.com/${repoName}/discussions`;
918
+ let changed = false;
919
+ contactLinks.items.forEach((_, index) => {
920
+ const url = doc.getIn([
921
+ "contact_links",
922
+ index,
923
+ "url"
924
+ ]);
925
+ if (typeof url !== "string") return;
926
+ if (!url.includes("/discussions")) return;
927
+ if (url === nextUrl) return;
928
+ doc.setIn([
929
+ "contact_links",
930
+ index,
931
+ "url"
932
+ ], nextUrl);
933
+ changed = true;
934
+ });
935
+ if (!changed) return source;
936
+ return doc.toString();
937
+ }
938
+
939
+ //#endregion
940
+ //#region src/utils/hash.ts
941
+ /**
942
+ * 生成给定二进制内容的 md5 摘要,用于快速比较文件内容。
943
+ */
944
+ function getFileHash(data) {
945
+ const hashSum = node_crypto.default.createHash("md5");
946
+ hashSum.update(data);
947
+ return hashSum.digest("hex");
948
+ }
949
+ /**
950
+ * 对比两个文件的 md5,如果不一致则认为内容有变化。
951
+ */
952
+ function isFileChanged(src, dest) {
953
+ try {
954
+ return getFileHash(src) !== getFileHash(dest);
955
+ } catch (err) {
956
+ logger.error("Error calculating file hash:", err);
957
+ return false;
958
+ }
959
+ }
960
+
961
+ //#endregion
962
+ //#region src/utils/regexp.ts
963
+ /**
964
+ * 逃逸正则表达式中所有特殊字符,避免被当做模式解析。
965
+ */
966
+ function escapeStringRegexp(str) {
967
+ return str.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&").replace(/-/g, "\\x2d");
968
+ }
969
+ /**
970
+ * 判断字符串是否命中任意一个正则,用于过滤要同步的资产文件。
971
+ */
972
+ function isMatch(str, arr) {
973
+ for (const reg of arr) if (reg.test(str)) return true;
974
+ return false;
975
+ }
976
+
981
977
  //#endregion
982
978
  //#region src/commands/init/setIssueTemplateConfig.ts
983
979
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@icebreakers/monorepo",
3
3
  "type": "module",
4
- "version": "3.2.1",
4
+ "version": "3.2.3",
5
5
  "description": "The icebreaker's monorepo manager",
6
6
  "author": "ice breaker <1324318532@qq.com>",
7
7
  "license": "MIT",
@@ -59,10 +59,10 @@
59
59
  "dependencies": {
60
60
  "@pnpm/find-workspace-dir": "^1000.1.3",
61
61
  "@pnpm/logger": "^1001.0.1",
62
- "@pnpm/types": "^1001.2.0",
63
- "@pnpm/worker": "^1000.6.1",
64
- "@pnpm/workspace.find-packages": "^1000.0.54",
65
- "@pnpm/workspace.read-manifest": "^1000.2.9",
62
+ "@pnpm/types": "^1001.3.0",
63
+ "@pnpm/worker": "^1000.6.2",
64
+ "@pnpm/workspace.find-packages": "^1000.0.55",
65
+ "@pnpm/workspace.read-manifest": "^1000.2.10",
66
66
  "c12": "^3.3.3",
67
67
  "comment-json": "^4.5.1",
68
68
  "consola": "^3.4.2",
@@ -75,7 +75,7 @@
75
75
  "semver": "^7.7.3",
76
76
  "simple-git": "^3.30.0",
77
77
  "yaml": "^2.8.2",
78
- "@icebreakers/monorepo-templates": "0.1.1"
78
+ "@icebreakers/monorepo-templates": "0.1.3"
79
79
  },
80
80
  "devDependencies": {
81
81
  "@types/klaw": "^3.0.7",