@icebreakers/monorepo 3.1.6 → 3.1.8
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/assets/monorepo.config.ts +1 -1
- package/assets/package.json +1 -1
- package/dist/cli.cjs +2 -1
- package/dist/cli.mjs +2 -1
- package/dist/index.cjs +2 -1
- package/dist/index.d.cts +13 -2
- package/dist/index.d.mts +13 -2
- package/dist/index.mjs +2 -2
- package/dist/{upgrade-bI11sYwb.cjs → upgrade-DEBWprtr.cjs} +98 -19
- package/dist/{upgrade-DM5OLZGd.mjs → upgrade-DjrKVY-g.mjs} +80 -7
- package/package.json +1 -1
- package/templates/apps/client/package.json +1 -1
- package/templates/apps/website/index.md +2 -2
- package/templates/apps/website/monorepo/publish.md +7 -2
- package/templates/apps/website/why/publish-basic-npm-package.md +1 -1
- package/templates/packages/vue-lib-template/package.json +1 -1
package/assets/package.json
CHANGED
package/dist/cli.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_upgrade = require('./upgrade-
|
|
1
|
+
const require_upgrade = require('./upgrade-DEBWprtr.cjs');
|
|
2
2
|
let node_process = require("node:process");
|
|
3
3
|
node_process = require_upgrade.__toESM(node_process);
|
|
4
4
|
let __inquirer_input = require("@inquirer/input");
|
|
@@ -50,6 +50,7 @@ commander.program.command("ai").description("AI 助手工具集").command("creat
|
|
|
50
50
|
const tasksFile = opts.tasks ?? aiConfig?.tasksFile;
|
|
51
51
|
const name$1 = opts.name;
|
|
52
52
|
if (Boolean(tasksFile && !opts.output && !opts.name)) {
|
|
53
|
+
if (!tasksFile) throw new Error("tasks file path is required when using tasks mode");
|
|
53
54
|
await require_upgrade.generateAgenticTemplates(await require_upgrade.loadAgenticTasks(tasksFile, cwd), {
|
|
54
55
|
cwd,
|
|
55
56
|
baseDir,
|
package/dist/cli.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as
|
|
1
|
+
import { A as createTimestampFolderName, E as cleanProjects, F as logger, M as generateAgenticTemplate, N as generateAgenticTemplates, P as loadAgenticTasks, T as version, c as getCreateChoices, i as init, j as defaultAgenticBaseDir, k as resolveCommandConfig, n as syncNpmMirror, o as createNewProject, r as setVscodeBinaryMirror, s as defaultTemplate, t as upgradeMonorepo, w as name } from "./upgrade-DjrKVY-g.mjs";
|
|
2
2
|
import process from "node:process";
|
|
3
3
|
import input from "@inquirer/input";
|
|
4
4
|
import select from "@inquirer/select";
|
|
@@ -47,6 +47,7 @@ program.command("ai").description("AI 助手工具集").command("create").alias(
|
|
|
47
47
|
const tasksFile = opts.tasks ?? aiConfig?.tasksFile;
|
|
48
48
|
const name$1 = opts.name;
|
|
49
49
|
if (Boolean(tasksFile && !opts.output && !opts.name)) {
|
|
50
|
+
if (!tasksFile) throw new Error("tasks file path is required when using tasks mode");
|
|
50
51
|
await generateAgenticTemplates(await loadAgenticTasks(tasksFile, cwd), {
|
|
51
52
|
cwd,
|
|
52
53
|
baseDir,
|
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_upgrade = require('./upgrade-
|
|
1
|
+
const require_upgrade = require('./upgrade-DEBWprtr.cjs');
|
|
2
2
|
|
|
3
3
|
exports.GitClient = require_upgrade.GitClient;
|
|
4
4
|
exports.assetsDir = require_upgrade.assetsDir;
|
|
@@ -39,6 +39,7 @@ exports.templateMap = require_upgrade.templateMap;
|
|
|
39
39
|
exports.templatesDir = require_upgrade.templatesDir;
|
|
40
40
|
exports.toPublishGitignorePath = require_upgrade.toPublishGitignorePath;
|
|
41
41
|
exports.toWorkspaceGitignorePath = require_upgrade.toWorkspaceGitignorePath;
|
|
42
|
+
exports.updateIssueTemplateConfig = require_upgrade.updateIssueTemplateConfig;
|
|
42
43
|
exports.upgradeMonorepo = require_upgrade.upgradeMonorepo;
|
|
43
44
|
Object.defineProperty(exports, 'version', {
|
|
44
45
|
enumerable: true,
|
package/dist/index.d.cts
CHANGED
|
@@ -252,7 +252,7 @@ interface CleanCommandConfig {
|
|
|
252
252
|
ignorePackages?: string[];
|
|
253
253
|
/**
|
|
254
254
|
* 是否包含 private 包。
|
|
255
|
-
* @default
|
|
255
|
+
* @default true
|
|
256
256
|
*/
|
|
257
257
|
includePrivate?: boolean;
|
|
258
258
|
/**
|
|
@@ -325,6 +325,11 @@ interface InitCommandConfig {
|
|
|
325
325
|
* @default false
|
|
326
326
|
*/
|
|
327
327
|
skipChangeset?: boolean;
|
|
328
|
+
/**
|
|
329
|
+
* 是否跳过 Issue 模版 discussions 链接的更新。
|
|
330
|
+
* @default false
|
|
331
|
+
*/
|
|
332
|
+
skipIssueTemplateConfig?: boolean;
|
|
328
333
|
}
|
|
329
334
|
/**
|
|
330
335
|
* `monorepo mirror` 命令配置,可增加额外的环境变量镜像。
|
|
@@ -533,6 +538,12 @@ declare const logger: consola0.ConsolaInstance;
|
|
|
533
538
|
*/
|
|
534
539
|
declare function isIgnorableFsError(error: unknown): error is NodeJS.ErrnoException;
|
|
535
540
|
//#endregion
|
|
541
|
+
//#region src/utils/github.d.ts
|
|
542
|
+
/**
|
|
543
|
+
* 将 Issue 模版里的 discussions 链接同步为当前仓库的 discussions 地址。
|
|
544
|
+
*/
|
|
545
|
+
declare function updateIssueTemplateConfig(source: string, repoName?: string): string;
|
|
546
|
+
//#endregion
|
|
536
547
|
//#region src/utils/gitignore.d.ts
|
|
537
548
|
/**
|
|
538
549
|
* Map a workspace path (containing `.gitignore`) to its packaged variant.
|
|
@@ -568,4 +579,4 @@ declare function escapeStringRegexp(str: string): string;
|
|
|
568
579
|
*/
|
|
569
580
|
declare function isMatch(str: string, arr: RegExp[]): boolean;
|
|
570
581
|
//#endregion
|
|
571
|
-
export { AgenticTemplateFormat, AgenticTemplateTask, type AiCommandConfig, type CleanCommandConfig, type CliOpts, type ConfigValues, Context, type CreateChoiceOption, type CreateCommandConfig, CreateNewProjectOptions, GenerateAgenticTemplateOptions, type GetWorkspacePackagesOptions, GitClient, type InitCommandConfig, type MirrorCommandConfig, type MonorepoConfig, type PackageJson, type SimpleGit, type SimpleGitOptions, type SyncCommandConfig, type UpgradeCommandConfig, assetsDir, cleanProjects, createContext, createNewProject, createTimestampFolderName, defaultAgenticBaseDir, defineMonorepoConfig, escapeStringRegexp, generateAgenticTemplate, generateAgenticTemplates, getCreateChoices, getFileHash, getTemplateMap, getWorkspaceData, getWorkspacePackages, init, isFileChanged, isGitignoreFile, isIgnorableFsError, isMatch, loadAgenticTasks, loadMonorepoConfig, logger, name, packageDir, resolveCommandConfig, rootDir, setVscodeBinaryMirror, syncNpmMirror, templateMap, templatesDir, toPublishGitignorePath, toWorkspaceGitignorePath, upgradeMonorepo, version };
|
|
582
|
+
export { AgenticTemplateFormat, AgenticTemplateTask, type AiCommandConfig, type CleanCommandConfig, type CliOpts, type ConfigValues, Context, type CreateChoiceOption, type CreateCommandConfig, CreateNewProjectOptions, GenerateAgenticTemplateOptions, type GetWorkspacePackagesOptions, GitClient, type InitCommandConfig, type MirrorCommandConfig, type MonorepoConfig, type PackageJson, type SimpleGit, type SimpleGitOptions, type SyncCommandConfig, type UpgradeCommandConfig, assetsDir, cleanProjects, createContext, createNewProject, createTimestampFolderName, defaultAgenticBaseDir, defineMonorepoConfig, escapeStringRegexp, generateAgenticTemplate, generateAgenticTemplates, getCreateChoices, getFileHash, getTemplateMap, getWorkspaceData, getWorkspacePackages, init, isFileChanged, isGitignoreFile, isIgnorableFsError, isMatch, loadAgenticTasks, loadMonorepoConfig, logger, name, packageDir, resolveCommandConfig, rootDir, setVscodeBinaryMirror, syncNpmMirror, templateMap, templatesDir, toPublishGitignorePath, toWorkspaceGitignorePath, updateIssueTemplateConfig, upgradeMonorepo, version };
|
package/dist/index.d.mts
CHANGED
|
@@ -252,7 +252,7 @@ interface CleanCommandConfig {
|
|
|
252
252
|
ignorePackages?: string[];
|
|
253
253
|
/**
|
|
254
254
|
* 是否包含 private 包。
|
|
255
|
-
* @default
|
|
255
|
+
* @default true
|
|
256
256
|
*/
|
|
257
257
|
includePrivate?: boolean;
|
|
258
258
|
/**
|
|
@@ -325,6 +325,11 @@ interface InitCommandConfig {
|
|
|
325
325
|
* @default false
|
|
326
326
|
*/
|
|
327
327
|
skipChangeset?: boolean;
|
|
328
|
+
/**
|
|
329
|
+
* 是否跳过 Issue 模版 discussions 链接的更新。
|
|
330
|
+
* @default false
|
|
331
|
+
*/
|
|
332
|
+
skipIssueTemplateConfig?: boolean;
|
|
328
333
|
}
|
|
329
334
|
/**
|
|
330
335
|
* `monorepo mirror` 命令配置,可增加额外的环境变量镜像。
|
|
@@ -533,6 +538,12 @@ declare const logger: consola0.ConsolaInstance;
|
|
|
533
538
|
*/
|
|
534
539
|
declare function isIgnorableFsError(error: unknown): error is NodeJS.ErrnoException;
|
|
535
540
|
//#endregion
|
|
541
|
+
//#region src/utils/github.d.ts
|
|
542
|
+
/**
|
|
543
|
+
* 将 Issue 模版里的 discussions 链接同步为当前仓库的 discussions 地址。
|
|
544
|
+
*/
|
|
545
|
+
declare function updateIssueTemplateConfig(source: string, repoName?: string): string;
|
|
546
|
+
//#endregion
|
|
536
547
|
//#region src/utils/gitignore.d.ts
|
|
537
548
|
/**
|
|
538
549
|
* Map a workspace path (containing `.gitignore`) to its packaged variant.
|
|
@@ -568,4 +579,4 @@ declare function escapeStringRegexp(str: string): string;
|
|
|
568
579
|
*/
|
|
569
580
|
declare function isMatch(str: string, arr: RegExp[]): boolean;
|
|
570
581
|
//#endregion
|
|
571
|
-
export { type AgenticTemplateFormat, type AgenticTemplateTask, type AiCommandConfig, type CleanCommandConfig, type CliOpts, type ConfigValues, Context, type CreateChoiceOption, type CreateCommandConfig, type CreateNewProjectOptions, type GenerateAgenticTemplateOptions, type GetWorkspacePackagesOptions, GitClient, type InitCommandConfig, type MirrorCommandConfig, type MonorepoConfig, type PackageJson, type SimpleGit, type SimpleGitOptions, type SyncCommandConfig, type UpgradeCommandConfig, assetsDir, cleanProjects, createContext, createNewProject, createTimestampFolderName, defaultAgenticBaseDir, defineMonorepoConfig, escapeStringRegexp, generateAgenticTemplate, generateAgenticTemplates, getCreateChoices, getFileHash, getTemplateMap, getWorkspaceData, getWorkspacePackages, init, isFileChanged, isGitignoreFile, isIgnorableFsError, isMatch, loadAgenticTasks, loadMonorepoConfig, logger, name, packageDir, resolveCommandConfig, rootDir, setVscodeBinaryMirror, syncNpmMirror, templateMap, templatesDir, toPublishGitignorePath, toWorkspaceGitignorePath, upgradeMonorepo, version };
|
|
582
|
+
export { type AgenticTemplateFormat, type AgenticTemplateTask, type AiCommandConfig, type CleanCommandConfig, type CliOpts, type ConfigValues, Context, type CreateChoiceOption, type CreateCommandConfig, type CreateNewProjectOptions, type GenerateAgenticTemplateOptions, type GetWorkspacePackagesOptions, GitClient, type InitCommandConfig, type MirrorCommandConfig, type MonorepoConfig, type PackageJson, type SimpleGit, type SimpleGitOptions, type SyncCommandConfig, type UpgradeCommandConfig, assetsDir, cleanProjects, createContext, createNewProject, createTimestampFolderName, defaultAgenticBaseDir, defineMonorepoConfig, escapeStringRegexp, generateAgenticTemplate, generateAgenticTemplates, getCreateChoices, getFileHash, getTemplateMap, getWorkspaceData, getWorkspacePackages, init, isFileChanged, isGitignoreFile, isIgnorableFsError, isMatch, loadAgenticTasks, loadMonorepoConfig, logger, name, packageDir, resolveCommandConfig, rootDir, setVscodeBinaryMirror, syncNpmMirror, templateMap, templatesDir, toPublishGitignorePath, toWorkspaceGitignorePath, updateIssueTemplateConfig, upgradeMonorepo, version };
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { A as
|
|
1
|
+
import { A as createTimestampFolderName, C as templatesDir, D as defineMonorepoConfig, E as cleanProjects, F as logger, I as getWorkspaceData, L as getWorkspacePackages, M as generateAgenticTemplate, N as generateAgenticTemplates, O as loadMonorepoConfig, P as loadAgenticTasks, R as GitClient, S as rootDir, T as version, _ as toWorkspaceGitignorePath, a as createContext, b as assetsDir, c as getCreateChoices, d as escapeStringRegexp, f as isMatch, g as toPublishGitignorePath, h as isGitignoreFile, i as init, j as defaultAgenticBaseDir, k as resolveCommandConfig, 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 name, x as packageDir, y as isIgnorableFsError } from "./upgrade-DjrKVY-g.mjs";
|
|
2
2
|
|
|
3
|
-
export { GitClient, assetsDir, cleanProjects, createContext, createNewProject, createTimestampFolderName, defaultAgenticBaseDir, defineMonorepoConfig, escapeStringRegexp, generateAgenticTemplate, generateAgenticTemplates, getCreateChoices, getFileHash, getTemplateMap, getWorkspaceData, getWorkspacePackages, init, isFileChanged, isGitignoreFile, isIgnorableFsError, isMatch, loadAgenticTasks, loadMonorepoConfig, logger, name, packageDir, resolveCommandConfig, rootDir, setVscodeBinaryMirror, syncNpmMirror, templateMap, templatesDir, toPublishGitignorePath, toWorkspaceGitignorePath, upgradeMonorepo, version };
|
|
3
|
+
export { GitClient, assetsDir, cleanProjects, createContext, createNewProject, createTimestampFolderName, defaultAgenticBaseDir, defineMonorepoConfig, escapeStringRegexp, generateAgenticTemplate, generateAgenticTemplates, getCreateChoices, getFileHash, getTemplateMap, getWorkspaceData, getWorkspacePackages, init, isFileChanged, isGitignoreFile, isIgnorableFsError, isMatch, loadAgenticTasks, loadMonorepoConfig, logger, name, packageDir, resolveCommandConfig, rootDir, setVscodeBinaryMirror, syncNpmMirror, templateMap, templatesDir, toPublishGitignorePath, toWorkspaceGitignorePath, updateIssueTemplateConfig, upgradeMonorepo, version };
|
|
@@ -47,6 +47,8 @@ picocolors = __toESM(picocolors);
|
|
|
47
47
|
let node_path = require("node:path");
|
|
48
48
|
node_path = __toESM(node_path);
|
|
49
49
|
let node_url = require("node:url");
|
|
50
|
+
let yaml = require("yaml");
|
|
51
|
+
yaml = __toESM(yaml);
|
|
50
52
|
let node_crypto = require("node:crypto");
|
|
51
53
|
node_crypto = __toESM(node_crypto);
|
|
52
54
|
require("@pnpm/types");
|
|
@@ -58,8 +60,6 @@ let p_queue = require("p-queue");
|
|
|
58
60
|
p_queue = __toESM(p_queue);
|
|
59
61
|
let klaw = require("klaw");
|
|
60
62
|
klaw = __toESM(klaw);
|
|
61
|
-
let yaml = require("yaml");
|
|
62
|
-
yaml = __toESM(yaml);
|
|
63
63
|
let node_buffer = require("node:buffer");
|
|
64
64
|
let semver = require("semver");
|
|
65
65
|
|
|
@@ -74,9 +74,9 @@ var join = /* @__PURE__ */ __name((segs, joinChar, options) => {
|
|
|
74
74
|
if (typeof options.join === "function") return options.join(segs);
|
|
75
75
|
return segs[0] + joinChar + segs[1];
|
|
76
76
|
}, "join");
|
|
77
|
-
var split$1 = /* @__PURE__ */ __name((path$
|
|
78
|
-
if (typeof options.split === "function") return options.split(path$
|
|
79
|
-
return path$
|
|
77
|
+
var split$1 = /* @__PURE__ */ __name((path$14, splitChar, options) => {
|
|
78
|
+
if (typeof options.split === "function") return options.split(path$14);
|
|
79
|
+
return path$14.split(splitChar);
|
|
80
80
|
}, "split");
|
|
81
81
|
var isValid = /* @__PURE__ */ __name((key, target = {}, options) => {
|
|
82
82
|
if (typeof options?.isValid === "function") return options.isValid(key, target);
|
|
@@ -85,17 +85,17 @@ var isValid = /* @__PURE__ */ __name((key, target = {}, options) => {
|
|
|
85
85
|
var isValidObject = /* @__PURE__ */ __name((v) => {
|
|
86
86
|
return isObject$2(v) || typeof v === "function";
|
|
87
87
|
}, "isValidObject");
|
|
88
|
-
var index_default = /* @__PURE__ */ __name((target, path$
|
|
88
|
+
var index_default = /* @__PURE__ */ __name((target, path$14, options = {}) => {
|
|
89
89
|
if (!isObject$2(options)) options = { default: options };
|
|
90
90
|
if (!isValidObject(target)) return typeof options.default !== "undefined" ? options.default : target;
|
|
91
|
-
if (typeof path$
|
|
92
|
-
const pathIsArray = Array.isArray(path$
|
|
93
|
-
const pathIsString = typeof path$
|
|
91
|
+
if (typeof path$14 === "number") path$14 = String(path$14);
|
|
92
|
+
const pathIsArray = Array.isArray(path$14);
|
|
93
|
+
const pathIsString = typeof path$14 === "string";
|
|
94
94
|
const splitChar = options.separator || ".";
|
|
95
95
|
const joinChar = options.joinChar || (typeof splitChar === "string" ? splitChar : ".");
|
|
96
96
|
if (!pathIsString && !pathIsArray) return target;
|
|
97
|
-
if (target[path$
|
|
98
|
-
const segs = pathIsArray ? path$
|
|
97
|
+
if (target[path$14] !== void 0) return isValid(path$14, target, options) ? target[path$14] : options.default;
|
|
98
|
+
const segs = pathIsArray ? path$14 : split$1(path$14, splitChar, options);
|
|
99
99
|
const len = segs.length;
|
|
100
100
|
let idx = 0;
|
|
101
101
|
do {
|
|
@@ -494,9 +494,9 @@ var require_set_value = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
494
494
|
} else obj[prop] = value;
|
|
495
495
|
return obj;
|
|
496
496
|
};
|
|
497
|
-
const setValue = (target, path$
|
|
498
|
-
if (!path$
|
|
499
|
-
const keys = split(path$
|
|
497
|
+
const setValue = (target, path$14, value, options) => {
|
|
498
|
+
if (!path$14 || !isObject(target)) return target;
|
|
499
|
+
const keys = split(path$14, options);
|
|
500
500
|
let obj = target;
|
|
501
501
|
for (let i = 0; i < keys.length; i++) {
|
|
502
502
|
const key = keys[i];
|
|
@@ -572,10 +572,11 @@ async function resolveCommandConfig(name$1, cwd) {
|
|
|
572
572
|
//#region src/commands/clean.ts
|
|
573
573
|
var import_set_value$5 = /* @__PURE__ */ __toESM(require_set_value(), 1);
|
|
574
574
|
function mergeCleanConfig(base, overrides) {
|
|
575
|
-
|
|
575
|
+
const normalizedBase = base ?? {};
|
|
576
|
+
if (!overrides) return normalizedBase;
|
|
576
577
|
const definedOverrides = Object.fromEntries(Object.entries(overrides).filter(([, value]) => value !== void 0));
|
|
577
578
|
return {
|
|
578
|
-
...
|
|
579
|
+
...normalizedBase,
|
|
579
580
|
...definedOverrides
|
|
580
581
|
};
|
|
581
582
|
}
|
|
@@ -584,7 +585,7 @@ function mergeCleanConfig(base, overrides) {
|
|
|
584
585
|
*/
|
|
585
586
|
async function cleanProjects(cwd, overrides) {
|
|
586
587
|
const cleanConfig = mergeCleanConfig(await resolveCommandConfig("clean", cwd), overrides);
|
|
587
|
-
const { packages, workspaceDir } = await getWorkspaceData(cwd, cleanConfig?.includePrivate ? { ignorePrivatePackage: false } : void 0);
|
|
588
|
+
const { packages, workspaceDir } = await getWorkspaceData(cwd, cleanConfig?.includePrivate ?? true ? { ignorePrivatePackage: false } : void 0);
|
|
588
589
|
const filteredPackages = packages.filter((pkg) => {
|
|
589
590
|
const name$2 = pkg.manifest.name ?? "";
|
|
590
591
|
if (!name$2) return true;
|
|
@@ -604,7 +605,8 @@ async function cleanProjects(cwd, overrides) {
|
|
|
604
605
|
};
|
|
605
606
|
})
|
|
606
607
|
});
|
|
607
|
-
const
|
|
608
|
+
const readmeZh = pathe.default.resolve(workspaceDir, "README.zh-CN.md");
|
|
609
|
+
const candidates = Array.from(new Set([...cleanDirs.filter(Boolean), readmeZh]));
|
|
608
610
|
await Promise.all(candidates.map(async (dir) => {
|
|
609
611
|
if (await fs_extra.default.pathExists(dir)) await fs_extra.default.remove(dir);
|
|
610
612
|
}));
|
|
@@ -617,7 +619,7 @@ async function cleanProjects(cwd, overrides) {
|
|
|
617
619
|
//#endregion
|
|
618
620
|
//#region package.json
|
|
619
621
|
var name = "@icebreakers/monorepo";
|
|
620
|
-
var version = "3.1.
|
|
622
|
+
var version = "3.1.8";
|
|
621
623
|
|
|
622
624
|
//#endregion
|
|
623
625
|
//#region src/constants.ts
|
|
@@ -655,6 +657,43 @@ function isIgnorableFsError(error) {
|
|
|
655
657
|
return code === "ENOENT" || code === "EBUSY" || code === "EEXIST";
|
|
656
658
|
}
|
|
657
659
|
|
|
660
|
+
//#endregion
|
|
661
|
+
//#region src/utils/github.ts
|
|
662
|
+
/**
|
|
663
|
+
* 将 Issue 模版里的 discussions 链接同步为当前仓库的 discussions 地址。
|
|
664
|
+
*/
|
|
665
|
+
function updateIssueTemplateConfig(source, repoName) {
|
|
666
|
+
if (!repoName) return source;
|
|
667
|
+
let doc;
|
|
668
|
+
try {
|
|
669
|
+
doc = (0, yaml.parseDocument)(source);
|
|
670
|
+
} catch {
|
|
671
|
+
return source;
|
|
672
|
+
}
|
|
673
|
+
const contactLinks = doc.get("contact_links");
|
|
674
|
+
if (!(0, yaml.isSeq)(contactLinks)) return source;
|
|
675
|
+
const nextUrl = `https://github.com/${repoName}/discussions`;
|
|
676
|
+
let changed = false;
|
|
677
|
+
contactLinks.items.forEach((_, index) => {
|
|
678
|
+
const url = doc.getIn([
|
|
679
|
+
"contact_links",
|
|
680
|
+
index,
|
|
681
|
+
"url"
|
|
682
|
+
]);
|
|
683
|
+
if (typeof url !== "string") return;
|
|
684
|
+
if (!url.includes("/discussions")) return;
|
|
685
|
+
if (url === nextUrl) return;
|
|
686
|
+
doc.setIn([
|
|
687
|
+
"contact_links",
|
|
688
|
+
index,
|
|
689
|
+
"url"
|
|
690
|
+
], nextUrl);
|
|
691
|
+
changed = true;
|
|
692
|
+
});
|
|
693
|
+
if (!changed) return source;
|
|
694
|
+
return doc.toString();
|
|
695
|
+
}
|
|
696
|
+
|
|
658
697
|
//#endregion
|
|
659
698
|
//#region src/utils/gitignore.ts
|
|
660
699
|
/**
|
|
@@ -912,6 +951,21 @@ async function setChangeset_default(ctx) {
|
|
|
912
951
|
}
|
|
913
952
|
}
|
|
914
953
|
|
|
954
|
+
//#endregion
|
|
955
|
+
//#region src/commands/init/setIssueTemplateConfig.ts
|
|
956
|
+
/**
|
|
957
|
+
* 同步 Issue 模版里的 discussions 链接到当前仓库。
|
|
958
|
+
*/
|
|
959
|
+
async function setIssueTemplateConfig_default(ctx) {
|
|
960
|
+
const repoName = ctx.gitUrl?.full_name;
|
|
961
|
+
if (!repoName) return;
|
|
962
|
+
const configPath = pathe.default.resolve(ctx.cwd, ".github/ISSUE_TEMPLATE/config.yml");
|
|
963
|
+
if (!await fs_extra.default.pathExists(configPath)) return;
|
|
964
|
+
const source = await fs_extra.default.readFile(configPath, "utf8");
|
|
965
|
+
const next = updateIssueTemplateConfig(source, repoName);
|
|
966
|
+
if (next !== source) await fs_extra.default.writeFile(configPath, next, "utf8");
|
|
967
|
+
}
|
|
968
|
+
|
|
915
969
|
//#endregion
|
|
916
970
|
//#region src/commands/init/setPkgJson.ts
|
|
917
971
|
var import_set_value$2 = /* @__PURE__ */ __toESM(require_set_value(), 1);
|
|
@@ -996,6 +1050,7 @@ async function init(cwd) {
|
|
|
996
1050
|
if (!initConfig.skipChangeset) await setChangeset_default(ctx);
|
|
997
1051
|
if (!initConfig.skipPkgJson) await setPkgJson_default(ctx);
|
|
998
1052
|
if (!initConfig.skipReadme) await setReadme_default(ctx);
|
|
1053
|
+
if (!initConfig.skipIssueTemplateConfig) await setIssueTemplateConfig_default(ctx);
|
|
999
1054
|
}
|
|
1000
1055
|
|
|
1001
1056
|
//#endregion
|
|
@@ -1441,6 +1496,24 @@ async function upgradeMonorepo(opts) {
|
|
|
1441
1496
|
});
|
|
1442
1497
|
continue;
|
|
1443
1498
|
}
|
|
1499
|
+
if (relPath === ".github/ISSUE_TEMPLATE/config.yml") {
|
|
1500
|
+
const data = updateIssueTemplateConfig(await fs_extra.default.readFile(file.path, "utf8"), repoName);
|
|
1501
|
+
const intent$1 = await evaluateWriteIntent(targetPath, {
|
|
1502
|
+
skipOverwrite,
|
|
1503
|
+
source: data
|
|
1504
|
+
});
|
|
1505
|
+
const action$1 = async () => {
|
|
1506
|
+
await fs_extra.default.outputFile(targetPath, data);
|
|
1507
|
+
logger.success(targetPath);
|
|
1508
|
+
};
|
|
1509
|
+
await scheduleOverwrite(intent$1, {
|
|
1510
|
+
relPath,
|
|
1511
|
+
targetPath,
|
|
1512
|
+
action: action$1,
|
|
1513
|
+
pending: pendingOverwrites
|
|
1514
|
+
});
|
|
1515
|
+
continue;
|
|
1516
|
+
}
|
|
1444
1517
|
const source = await fs_extra.default.readFile(file.path);
|
|
1445
1518
|
const intent = await evaluateWriteIntent(targetPath, {
|
|
1446
1519
|
skipOverwrite,
|
|
@@ -1681,6 +1754,12 @@ Object.defineProperty(exports, 'toWorkspaceGitignorePath', {
|
|
|
1681
1754
|
return toWorkspaceGitignorePath;
|
|
1682
1755
|
}
|
|
1683
1756
|
});
|
|
1757
|
+
Object.defineProperty(exports, 'updateIssueTemplateConfig', {
|
|
1758
|
+
enumerable: true,
|
|
1759
|
+
get: function () {
|
|
1760
|
+
return updateIssueTemplateConfig;
|
|
1761
|
+
}
|
|
1762
|
+
});
|
|
1684
1763
|
Object.defineProperty(exports, 'upgradeMonorepo', {
|
|
1685
1764
|
enumerable: true,
|
|
1686
1765
|
get: function () {
|
|
@@ -12,6 +12,7 @@ import { loadConfig } from "c12";
|
|
|
12
12
|
import pc from "picocolors";
|
|
13
13
|
import path$1 from "node:path";
|
|
14
14
|
import { fileURLToPath } from "node:url";
|
|
15
|
+
import YAML, { isSeq, parseDocument } from "yaml";
|
|
15
16
|
import crypto from "node:crypto";
|
|
16
17
|
import "@pnpm/types";
|
|
17
18
|
import { parse, stringify } from "comment-json";
|
|
@@ -19,7 +20,6 @@ import os from "node:os";
|
|
|
19
20
|
import { execaCommand } from "execa";
|
|
20
21
|
import PQueue from "p-queue";
|
|
21
22
|
import klaw from "klaw";
|
|
22
|
-
import YAML from "yaml";
|
|
23
23
|
import { Buffer as Buffer$1 } from "node:buffer";
|
|
24
24
|
import { coerce, gte, minVersion } from "semver";
|
|
25
25
|
|
|
@@ -560,10 +560,11 @@ async function resolveCommandConfig(name$1, cwd) {
|
|
|
560
560
|
//#region src/commands/clean.ts
|
|
561
561
|
var import_set_value$5 = /* @__PURE__ */ __toESM(require_set_value(), 1);
|
|
562
562
|
function mergeCleanConfig(base, overrides) {
|
|
563
|
-
|
|
563
|
+
const normalizedBase = base ?? {};
|
|
564
|
+
if (!overrides) return normalizedBase;
|
|
564
565
|
const definedOverrides = Object.fromEntries(Object.entries(overrides).filter(([, value]) => value !== void 0));
|
|
565
566
|
return {
|
|
566
|
-
...
|
|
567
|
+
...normalizedBase,
|
|
567
568
|
...definedOverrides
|
|
568
569
|
};
|
|
569
570
|
}
|
|
@@ -572,7 +573,7 @@ function mergeCleanConfig(base, overrides) {
|
|
|
572
573
|
*/
|
|
573
574
|
async function cleanProjects(cwd, overrides) {
|
|
574
575
|
const cleanConfig = mergeCleanConfig(await resolveCommandConfig("clean", cwd), overrides);
|
|
575
|
-
const { packages, workspaceDir } = await getWorkspaceData(cwd, cleanConfig?.includePrivate ? { ignorePrivatePackage: false } : void 0);
|
|
576
|
+
const { packages, workspaceDir } = await getWorkspaceData(cwd, cleanConfig?.includePrivate ?? true ? { ignorePrivatePackage: false } : void 0);
|
|
576
577
|
const filteredPackages = packages.filter((pkg) => {
|
|
577
578
|
const name$2 = pkg.manifest.name ?? "";
|
|
578
579
|
if (!name$2) return true;
|
|
@@ -592,7 +593,8 @@ async function cleanProjects(cwd, overrides) {
|
|
|
592
593
|
};
|
|
593
594
|
})
|
|
594
595
|
});
|
|
595
|
-
const
|
|
596
|
+
const readmeZh = path.resolve(workspaceDir, "README.zh-CN.md");
|
|
597
|
+
const candidates = Array.from(new Set([...cleanDirs.filter(Boolean), readmeZh]));
|
|
596
598
|
await Promise.all(candidates.map(async (dir) => {
|
|
597
599
|
if (await fs.pathExists(dir)) await fs.remove(dir);
|
|
598
600
|
}));
|
|
@@ -605,7 +607,7 @@ async function cleanProjects(cwd, overrides) {
|
|
|
605
607
|
//#endregion
|
|
606
608
|
//#region package.json
|
|
607
609
|
var name = "@icebreakers/monorepo";
|
|
608
|
-
var version = "3.1.
|
|
610
|
+
var version = "3.1.8";
|
|
609
611
|
|
|
610
612
|
//#endregion
|
|
611
613
|
//#region src/constants.ts
|
|
@@ -643,6 +645,43 @@ function isIgnorableFsError(error) {
|
|
|
643
645
|
return code === "ENOENT" || code === "EBUSY" || code === "EEXIST";
|
|
644
646
|
}
|
|
645
647
|
|
|
648
|
+
//#endregion
|
|
649
|
+
//#region src/utils/github.ts
|
|
650
|
+
/**
|
|
651
|
+
* 将 Issue 模版里的 discussions 链接同步为当前仓库的 discussions 地址。
|
|
652
|
+
*/
|
|
653
|
+
function updateIssueTemplateConfig(source, repoName) {
|
|
654
|
+
if (!repoName) return source;
|
|
655
|
+
let doc;
|
|
656
|
+
try {
|
|
657
|
+
doc = parseDocument(source);
|
|
658
|
+
} catch {
|
|
659
|
+
return source;
|
|
660
|
+
}
|
|
661
|
+
const contactLinks = doc.get("contact_links");
|
|
662
|
+
if (!isSeq(contactLinks)) return source;
|
|
663
|
+
const nextUrl = `https://github.com/${repoName}/discussions`;
|
|
664
|
+
let changed = false;
|
|
665
|
+
contactLinks.items.forEach((_, index) => {
|
|
666
|
+
const url = doc.getIn([
|
|
667
|
+
"contact_links",
|
|
668
|
+
index,
|
|
669
|
+
"url"
|
|
670
|
+
]);
|
|
671
|
+
if (typeof url !== "string") return;
|
|
672
|
+
if (!url.includes("/discussions")) return;
|
|
673
|
+
if (url === nextUrl) return;
|
|
674
|
+
doc.setIn([
|
|
675
|
+
"contact_links",
|
|
676
|
+
index,
|
|
677
|
+
"url"
|
|
678
|
+
], nextUrl);
|
|
679
|
+
changed = true;
|
|
680
|
+
});
|
|
681
|
+
if (!changed) return source;
|
|
682
|
+
return doc.toString();
|
|
683
|
+
}
|
|
684
|
+
|
|
646
685
|
//#endregion
|
|
647
686
|
//#region src/utils/gitignore.ts
|
|
648
687
|
/**
|
|
@@ -900,6 +939,21 @@ async function setChangeset_default(ctx) {
|
|
|
900
939
|
}
|
|
901
940
|
}
|
|
902
941
|
|
|
942
|
+
//#endregion
|
|
943
|
+
//#region src/commands/init/setIssueTemplateConfig.ts
|
|
944
|
+
/**
|
|
945
|
+
* 同步 Issue 模版里的 discussions 链接到当前仓库。
|
|
946
|
+
*/
|
|
947
|
+
async function setIssueTemplateConfig_default(ctx) {
|
|
948
|
+
const repoName = ctx.gitUrl?.full_name;
|
|
949
|
+
if (!repoName) return;
|
|
950
|
+
const configPath = path.resolve(ctx.cwd, ".github/ISSUE_TEMPLATE/config.yml");
|
|
951
|
+
if (!await fs.pathExists(configPath)) return;
|
|
952
|
+
const source = await fs.readFile(configPath, "utf8");
|
|
953
|
+
const next = updateIssueTemplateConfig(source, repoName);
|
|
954
|
+
if (next !== source) await fs.writeFile(configPath, next, "utf8");
|
|
955
|
+
}
|
|
956
|
+
|
|
903
957
|
//#endregion
|
|
904
958
|
//#region src/commands/init/setPkgJson.ts
|
|
905
959
|
var import_set_value$2 = /* @__PURE__ */ __toESM(require_set_value(), 1);
|
|
@@ -984,6 +1038,7 @@ async function init(cwd) {
|
|
|
984
1038
|
if (!initConfig.skipChangeset) await setChangeset_default(ctx);
|
|
985
1039
|
if (!initConfig.skipPkgJson) await setPkgJson_default(ctx);
|
|
986
1040
|
if (!initConfig.skipReadme) await setReadme_default(ctx);
|
|
1041
|
+
if (!initConfig.skipIssueTemplateConfig) await setIssueTemplateConfig_default(ctx);
|
|
987
1042
|
}
|
|
988
1043
|
|
|
989
1044
|
//#endregion
|
|
@@ -1429,6 +1484,24 @@ async function upgradeMonorepo(opts) {
|
|
|
1429
1484
|
});
|
|
1430
1485
|
continue;
|
|
1431
1486
|
}
|
|
1487
|
+
if (relPath === ".github/ISSUE_TEMPLATE/config.yml") {
|
|
1488
|
+
const data = updateIssueTemplateConfig(await fs.readFile(file.path, "utf8"), repoName);
|
|
1489
|
+
const intent$1 = await evaluateWriteIntent(targetPath, {
|
|
1490
|
+
skipOverwrite,
|
|
1491
|
+
source: data
|
|
1492
|
+
});
|
|
1493
|
+
const action$1 = async () => {
|
|
1494
|
+
await fs.outputFile(targetPath, data);
|
|
1495
|
+
logger.success(targetPath);
|
|
1496
|
+
};
|
|
1497
|
+
await scheduleOverwrite(intent$1, {
|
|
1498
|
+
relPath,
|
|
1499
|
+
targetPath,
|
|
1500
|
+
action: action$1,
|
|
1501
|
+
pending: pendingOverwrites
|
|
1502
|
+
});
|
|
1503
|
+
continue;
|
|
1504
|
+
}
|
|
1432
1505
|
const source = await fs.readFile(file.path);
|
|
1433
1506
|
const intent = await evaluateWriteIntent(targetPath, {
|
|
1434
1507
|
skipOverwrite,
|
|
@@ -1453,4 +1526,4 @@ async function upgradeMonorepo(opts) {
|
|
|
1453
1526
|
}
|
|
1454
1527
|
|
|
1455
1528
|
//#endregion
|
|
1456
|
-
export {
|
|
1529
|
+
export { createTimestampFolderName as A, templatesDir as C, defineMonorepoConfig as D, cleanProjects as E, logger as F, getWorkspaceData as I, getWorkspacePackages as L, generateAgenticTemplate as M, generateAgenticTemplates as N, loadMonorepoConfig as O, loadAgenticTasks as P, GitClient as R, rootDir as S, version as T, toWorkspaceGitignorePath as _, createContext as a, assetsDir as b, getCreateChoices as c, escapeStringRegexp as d, isMatch as f, toPublishGitignorePath as g, isGitignoreFile as h, init as i, defaultAgenticBaseDir as j, resolveCommandConfig 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, name as w, packageDir as x, isIgnorableFsError as y };
|
package/package.json
CHANGED
|
@@ -18,7 +18,7 @@ layout: doc
|
|
|
18
18
|
|
|
19
19
|
1. **拉取模板**:[GitHub](https://github.com/sonofmagic/monorepo-template) 右上角 `Use this template`,或克隆源码。
|
|
20
20
|
2. **安装依赖**:在 `pnpm-workspace.yaml` 所在目录执行 `pnpm install`(需要 Node.js ≥ 20,推荐 `npm i -g pnpm`)。
|
|
21
|
-
3.
|
|
21
|
+
3. **可选清理**:直接运行 `npx -y @icebreakers/monorepo@latest clean` 远程执行清理,移除演示包后再执行 `pnpm install`(避免依赖本地构建 `monorepo`);如已安装依赖,也可使用 `pnpm script:clean`。
|
|
22
22
|
4. **初始化元数据**:`pnpm script:init` 会批量更新 `package.json`、`README.md` 等公共信息。
|
|
23
23
|
|
|
24
24
|
## 仓库结构速览
|
|
@@ -49,7 +49,7 @@ layout: doc
|
|
|
49
49
|
|
|
50
50
|
```bash
|
|
51
51
|
npx monorepo new # 创建子包/应用
|
|
52
|
-
npx monorepo clean
|
|
52
|
+
npx -y @icebreakers/monorepo@latest clean # 远程清理已勾选的子项目,避免依赖本地构建
|
|
53
53
|
npx monorepo sync # 同步所有包到 npmmirror
|
|
54
54
|
npx monorepo mirror # 写入 VS Code 镜像配置
|
|
55
55
|
npx monorepo up # 从最新模板同步配置文件
|
|
@@ -98,8 +98,11 @@ jobs:
|
|
|
98
98
|
- uses: pnpm/action-setup@v4
|
|
99
99
|
- uses: actions/setup-node@v4
|
|
100
100
|
with:
|
|
101
|
-
|
|
101
|
+
# 这是为了使用新版本的 npm, 只有 npm@11.5.x 以上版本才支持 OIDC
|
|
102
|
+
# 否则你就必须使用 npm i -g npm@latest 来升级 npm 版本
|
|
103
|
+
node-version: 24
|
|
102
104
|
cache: pnpm
|
|
105
|
+
registry-url: https://registry.npmjs.org
|
|
103
106
|
- run: pnpm install
|
|
104
107
|
- name: Create Release Pull Request or Publish to npm
|
|
105
108
|
uses: changesets/action@v1
|
|
@@ -107,11 +110,13 @@ jobs:
|
|
|
107
110
|
publish: pnpm publish-packages
|
|
108
111
|
env:
|
|
109
112
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
110
|
-
|
|
113
|
+
# npm/action-oidc-auth 会设置 NODE_AUTH_TOKEN 供 publish 使用
|
|
111
114
|
```
|
|
112
115
|
|
|
113
116
|
`pnpm publish-packages` 为模板内脚本,可替换为自定义构建+发布流程。
|
|
114
117
|
|
|
118
|
+
> 说明:npm 现行 token 默认 90 天过期,推荐在 CI 中使用 OIDC(如上)动态获取 `NODE_AUTH_TOKEN`,无需手动传入 `NPM_TOKEN`。若使用自托管或其他 CI,需要确保工作流具备 `id-token: write` 权限。
|
|
119
|
+
|
|
115
120
|
## 与其他方案对比
|
|
116
121
|
|
|
117
122
|
| 能力 / 工具 | changesets | lerna 经典模式 | 手写脚本 |
|
|
@@ -68,7 +68,7 @@ registry.npmjs.org/:_authToken=npm_hashhashhashhashhashhashhashhashhash
|
|
|
68
68
|
|
|
69
69
|
假如这一行存在,说明你本地的 `npm Access Token` 就设置好了,然后你才有发包的权限。
|
|
70
70
|
|
|
71
|
-
> 你也可以在 `https://www.npmjs.com/settings/<你的用户名>/tokens` 中管理你的 `token`,给不同的 `token`
|
|
71
|
+
> 你也可以在 `https://www.npmjs.com/settings/<你的用户名>/tokens` 中管理你的 `token`,给不同的 `token` 设置不同的作用域,有效期(目前最长 90 天)和 `ip` 限制,帮助你适配正常开发,`CI/CD`,`Token` 分发的各种场景;如需避免手动轮换,CI 场景推荐使用 npm 官方的 OIDC 方案获取临时 `NODE_AUTH_TOKEN`,并在工作流开启 `id-token: write` 权限。
|
|
72
72
|
|
|
73
73
|
同样发私有源包也是同理:
|
|
74
74
|
|