mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 09:00:42 +00:00
fix(ci): keep postinstall script self-contained
This commit is contained in:
@@ -21,9 +21,8 @@ import {
|
||||
unlinkSync,
|
||||
writeFileSync,
|
||||
} from "node:fs";
|
||||
import { basename, dirname, isAbsolute, join, relative } from "node:path";
|
||||
import { basename, dirname, isAbsolute, join, posix, relative } from "node:path";
|
||||
import { fileURLToPath, pathToFileURL } from "node:url";
|
||||
import { expandPackageDistImportClosure } from "./lib/package-dist-imports.mjs";
|
||||
import { resolveNpmRunner } from "./npm-runner.mjs";
|
||||
|
||||
export const BUNDLED_PLUGIN_INSTALL_TARGETS = [];
|
||||
@@ -272,6 +271,137 @@ function pruneEmptyDistDirectories(params = {}) {
|
||||
prune(distRoot.distDir);
|
||||
}
|
||||
|
||||
const JS_DIST_FILE_RE = /^dist\/.*\.(?:cjs|js|mjs)$/u;
|
||||
|
||||
function stripSpecifierSuffix(value) {
|
||||
return value.replace(/[?#].*$/u, "");
|
||||
}
|
||||
|
||||
function resolveDistImportPath(importerPath, specifier) {
|
||||
if (!specifier.startsWith(".")) {
|
||||
return null;
|
||||
}
|
||||
const stripped = stripSpecifierSuffix(specifier);
|
||||
if (!stripped) {
|
||||
return null;
|
||||
}
|
||||
return posix.normalize(posix.join(posix.dirname(importerPath), stripped));
|
||||
}
|
||||
|
||||
function findStatementStart(source, index) {
|
||||
return (
|
||||
Math.max(
|
||||
source.lastIndexOf(";", index),
|
||||
source.lastIndexOf("{", index),
|
||||
source.lastIndexOf("}", index),
|
||||
source.lastIndexOf("\n", index),
|
||||
source.lastIndexOf("\r", index),
|
||||
) + 1
|
||||
);
|
||||
}
|
||||
|
||||
function isImportSpecifierContext(source, index) {
|
||||
const dynamicPrefix = source.slice(Math.max(0, index - 32), index);
|
||||
if (/\bimport\s*\(\s*$/u.test(dynamicPrefix)) {
|
||||
return true;
|
||||
}
|
||||
const statementPrefix = source.slice(findStatementStart(source, index), index).trimStart();
|
||||
return (
|
||||
/^(?:import|export)\b[\s\S]*\bfrom\s*$/u.test(statementPrefix) ||
|
||||
/^import\s*$/u.test(statementPrefix)
|
||||
);
|
||||
}
|
||||
|
||||
function collectImportSpecifiers(source) {
|
||||
const specifiers = [];
|
||||
let inBlockComment = false;
|
||||
let inLineComment = false;
|
||||
for (let index = 0; index < source.length; index += 1) {
|
||||
if (inBlockComment) {
|
||||
if (source[index] === "*" && source[index + 1] === "/") {
|
||||
inBlockComment = false;
|
||||
index += 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (inLineComment) {
|
||||
if (source[index] === "\n" || source[index] === "\r") {
|
||||
inLineComment = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (source[index] === "/" && source[index + 1] === "*") {
|
||||
inBlockComment = true;
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
if (source[index] === "/" && source[index + 1] === "/") {
|
||||
inLineComment = true;
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
const quote = source[index];
|
||||
if (quote !== '"' && quote !== "'") {
|
||||
continue;
|
||||
}
|
||||
|
||||
let cursor = index + 1;
|
||||
let value = "";
|
||||
while (cursor < source.length) {
|
||||
const char = source[cursor];
|
||||
if (char === "\\") {
|
||||
value += source.slice(cursor, cursor + 2);
|
||||
cursor += 2;
|
||||
continue;
|
||||
}
|
||||
if (char === quote) {
|
||||
break;
|
||||
}
|
||||
value += char;
|
||||
cursor += 1;
|
||||
}
|
||||
if (cursor >= source.length) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (value.startsWith(".") && isImportSpecifierContext(source, index)) {
|
||||
specifiers.push(value);
|
||||
}
|
||||
index = cursor;
|
||||
}
|
||||
return specifiers;
|
||||
}
|
||||
|
||||
function expandInstalledDistImportClosure(params) {
|
||||
const files = [...new Set(params.files)];
|
||||
const fileSet = new Set(files);
|
||||
const expectedSet = new Set(params.seedFiles);
|
||||
let changed = true;
|
||||
|
||||
while (changed) {
|
||||
changed = false;
|
||||
for (const importerPath of [...expectedSet]
|
||||
.filter((file) => fileSet.has(file))
|
||||
.toSorted((left, right) => left.localeCompare(right))) {
|
||||
if (!JS_DIST_FILE_RE.test(importerPath) || importerPath.includes("/node_modules/")) {
|
||||
continue;
|
||||
}
|
||||
const source = params.readText(importerPath);
|
||||
for (const specifier of collectImportSpecifiers(source)) {
|
||||
const importedPath = resolveDistImportPath(importerPath, specifier);
|
||||
if (!importedPath || !fileSet.has(importedPath) || expectedSet.has(importedPath)) {
|
||||
continue;
|
||||
}
|
||||
expectedSet.add(importedPath);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [...expectedSet].toSorted((left, right) => left.localeCompare(right));
|
||||
}
|
||||
|
||||
export function pruneInstalledPackageDist(params = {}) {
|
||||
const packageRoot = params.packageRoot ?? DEFAULT_PACKAGE_ROOT;
|
||||
const removeFile = params.unlinkSync ?? unlinkSync;
|
||||
@@ -295,7 +425,7 @@ export function pruneInstalledPackageDist(params = {}) {
|
||||
const installedFiles = listInstalledDistFiles(params);
|
||||
const readFile = params.readFileSync ?? readFileSync;
|
||||
expectedFiles = new Set(
|
||||
expandPackageDistImportClosure({
|
||||
expandInstalledDistImportClosure({
|
||||
files: installedFiles,
|
||||
seedFiles: [...expectedFiles],
|
||||
readText(relativePath) {
|
||||
|
||||
Reference in New Issue
Block a user