@infly/libs 2.0.49 → 2.0.51
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/README.md +45 -5
- package/adapters/vue2/project-preview.js +152 -152
- package/{tools → adapters/webpack}/auto-export.js +56 -55
- package/bin/cli.js +1 -1
- package/build/build-dist/index.js +866 -866
- package/build/docker/compose-command.js +74 -74
- package/build/docker/release-docker.js +70 -6
- package/build/index.js +34 -0
- package/{tools/file-process.js → build/project-files.js} +55 -52
- package/{tools → cli}/progress.js +67 -63
- package/{tools → cli}/project-command.js +206 -198
- package/{tools → cli}/select-option.js +61 -60
- package/{tools → core/async}/concurrency.js +31 -30
- package/package.json +19 -5
- package/release/npm-plan.js +51 -0
- package/script/git-automation/submodule-utils.js +22 -18
- package/{tools/workspace-config.js → workspace/config.js} +146 -145
- package/workspace/packages.js +91 -0
- package/adapters/vue2/vite/index.js +0 -95
- package/adapters/vue2/vite/jest.config.js +0 -11
- package/tools/format.js +0 -31
- package/tools/project-preview.js +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@infly/libs",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.51",
|
|
4
4
|
"description": "不受前端框架限制的独立工具库",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -8,12 +8,16 @@
|
|
|
8
8
|
"index.js",
|
|
9
9
|
"bin/",
|
|
10
10
|
"compat/",
|
|
11
|
+
"core/",
|
|
12
|
+
"cli/",
|
|
11
13
|
"adapters/vue2/",
|
|
14
|
+
"adapters/webpack/",
|
|
12
15
|
"build/",
|
|
13
16
|
"module/",
|
|
14
17
|
"script/git-automation/",
|
|
15
18
|
"script/index.js",
|
|
16
|
-
"
|
|
19
|
+
"release/",
|
|
20
|
+
"workspace/",
|
|
17
21
|
"README.md",
|
|
18
22
|
"LICENSE",
|
|
19
23
|
"!**/*.test.js",
|
|
@@ -39,11 +43,21 @@
|
|
|
39
43
|
},
|
|
40
44
|
"exports": {
|
|
41
45
|
".": "./index.js",
|
|
46
|
+
"./build": "./build/index.js",
|
|
47
|
+
"./concurrency": "./core/async/concurrency.js",
|
|
48
|
+
"./progress": "./cli/progress.js",
|
|
49
|
+
"./npm-release": "./release/npm-plan.js",
|
|
50
|
+
"./workspace-packages": "./workspace/packages.js",
|
|
51
|
+
"./workspace-config": "./workspace/config.js",
|
|
52
|
+
"./cli/project-command": "./cli/project-command.js",
|
|
53
|
+
"./cli/select-option": "./cli/select-option.js",
|
|
54
|
+
"./adapters/webpack/auto-export": "./adapters/webpack/auto-export.js",
|
|
55
|
+
"./git/configure": "./script/git-automation/git-configure.js",
|
|
56
|
+
"./git/submodule-status": "./script/git-automation/submodule-status.js",
|
|
57
|
+
"./git/submodules": "./script/git-automation/submodule-utils.js",
|
|
42
58
|
"./adapters/vue2/*": "./adapters/vue2/*",
|
|
43
|
-
"./adapters/vue2/build/*": "./adapters/vue2/build/*",
|
|
44
59
|
"./module/*": "./module/*",
|
|
45
60
|
"./store/*": "./adapters/vue2/store/*",
|
|
46
|
-
"./tools/*": "./tools/*",
|
|
47
61
|
"./build/*": "./build/*",
|
|
48
62
|
"./build/build-utils/*": "./build/build-utils/*",
|
|
49
63
|
"./script/git-automation/*": "./script/git-automation/*"
|
|
@@ -60,7 +74,7 @@
|
|
|
60
74
|
"author": "Kahal",
|
|
61
75
|
"license": "ISC",
|
|
62
76
|
"dependencies": {
|
|
63
|
-
"@infly/ts-libs": "
|
|
77
|
+
"@infly/ts-libs": "^0.1.12",
|
|
64
78
|
"connect": "^3.7.0",
|
|
65
79
|
"dotenv": "16.6.1",
|
|
66
80
|
"enquirer": "^2.4.1",
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// 无副作用的 npm 稳定版本与发布计划计算。
|
|
2
|
+
function parseStableVersion(version) {
|
|
3
|
+
const match = /^(\d+)\.(\d+)\.(\d+)$/.exec(String(version));
|
|
4
|
+
if (!match) throw new Error(`不支持的版本号: ${version}`);
|
|
5
|
+
return match.slice(1).map(Number);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function bumpPatch(version) {
|
|
9
|
+
const parts = parseStableVersion(version);
|
|
10
|
+
parts[2] += 1;
|
|
11
|
+
return parts.join(".");
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function compareVersions(left, right) {
|
|
15
|
+
const a = parseStableVersion(left);
|
|
16
|
+
const b = parseStableVersion(right);
|
|
17
|
+
for (let index = 0; index < 3; index += 1) {
|
|
18
|
+
if (a[index] !== b[index]) return a[index] > b[index] ? 1 : -1;
|
|
19
|
+
}
|
|
20
|
+
return 0;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function buildReleasePlan(packages, registryVersions, options = {}) {
|
|
24
|
+
const prepared = Boolean(options.prepared);
|
|
25
|
+
return packages.map((pkg) => {
|
|
26
|
+
const registryVersion = registryVersions[pkg.name];
|
|
27
|
+
// registryVersion 为空表示包从未发布(npm view 404),按首次发布处理:
|
|
28
|
+
// 直接发布本地版本,不做 patch bump,也无需写回 package.json
|
|
29
|
+
if (!registryVersion) {
|
|
30
|
+
return {
|
|
31
|
+
...pkg,
|
|
32
|
+
registryVersion: null,
|
|
33
|
+
targetVersion: pkg.version,
|
|
34
|
+
needsVersionWrite: false,
|
|
35
|
+
isFirstRelease: true,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
const comparison = compareVersions(pkg.version, registryVersion);
|
|
39
|
+
if (comparison < 0) {
|
|
40
|
+
throw new Error(`${pkg.name} 本地版本 ${pkg.version} 落后于 npm ${registryVersion}`);
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
...pkg,
|
|
44
|
+
registryVersion,
|
|
45
|
+
targetVersion: comparison === 0 && !prepared ? bumpPatch(pkg.version) : pkg.version,
|
|
46
|
+
needsVersionWrite: comparison === 0 && !prepared,
|
|
47
|
+
};
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
module.exports = { buildReleasePlan, bumpPatch, compareVersions, parseStableVersion };
|
|
@@ -1,18 +1,22 @@
|
|
|
1
|
-
const fs = require("fs");
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
|
|
3
|
+
function normalizeRelativePath(value) {
|
|
4
|
+
return String(value).replace(/\\/g, "/");
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 从 .gitmodules 中解析所有子模块路径
|
|
9
|
+
*/
|
|
10
|
+
function parseGitmodulesPaths(rootDir) {
|
|
11
|
+
const p = require("path").join(rootDir, ".gitmodules");
|
|
12
|
+
if (!fs.existsSync(p)) return [];
|
|
13
|
+
const content = fs.readFileSync(p, "utf8");
|
|
14
|
+
const paths = [];
|
|
15
|
+
content.split(/\[submodule/).forEach((block) => {
|
|
16
|
+
const m = block.match(/path\s*=\s*(.+)/);
|
|
17
|
+
if (m) paths.push(m[1].trim());
|
|
18
|
+
});
|
|
19
|
+
return paths;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
module.exports = { normalizeRelativePath, parseGitmodulesPaths };
|
|
@@ -1,145 +1,146 @@
|
|
|
1
|
-
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const
|
|
65
|
-
const
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
.
|
|
77
|
-
.filter((entry) =>
|
|
78
|
-
.
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
1
|
+
// workspace 配置读取与模式展开。
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
const path = require("path");
|
|
4
|
+
const YAML = require("yaml");
|
|
5
|
+
|
|
6
|
+
function readJson(filePath) {
|
|
7
|
+
return JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function readWorkspaceList(content, sectionName) {
|
|
11
|
+
let workspaceConfig;
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
workspaceConfig = YAML.parse(content);
|
|
15
|
+
} catch (error) {
|
|
16
|
+
throw new Error(`无法解析 pnpm-workspace.yaml: ${error.message}`, { cause: error });
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (workspaceConfig == null) {
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (typeof workspaceConfig !== "object" || Array.isArray(workspaceConfig)) {
|
|
24
|
+
throw new TypeError("pnpm-workspace.yaml 的根节点必须是对象");
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const patterns = workspaceConfig[sectionName];
|
|
28
|
+
|
|
29
|
+
if (patterns == null) {
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (
|
|
34
|
+
!Array.isArray(patterns)
|
|
35
|
+
|| patterns.some((pattern) => typeof pattern !== "string" || pattern.trim().length === 0)
|
|
36
|
+
) {
|
|
37
|
+
throw new TypeError(`pnpm-workspace.yaml 的 ${sectionName} 必须是非空字符串数组`);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return patterns;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function readWorkspaceSection(workspaceFile, sectionName) {
|
|
44
|
+
return readWorkspaceList(fs.readFileSync(workspaceFile, "utf8"), sectionName);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function readWorkspaceSectionWithFallback(workspaceFile, sectionName, fallbackSectionName) {
|
|
48
|
+
const patterns = readWorkspaceSection(workspaceFile, sectionName);
|
|
49
|
+
|
|
50
|
+
if (patterns.length > 0) {
|
|
51
|
+
return patterns;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return readWorkspaceSection(workspaceFile, fallbackSectionName);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function expandWorkspacePattern(rootDir, pattern) {
|
|
58
|
+
const normalizedPattern = pattern.replace(/\\/g, "/");
|
|
59
|
+
|
|
60
|
+
if (!normalizedPattern.includes("*")) {
|
|
61
|
+
return [path.join(rootDir, normalizedPattern)];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const starIndex = normalizedPattern.indexOf("*");
|
|
65
|
+
const basePart = normalizedPattern.slice(0, starIndex);
|
|
66
|
+
const suffixPart = normalizedPattern.slice(starIndex + 1);
|
|
67
|
+
const baseDir = path.join(rootDir, basePart);
|
|
68
|
+
|
|
69
|
+
if (!fs.existsSync(baseDir)) {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const suffixIsNamePattern = suffixPart && !suffixPart.startsWith("/");
|
|
74
|
+
|
|
75
|
+
return fs
|
|
76
|
+
.readdirSync(baseDir, { withFileTypes: true })
|
|
77
|
+
.filter((entry) => entry.isDirectory())
|
|
78
|
+
.filter((entry) => !suffixIsNamePattern || entry.name.endsWith(suffixPart))
|
|
79
|
+
.map((entry) => (suffixIsNamePattern
|
|
80
|
+
? path.join(baseDir, entry.name)
|
|
81
|
+
: path.join(baseDir, entry.name, suffixPart)))
|
|
82
|
+
.filter((packageDir) => fs.existsSync(path.join(packageDir, "package.json")));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function getWorkspacePackages(rootDir, workspaceFile, sectionName, fallbackSectionName, scriptName) {
|
|
86
|
+
const patterns = fallbackSectionName
|
|
87
|
+
? readWorkspaceSectionWithFallback(workspaceFile, sectionName, fallbackSectionName)
|
|
88
|
+
: readWorkspaceSection(workspaceFile, sectionName);
|
|
89
|
+
const included = new Set();
|
|
90
|
+
patterns.forEach((pattern) => {
|
|
91
|
+
const excluded = pattern.startsWith("!");
|
|
92
|
+
const resolvedPattern = excluded ? pattern.slice(1) : pattern;
|
|
93
|
+
expandWorkspacePattern(rootDir, resolvedPattern).forEach((packageDir) => {
|
|
94
|
+
const resolvedDir = path.resolve(packageDir);
|
|
95
|
+
if (excluded) included.delete(resolvedDir);
|
|
96
|
+
else included.add(resolvedDir);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
const packageDirs = [...included];
|
|
100
|
+
const seen = new Set();
|
|
101
|
+
|
|
102
|
+
return packageDirs
|
|
103
|
+
.map((packageDir) => {
|
|
104
|
+
const packageJsonPath = path.join(packageDir, "package.json");
|
|
105
|
+
|
|
106
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const packageJson = readJson(packageJsonPath);
|
|
111
|
+
const scripts = packageJson.scripts || {};
|
|
112
|
+
|
|
113
|
+
if (!packageJson.name || seen.has(packageJson.name) || (scriptName && !scripts[scriptName])) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
seen.add(packageJson.name);
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
name: packageJson.name,
|
|
121
|
+
dir: path.relative(rootDir, packageDir),
|
|
122
|
+
packageJson,
|
|
123
|
+
};
|
|
124
|
+
})
|
|
125
|
+
.filter(Boolean);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function toTurboFilter(value) {
|
|
129
|
+
const normalized = value.replace(/\\/g, "/");
|
|
130
|
+
|
|
131
|
+
if (normalized.includes("/") && !normalized.startsWith("./") && !normalized.startsWith("../")) {
|
|
132
|
+
return `./${normalized}`;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return normalized;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
module.exports = {
|
|
139
|
+
expandWorkspacePattern,
|
|
140
|
+
getWorkspacePackages,
|
|
141
|
+
readJson,
|
|
142
|
+
readWorkspaceList,
|
|
143
|
+
readWorkspaceSection,
|
|
144
|
+
readWorkspaceSectionWithFallback,
|
|
145
|
+
toTurboFilter,
|
|
146
|
+
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// workspace 包发现、依赖图与变更影响计算。
|
|
2
|
+
const fs = require("node:fs");
|
|
3
|
+
const path = require("node:path");
|
|
4
|
+
|
|
5
|
+
const DEPENDENCY_SECTIONS = [
|
|
6
|
+
"dependencies",
|
|
7
|
+
"devDependencies",
|
|
8
|
+
"peerDependencies",
|
|
9
|
+
"optionalDependencies",
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
function normalizeWorkspacePath(filePath) {
|
|
13
|
+
return String(filePath || "").replace(/\\/g, "/").replace(/^\.\//, "");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function discoverWorkspacePackages(rootDir, options = {}) {
|
|
17
|
+
const packagesDirectory = options.packagesDirectory || "packages";
|
|
18
|
+
const packagesDir = path.join(rootDir, packagesDirectory);
|
|
19
|
+
const include = options.include || (() => true);
|
|
20
|
+
|
|
21
|
+
const packages = fs.readdirSync(packagesDir, { withFileTypes: true })
|
|
22
|
+
.filter((entry) => entry.isDirectory())
|
|
23
|
+
.map((entry) => {
|
|
24
|
+
const directoryPath = path.join(packagesDir, entry.name);
|
|
25
|
+
const manifestPath = path.join(directoryPath, "package.json");
|
|
26
|
+
if (!fs.existsSync(manifestPath)) return null;
|
|
27
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
|
|
28
|
+
const pkg = {
|
|
29
|
+
dir: entry.name,
|
|
30
|
+
directoryPath,
|
|
31
|
+
manifest,
|
|
32
|
+
manifestPath,
|
|
33
|
+
name: manifest.name,
|
|
34
|
+
relativeDir: normalizeWorkspacePath(path.join(packagesDirectory, entry.name)),
|
|
35
|
+
version: manifest.version,
|
|
36
|
+
};
|
|
37
|
+
return include(pkg) ? pkg : null;
|
|
38
|
+
})
|
|
39
|
+
.filter(Boolean);
|
|
40
|
+
return options.sort === false
|
|
41
|
+
? packages
|
|
42
|
+
: packages.sort((left, right) => left.relativeDir.localeCompare(right.relativeDir));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function getInternalDependencies(pkg, packageNames) {
|
|
46
|
+
const dependencies = new Set();
|
|
47
|
+
for (const section of DEPENDENCY_SECTIONS) {
|
|
48
|
+
for (const dependencyName of Object.keys(pkg.manifest?.[section] || {})) {
|
|
49
|
+
if (packageNames.has(dependencyName)) dependencies.add(dependencyName);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return dependencies;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function selectAffectedWorkspacePackages(changedPaths, packages, options = {}) {
|
|
56
|
+
const normalizedPaths = changedPaths.map(normalizeWorkspacePath).filter(Boolean);
|
|
57
|
+
const isGlobalChange = options.isGlobalChange || (() => false);
|
|
58
|
+
if (normalizedPaths.some(isGlobalChange)) return [...packages];
|
|
59
|
+
|
|
60
|
+
const selectedNames = new Set();
|
|
61
|
+
for (const pkg of packages) {
|
|
62
|
+
const relativeDir = normalizeWorkspacePath(pkg.relativeDir || `packages/${pkg.dir}`);
|
|
63
|
+
if (normalizedPaths.some((filePath) => filePath.startsWith(`${relativeDir}/`))) {
|
|
64
|
+
selectedNames.add(pkg.name);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const packageNames = new Set(packages.map((pkg) => pkg.name));
|
|
69
|
+
let changed = true;
|
|
70
|
+
while (changed) {
|
|
71
|
+
changed = false;
|
|
72
|
+
for (const pkg of packages) {
|
|
73
|
+
if (selectedNames.has(pkg.name)) continue;
|
|
74
|
+
const dependencies = getInternalDependencies(pkg, packageNames);
|
|
75
|
+
if ([...dependencies].some((dependency) => selectedNames.has(dependency))) {
|
|
76
|
+
selectedNames.add(pkg.name);
|
|
77
|
+
changed = true;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return packages.filter((pkg) => selectedNames.has(pkg.name));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
module.exports = {
|
|
86
|
+
DEPENDENCY_SECTIONS,
|
|
87
|
+
discoverWorkspacePackages,
|
|
88
|
+
getInternalDependencies,
|
|
89
|
+
normalizeWorkspacePath,
|
|
90
|
+
selectAffectedWorkspacePackages,
|
|
91
|
+
};
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
const fs = require("node:fs");
|
|
2
|
-
const path = require("node:path");
|
|
3
|
-
|
|
4
|
-
function findAdminMonorepoRoot(startDir = process.cwd()) {
|
|
5
|
-
let directory = path.resolve(startDir);
|
|
6
|
-
for (;;) {
|
|
7
|
-
if (
|
|
8
|
-
fs.existsSync(path.join(directory, "pnpm-workspace.yaml"))
|
|
9
|
-
&& fs.existsSync(path.join(directory, "configs/vite-configs/registry.js"))
|
|
10
|
-
) return directory;
|
|
11
|
-
const parent = path.dirname(directory);
|
|
12
|
-
if (parent === directory) return null;
|
|
13
|
-
directory = parent;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function resolveAppScssImport(importPath, importer, appRoot) {
|
|
18
|
-
const cleanImporter = importer.replace(/[?#].*$/, "");
|
|
19
|
-
if (importPath.startsWith("@/")) {
|
|
20
|
-
return path.resolve(appRoot, "src", importPath.slice(2));
|
|
21
|
-
}
|
|
22
|
-
if (importPath.startsWith("./") || importPath.startsWith("../")) {
|
|
23
|
-
return path.resolve(path.dirname(cleanImporter), importPath);
|
|
24
|
-
}
|
|
25
|
-
if (path.isAbsolute(importPath)) return path.resolve(importPath);
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function transformScssExportImports(code, importer, options) {
|
|
30
|
-
const { appRoot, readFile = (file) => fs.readFileSync(file, "utf8") } = options;
|
|
31
|
-
return code.replace(
|
|
32
|
-
/import\s+([\w$]+)\s+from\s+(["'])([^"'?]+\.scss)\2\s*;?/g,
|
|
33
|
-
(statement, binding, quote, importPath) => {
|
|
34
|
-
const resolved = resolveAppScssImport(importPath, importer, appRoot);
|
|
35
|
-
if (!resolved) return statement;
|
|
36
|
-
let scss;
|
|
37
|
-
try {
|
|
38
|
-
scss = readFile(resolved);
|
|
39
|
-
} catch (_) {
|
|
40
|
-
return statement;
|
|
41
|
-
}
|
|
42
|
-
if (typeof scss !== "string") return statement;
|
|
43
|
-
const exportBlock = scss.match(/:export\s*\{([\s\S]*?)\}/);
|
|
44
|
-
if (!exportBlock) return statement;
|
|
45
|
-
|
|
46
|
-
const variables = new Map();
|
|
47
|
-
for (const match of scss.matchAll(/^\s*\$([\w-]+)\s*:\s*([^;]+);/gm)) {
|
|
48
|
-
variables.set(match[1], match[2].trim());
|
|
49
|
-
}
|
|
50
|
-
const exported = {};
|
|
51
|
-
for (const match of exportBlock[1].matchAll(/([\w-]+)\s*:\s*([^;]+);/g)) {
|
|
52
|
-
const rawValue = match[2].trim();
|
|
53
|
-
const variableName = rawValue.match(/^\$([\w-]+)$/);
|
|
54
|
-
exported[match[1]] = variableName && variables.has(variableName[1])
|
|
55
|
-
? variables.get(variableName[1])
|
|
56
|
-
: rawValue;
|
|
57
|
-
}
|
|
58
|
-
return `import ${quote}${importPath}${quote};\nconst ${binding} = ${JSON.stringify(exported)};`;
|
|
59
|
-
},
|
|
60
|
-
);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function createScssExportCompatPlugin(appRoot) {
|
|
64
|
-
return {
|
|
65
|
-
name: "infly-vue2:scss-export-compat",
|
|
66
|
-
enforce: "pre",
|
|
67
|
-
transform(code, id) {
|
|
68
|
-
if (
|
|
69
|
-
id.includes("node_modules")
|
|
70
|
-
|| (!id.includes(".vue") && !/\.[cm]?[jt]sx?(?:[?#].*)?$/.test(id))
|
|
71
|
-
|| !/import\s+[\w$]+\s+from\s+["'][^"']+\.scss["']/.test(code)
|
|
72
|
-
) return null;
|
|
73
|
-
const transformed = transformScssExportImports(code, id, { appRoot });
|
|
74
|
-
return transformed === code ? null : { code: transformed, map: null };
|
|
75
|
-
},
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function addAppRootSassLoadPath(css, appRoot) {
|
|
80
|
-
if (!css.preprocessorOptions) css.preprocessorOptions = {};
|
|
81
|
-
if (!css.preprocessorOptions.scss) css.preprocessorOptions.scss = {};
|
|
82
|
-
const loadPaths = css.preprocessorOptions.scss.loadPaths || [];
|
|
83
|
-
const resolvedAppRoot = path.resolve(appRoot);
|
|
84
|
-
css.preprocessorOptions.scss.loadPaths = loadPaths.includes(resolvedAppRoot)
|
|
85
|
-
? loadPaths
|
|
86
|
-
: [...loadPaths, resolvedAppRoot];
|
|
87
|
-
return css;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
module.exports = {
|
|
91
|
-
addAppRootSassLoadPath,
|
|
92
|
-
findAdminMonorepoRoot,
|
|
93
|
-
transformScssExportImports,
|
|
94
|
-
createScssExportCompatPlugin,
|
|
95
|
-
};
|