























@@ -77,6 +77,15 @@ const OMITTED_DIST_SUBTREE_PATTERNS = [
7777] as const;
7878const INSTALL_STAGE_DEBRIS_DIR_PATTERN = /^\.openclaw-install-stage(?:-[^/]+)?$/iu;
7979type ExternalizedBundledExtensionIds = ReadonlySet<string>;
80+type PackageDistExclusionRules = {
81+files: ReadonlySet<string>;
82+prefixes: readonly string[];
83+patterns: readonly RegExp[];
84+};
85+type PackageDistInventoryRules = {
86+externalizedExtensionIds: ExternalizedBundledExtensionIds;
87+exclusions: PackageDistExclusionRules;
88+};
8089type PackageDistInventoryScanContext = {
8190activeFsOps: number;
8291fsConcurrency: number;
@@ -115,8 +124,12 @@ function isInstallStageDirName(value: string): boolean {
115124return INSTALL_STAGE_DEBRIS_DIR_PATTERN.test(value);
116125}
117126127+function splitRelativePath(relativePath: string): string[] {
128+return normalizeRelativePath(relativePath).split("/");
129+}
130+118131function isLegacyPluginDependencyDirPath(relativePath: string): boolean {
119-const parts = normalizeRelativePath(relativePath).split("/");
132+const parts = splitRelativePath(relativePath);
120133if (parts[0]?.toLowerCase() !== "dist" || parts[1]?.toLowerCase() !== "extensions") {
121134return false;
122135}
@@ -131,7 +144,7 @@ function isLegacyPluginDependencyDirPath(relativePath: string): boolean {
131144}
132145133146export function isLegacyPluginDependencyInstallStagePath(relativePath: string): boolean {
134-const parts = normalizeRelativePath(relativePath).split("/");
147+const parts = splitRelativePath(relativePath);
135148return (
136149parts.length >= 4 &&
137150parts[0]?.toLowerCase() === "dist" &&
@@ -141,25 +154,76 @@ export function isLegacyPluginDependencyInstallStagePath(relativePath: string):
141154);
142155}
143156144-function collectExcludedPackagedExtensionDirs(rootPackageJson: unknown): Set<string> {
157+function escapeRegExp(value: string): string {
158+return value.replace(/[\\^$+?.()|[\]{}]/g, "\\$&");
159+}
160+161+function compilePackageFilesExclusionPattern(pattern: string): RegExp {
162+let source = "^";
163+for (let index = 0; index < pattern.length; index += 1) {
164+const char = pattern[index];
165+if (char === "*") {
166+if (pattern[index + 1] === "*") {
167+source += ".*";
168+index += 1;
169+} else {
170+source += "[^/]*";
171+}
172+continue;
173+}
174+source += escapeRegExp(char ?? "");
175+}
176+source += "$";
177+return new RegExp(source, "u");
178+}
179+180+function collectPackageDistInventoryRules(rootPackageJson: unknown): PackageDistInventoryRules {
145181if (!rootPackageJson || typeof rootPackageJson !== "object") {
146-return new Set();
182+return {
183+externalizedExtensionIds: new Set(),
184+exclusions: { files: new Set(), prefixes: [], patterns: [] },
185+};
147186}
148187const files = (rootPackageJson as { files?: unknown }).files;
149188if (!Array.isArray(files)) {
150-return new Set();
189+return {
190+externalizedExtensionIds: new Set(),
191+exclusions: { files: new Set(), prefixes: [], patterns: [] },
192+};
151193}
152-const excluded = new Set<string>();
194+const externalizedExtensionIds = new Set<string>();
195+const excludedFiles = new Set<string>();
196+const excludedPrefixes: string[] = [];
197+const excludedPatterns: RegExp[] = [];
153198for (const entry of files) {
154199if (typeof entry !== "string") {
155200continue;
156201}
157-const match = /^!dist\/extensions\/([^/]+)\/\*\*$/u.exec(entry);
202+const normalized = normalizeRelativePath(entry);
203+const match = /^!dist\/extensions\/([^/]+)\/\*\*$/u.exec(normalized);
158204if (match?.[1]) {
159-excluded.add(match[1]);
205+externalizedExtensionIds.add(match[1]);
206+}
207+if (!normalized.startsWith("!dist/")) {
208+continue;
209+}
210+const excludedPath = normalized.slice(1);
211+if (excludedPath.endsWith("/**") && !excludedPath.slice(0, -3).includes("*")) {
212+excludedPrefixes.push(excludedPath.slice(0, -2));
213+} else if (excludedPath.includes("*")) {
214+excludedPatterns.push(compilePackageFilesExclusionPattern(excludedPath));
215+} else {
216+excludedFiles.add(excludedPath);
160217}
161218}
162-return excluded;
219+return {
220+ externalizedExtensionIds,
221+exclusions: {
222+files: excludedFiles,
223+prefixes: excludedPrefixes.toSorted((left, right) => left.localeCompare(right)),
224+patterns: excludedPatterns,
225+},
226+};
163227}
164228165229function isExternalizedBundledExtensionDistPath(
@@ -188,21 +252,35 @@ function isOmittedPluginSdkTestPath(relativePath: string): boolean {
188252);
189253}
190254191-async function collectExternalizedBundledExtensionIds(
255+async function collectPackageDistInventoryRulesForRoot(
192256packageRoot: string,
193-): Promise<ExternalizedBundledExtensionIds> {
257+): Promise<PackageDistInventoryRules> {
194258const packageJsonPath = path.join(packageRoot, "package.json");
195-return collectExcludedPackagedExtensionDirs(await readJsonIfExists<unknown>(packageJsonPath));
259+return collectPackageDistInventoryRules(await readJsonIfExists<unknown>(packageJsonPath));
260+}
261+262+function isPackageFilesExcludedDistPath(
263+relativePath: string,
264+exclusions: PackageDistExclusionRules,
265+): boolean {
266+return (
267+exclusions.files.has(relativePath) ||
268+exclusions.prefixes.some((prefix) => relativePath.startsWith(prefix)) ||
269+exclusions.patterns.some((pattern) => pattern.test(relativePath))
270+);
196271}
197272198273function isPackagedDistPath(
199274relativePath: string,
200-externalizedExtensionIds: ExternalizedBundledExtensionIds,
275+rules: PackageDistInventoryRules,
201276): boolean {
202277if (!relativePath.startsWith("dist/")) {
203278return false;
204279}
205-if (isExternalizedBundledExtensionDistPath(relativePath, externalizedExtensionIds)) {
280+if (isExternalizedBundledExtensionDistPath(relativePath, rules.externalizedExtensionIds)) {
281+return false;
282+}
283+if (isPackageFilesExcludedDistPath(relativePath, rules.exclusions)) {
206284return false;
207285}
208286if (isLegacyPluginDependencyDirPath(relativePath)) {
@@ -238,10 +316,10 @@ function isPackagedDistPath(
238316239317function isOmittedDistSubtree(
240318relativePath: string,
241-externalizedExtensionIds: ExternalizedBundledExtensionIds,
319+rules: PackageDistInventoryRules,
242320): boolean {
243321return (
244-isExternalizedBundledExtensionDistPath(relativePath, externalizedExtensionIds) ||
322+isExternalizedBundledExtensionDistPath(relativePath, rules.externalizedExtensionIds) ||
245323isLegacyPluginDependencyDirPath(relativePath) ||
246324isOmittedPluginSdkTestPath(relativePath) ||
247325OMITTED_DIST_SUBTREE_PATTERNS.some((pattern) => pattern.test(relativePath))
@@ -251,11 +329,11 @@ function isOmittedDistSubtree(
251329async function collectRelativeFiles(
252330rootDir: string,
253331baseDir: string,
254-externalizedExtensionIds: ExternalizedBundledExtensionIds,
332+rules: PackageDistInventoryRules,
255333context: PackageDistInventoryScanContext,
256334): Promise<string[]> {
257335const rootRelativePath = normalizeRelativePath(path.relative(baseDir, rootDir));
258-if (rootRelativePath && isOmittedDistSubtree(rootRelativePath, externalizedExtensionIds)) {
336+if (rootRelativePath && isOmittedDistSubtree(rootRelativePath, rules)) {
259337return [];
260338}
261339try {
@@ -276,10 +354,10 @@ async function collectRelativeFiles(
276354throw new Error(`Unsafe package dist path: ${relativePath}`);
277355}
278356if (entry.isDirectory()) {
279-return await collectRelativeFiles(entryPath, baseDir, externalizedExtensionIds, context);
357+return await collectRelativeFiles(entryPath, baseDir, rules, context);
280358}
281359if (entry.isFile()) {
282-return isPackagedDistPath(relativePath, externalizedExtensionIds) ? [relativePath] : [];
360+return isPackagedDistPath(relativePath, rules) ? [relativePath] : [];
283361}
284362return [];
285363}),
@@ -294,12 +372,12 @@ async function collectRelativeFiles(
294372}
295373296374export async function collectPackageDistInventory(packageRoot: string): Promise<string[]> {
297-const externalizedExtensionIds = await collectExternalizedBundledExtensionIds(packageRoot);
375+const rules = await collectPackageDistInventoryRulesForRoot(packageRoot);
298376const scanContext = createPackageDistInventoryScanContext();
299377return await collectRelativeFiles(
300378path.join(packageRoot, "dist"),
301379packageRoot,
302-externalizedExtensionIds,
380+rules,
303381scanContext,
304382);
305383}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。