@pipelab/core-node 1.0.0-beta.32 → 1.0.0-beta.35
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/CHANGELOG.md +27 -0
- package/dist/index.cjs +240 -271
- package/dist/index.d.cts +33 -32
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +33 -32
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +240 -271
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
- package/src/handlers/index.ts +6 -1
- package/src/handlers/plugins.ts +11 -34
- package/src/plugins-registry.ts +25 -30
- package/src/runner.ts +1 -1
- package/src/server.ts +0 -1
- package/src/utils/remote.ts +27 -42
- package/src/utils.ts +10 -9
- package/scratch/simulate-updates.ts +0 -120
package/dist/index.mjs
CHANGED
|
@@ -9022,7 +9022,6 @@ var import_src = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((export
|
|
|
9022
9022
|
};
|
|
9023
9023
|
})))(), 1);
|
|
9024
9024
|
const sendStartupProgress = (message) => {
|
|
9025
|
-
console.log(`[Startup Progress] ${message}`);
|
|
9026
9025
|
webSocketServer.broadcast("startup:progress", {
|
|
9027
9026
|
type: "progress",
|
|
9028
9027
|
data: { message }
|
|
@@ -9189,7 +9188,7 @@ async function fetchPackage(packageName, versionOrRange, options) {
|
|
|
9189
9188
|
const localStart = Date.now();
|
|
9190
9189
|
const local = await tryResolveMonorepoPackage(packageName);
|
|
9191
9190
|
if (local) {
|
|
9192
|
-
console.
|
|
9191
|
+
console.debug(`[Fetcher] ${packageName}: Resolved to local source at ${local.packageDir} (${Date.now() - localStart}ms)`);
|
|
9193
9192
|
return {
|
|
9194
9193
|
...local,
|
|
9195
9194
|
resolvedVersion: "workspace"
|
|
@@ -9203,7 +9202,7 @@ async function fetchPackage(packageName, versionOrRange, options) {
|
|
|
9203
9202
|
const includePrerelease = !!(ctx.releaseTag && ctx.releaseTag !== "latest");
|
|
9204
9203
|
let resolvedVersionOrRange = versionOrRange;
|
|
9205
9204
|
if (resolvedVersionOrRange === "local") resolvedVersionOrRange = "latest";
|
|
9206
|
-
console.
|
|
9205
|
+
console.debug(`[Fetcher] Resolving ${packageName}@${resolvedVersionOrRange || "latest"}...`);
|
|
9207
9206
|
const resolveStart = Date.now();
|
|
9208
9207
|
if (!await isOnline()) {
|
|
9209
9208
|
console.warn(`[Fetcher] ${packageName}: offline mode detected (${Date.now() - resolveStart}ms), trying local fallback...`);
|
|
@@ -9211,7 +9210,7 @@ async function fetchPackage(packageName, versionOrRange, options) {
|
|
|
9211
9210
|
const fallbackVersion = await tryLocalFallback(resolvedVersionOrRange, /* @__PURE__ */ new Error("Offline"), baseDir, packageName, includePrerelease);
|
|
9212
9211
|
if (fallbackVersion) {
|
|
9213
9212
|
resolvedVersion = fallbackVersion;
|
|
9214
|
-
console.
|
|
9213
|
+
console.debug(`[Fetcher] ${packageName}: Resolved to local fallback ${resolvedVersion} (${Date.now() - fallbackStart}ms)`);
|
|
9215
9214
|
} else throw new Error(`Offline and no local fallback version available for ${packageName}`);
|
|
9216
9215
|
} else try {
|
|
9217
9216
|
const cachePath = ctx.getCachePath(CacheFolder.Pacote);
|
|
@@ -9229,7 +9228,7 @@ async function fetchPackage(packageName, versionOrRange, options) {
|
|
|
9229
9228
|
if (releaseTagVersion && semver.valid(releaseTagVersion)) {
|
|
9230
9229
|
const rewrittenRangeForCheck = allowPrereleaseInRange(range);
|
|
9231
9230
|
if (semver.satisfies(releaseTagVersion, rewrittenRangeForCheck, { includePrerelease: true })) {
|
|
9232
|
-
console.
|
|
9231
|
+
console.debug(`[Fetcher] Using release tag "${ctx.releaseTag}" (${releaseTagVersion}) for ${packageName}@${range} because it satisfies the range`);
|
|
9233
9232
|
foundVersion = releaseTagVersion;
|
|
9234
9233
|
}
|
|
9235
9234
|
}
|
|
@@ -9239,7 +9238,7 @@ async function fetchPackage(packageName, versionOrRange, options) {
|
|
|
9239
9238
|
if (rewrittenRange !== range) {
|
|
9240
9239
|
const matched = semver.maxSatisfying(versions, rewrittenRange, { includePrerelease });
|
|
9241
9240
|
if (matched) {
|
|
9242
|
-
console.
|
|
9241
|
+
console.debug(`[Fetcher] Resolved ${packageName}@${range} to ${matched} via rewritten range ${rewrittenRange}`);
|
|
9243
9242
|
foundVersion = matched;
|
|
9244
9243
|
}
|
|
9245
9244
|
}
|
|
@@ -9248,21 +9247,21 @@ async function fetchPackage(packageName, versionOrRange, options) {
|
|
|
9248
9247
|
const releaseTagVersion = packument["dist-tags"]?.[ctx.releaseTag];
|
|
9249
9248
|
if (releaseTagVersion && semver.valid(releaseTagVersion)) {
|
|
9250
9249
|
if (!foundVersion || semver.valid(foundVersion) && semver.gte(releaseTagVersion, foundVersion)) {
|
|
9251
|
-
console.
|
|
9250
|
+
console.debug(`[Fetcher] Using release tag "${ctx.releaseTag}" (${releaseTagVersion}) instead of "latest" (${foundVersion || "none"}) for ${packageName}`);
|
|
9252
9251
|
foundVersion = releaseTagVersion;
|
|
9253
9252
|
} else if (foundVersion) console.warn(`[Fetcher] Tag "${ctx.releaseTag}" (${releaseTagVersion}) is older than "latest" (${foundVersion}) for ${packageName}, keeping "latest"`);
|
|
9254
9253
|
}
|
|
9255
9254
|
}
|
|
9256
9255
|
if (!foundVersion) throw new Error(`Package ${packageName}@${range} not found on npm (available tags: ${Object.keys(packument["dist-tags"] || {}).join(", ")})`);
|
|
9257
9256
|
resolvedVersion = foundVersion;
|
|
9258
|
-
console.
|
|
9257
|
+
console.debug(`[Fetcher] ${packageName}: Resolved to v${resolvedVersion} via npm (${Date.now() - resolveStart}ms)`);
|
|
9259
9258
|
} catch (error) {
|
|
9260
9259
|
console.warn(`[Fetcher] ${packageName}: remote resolution failed (${Date.now() - resolveStart}ms), trying local fallback...`);
|
|
9261
9260
|
const fallbackStart = Date.now();
|
|
9262
9261
|
const fallbackVersion = await tryLocalFallback(resolvedVersionOrRange, error, baseDir, packageName, includePrerelease);
|
|
9263
9262
|
if (fallbackVersion) {
|
|
9264
9263
|
resolvedVersion = fallbackVersion;
|
|
9265
|
-
console.
|
|
9264
|
+
console.debug(`[Fetcher] ${packageName}: Resolved to local fallback ${resolvedVersion} (${Date.now() - fallbackStart}ms)`);
|
|
9266
9265
|
} else throw error;
|
|
9267
9266
|
}
|
|
9268
9267
|
const cachePath = ctx.getCachePath(CacheFolder.Pacote);
|
|
@@ -9271,7 +9270,7 @@ async function fetchPackage(packageName, versionOrRange, options) {
|
|
|
9271
9270
|
const isInstalled = options?.installDeps ? isPackageComplete(packageDir) && isDependenciesInstalledSync(packageDir) : isPackageComplete(packageDir);
|
|
9272
9271
|
const checkDuration = Date.now() - checkStart;
|
|
9273
9272
|
if (isInstalled) {
|
|
9274
|
-
console.
|
|
9273
|
+
console.debug(`[Fetcher] ${packageName}@${resolvedVersion}: Already installed (check took ${checkDuration}ms, fetchPackage took ${Date.now() - start}ms)`);
|
|
9275
9274
|
return {
|
|
9276
9275
|
packageDir,
|
|
9277
9276
|
resolvedVersion
|
|
@@ -9279,7 +9278,7 @@ async function fetchPackage(packageName, versionOrRange, options) {
|
|
|
9279
9278
|
}
|
|
9280
9279
|
return withLock(`package:${packageName}:${resolvedVersion}`, async () => {
|
|
9281
9280
|
if (!isPackageComplete(packageDir)) {
|
|
9282
|
-
console.
|
|
9281
|
+
console.debug(`[Fetcher] ${packageName}@${resolvedVersion}: Downloading to ${packageDir}...`);
|
|
9283
9282
|
const downloadStart = Date.now();
|
|
9284
9283
|
const tempDir = join(baseDir, `.tmp-${resolvedVersion}-${Math.random().toString(36).slice(2)}`);
|
|
9285
9284
|
await mkdir(tempDir, { recursive: true });
|
|
@@ -9293,10 +9292,10 @@ async function fetchPackage(packageName, versionOrRange, options) {
|
|
|
9293
9292
|
try {
|
|
9294
9293
|
await rename(tempDir, packageDir);
|
|
9295
9294
|
} catch (err) {
|
|
9296
|
-
if (isPackageComplete(packageDir)) console.
|
|
9295
|
+
if (isPackageComplete(packageDir)) console.debug(`[Fetcher] Destination ${packageDir} already exists and is valid.`);
|
|
9297
9296
|
else throw err;
|
|
9298
9297
|
}
|
|
9299
|
-
console.
|
|
9298
|
+
console.debug(`[Fetcher] ${packageName}@${resolvedVersion}: Downloaded and extracted in ${Date.now() - downloadStart}ms`);
|
|
9300
9299
|
} catch (err) {
|
|
9301
9300
|
await rm(tempDir, {
|
|
9302
9301
|
recursive: true,
|
|
@@ -9307,13 +9306,13 @@ async function fetchPackage(packageName, versionOrRange, options) {
|
|
|
9307
9306
|
}
|
|
9308
9307
|
const entryStart = Date.now();
|
|
9309
9308
|
const entryPoint = await resolveEntryPoint(packageDir, packageName);
|
|
9310
|
-
console.
|
|
9309
|
+
console.debug(`[Fetcher] ${packageName}@${resolvedVersion}: Resolved entry point in ${Date.now() - entryStart}ms`);
|
|
9311
9310
|
if (options?.installDeps) {
|
|
9312
9311
|
const depsStart = Date.now();
|
|
9313
9312
|
await installDependencies(packageDir, packageName, options);
|
|
9314
|
-
console.
|
|
9313
|
+
console.debug(`[Fetcher] ${packageName}@${resolvedVersion}: Installed dependencies in ${Date.now() - depsStart}ms`);
|
|
9315
9314
|
}
|
|
9316
|
-
console.
|
|
9315
|
+
console.debug(`[Fetcher] ${packageName}@${resolvedVersion}: FetchPackage complete in ${Date.now() - start}ms`);
|
|
9317
9316
|
return {
|
|
9318
9317
|
packageDir,
|
|
9319
9318
|
resolvedVersion,
|
|
@@ -9357,7 +9356,7 @@ async function ensureNodeJS(context, version = DEFAULT_NODE_VERSION) {
|
|
|
9357
9356
|
const nodeDir = context.getThirdPartyPath("node", version);
|
|
9358
9357
|
const finalNodePath = join(nodeDir, isWindows ? "node.exe" : "bin/node");
|
|
9359
9358
|
if (isNodeJSComplete(finalNodePath)) {
|
|
9360
|
-
console.
|
|
9359
|
+
console.debug(`[Environment] Node.js check took ${Date.now() - checkStart}ms (found at ${finalNodePath})`);
|
|
9361
9360
|
return finalNodePath;
|
|
9362
9361
|
}
|
|
9363
9362
|
return withLock(`node:${version}`, async () => {
|
|
@@ -9373,7 +9372,7 @@ async function ensureNodeJS(context, version = DEFAULT_NODE_VERSION) {
|
|
|
9373
9372
|
console.log(`Downloading Node.js from ${downloadUrl}...`);
|
|
9374
9373
|
const dlStart = Date.now();
|
|
9375
9374
|
await downloadFile(downloadUrl, archivePath);
|
|
9376
|
-
console.
|
|
9375
|
+
console.debug(`[Environment] Node.js download took ${Date.now() - dlStart}ms`);
|
|
9377
9376
|
sendStartupProgress(`Extracting Node.js v${version}...`);
|
|
9378
9377
|
console.log(`Extracting Node.js to ${tempDir}...`);
|
|
9379
9378
|
const extStart = Date.now();
|
|
@@ -9398,10 +9397,10 @@ async function ensureNodeJS(context, version = DEFAULT_NODE_VERSION) {
|
|
|
9398
9397
|
try {
|
|
9399
9398
|
await rename(tempNodeDir, nodeDir);
|
|
9400
9399
|
} catch (err) {
|
|
9401
|
-
if (isNodeJSComplete(finalNodePath)) console.
|
|
9400
|
+
if (isNodeJSComplete(finalNodePath)) console.debug(`[Fetcher] Node.js directory already exists and is valid.`);
|
|
9402
9401
|
else throw err;
|
|
9403
9402
|
}
|
|
9404
|
-
console.
|
|
9403
|
+
console.debug(`[Environment] Node.js extraction took ${Date.now() - extStart}ms`);
|
|
9405
9404
|
} finally {
|
|
9406
9405
|
await rm(tempNodeDir, {
|
|
9407
9406
|
recursive: true,
|
|
@@ -9412,7 +9411,7 @@ async function ensureNodeJS(context, version = DEFAULT_NODE_VERSION) {
|
|
|
9412
9411
|
force: true
|
|
9413
9412
|
}).catch(() => {});
|
|
9414
9413
|
}
|
|
9415
|
-
console.
|
|
9414
|
+
console.debug(`[Environment] Node.js set up complete in ${Date.now() - checkStart}ms`);
|
|
9416
9415
|
return finalNodePath;
|
|
9417
9416
|
});
|
|
9418
9417
|
}
|
|
@@ -9423,14 +9422,14 @@ async function ensurePNPM(context, version = DEFAULT_PNPM_VERSION) {
|
|
|
9423
9422
|
const checkStart = Date.now();
|
|
9424
9423
|
const pnpmPath = join(context.getPackagesPath("pnpm", version), "bin", "pnpm.cjs");
|
|
9425
9424
|
if (existsSync(pnpmPath)) {
|
|
9426
|
-
console.
|
|
9425
|
+
console.debug(`[Environment] PNPM check took ${Date.now() - checkStart}ms (found at ${pnpmPath})`);
|
|
9427
9426
|
return pnpmPath;
|
|
9428
9427
|
}
|
|
9429
9428
|
return withLock(`pnpm:${version}`, async () => {
|
|
9430
9429
|
if (existsSync(pnpmPath)) return pnpmPath;
|
|
9431
9430
|
sendStartupProgress(`Checking PNPM v${version}...`);
|
|
9432
9431
|
const { packageDir } = await fetchPackage("pnpm", version, { context });
|
|
9433
|
-
console.
|
|
9432
|
+
console.debug(`[Environment] PNPM set up complete in ${Date.now() - checkStart}ms`);
|
|
9434
9433
|
return join(packageDir, "bin", "pnpm.cjs");
|
|
9435
9434
|
});
|
|
9436
9435
|
}
|
|
@@ -9438,19 +9437,19 @@ async function installDependencies(packageDir, packageName, options) {
|
|
|
9438
9437
|
const start = Date.now();
|
|
9439
9438
|
const nodeModulesPath = join(packageDir, "node_modules");
|
|
9440
9439
|
if (isDependenciesInstalledSync(packageDir)) {
|
|
9441
|
-
console.
|
|
9440
|
+
console.debug(`[Fetcher] ${packageName}: Dependencies already installed, skipping.`);
|
|
9442
9441
|
return;
|
|
9443
9442
|
}
|
|
9444
9443
|
try {
|
|
9445
|
-
console.
|
|
9444
|
+
console.debug(`[Fetcher] ${packageName}: Ensuring dependencies are installed...`);
|
|
9446
9445
|
const pnpmStart = Date.now();
|
|
9447
9446
|
const { all } = await runPnpm(packageDir, {
|
|
9448
9447
|
signal: options.signal,
|
|
9449
9448
|
context: options.context
|
|
9450
9449
|
});
|
|
9451
|
-
console.
|
|
9452
|
-
if (all) console.
|
|
9453
|
-
console.
|
|
9450
|
+
console.debug(`[Fetcher] ${packageName}: pnpm install command took ${Date.now() - pnpmStart}ms`);
|
|
9451
|
+
if (all) console.debug(`[Fetcher] ${packageName}: Installation trace:\n${all}`);
|
|
9452
|
+
console.debug(`[Fetcher] ${packageName}: Dependencies installed successfully (total installDependencies took ${Date.now() - start}ms).`);
|
|
9454
9453
|
} catch (err) {
|
|
9455
9454
|
console.error(`[Fetcher] ${packageName}: CRITICAL ERROR during dependency installation: ${err.message}`);
|
|
9456
9455
|
if (err.all) console.error(`[Fetcher] ${packageName}: Error details:\n${err.all}`);
|
|
@@ -9698,209 +9697,6 @@ const handleActionExecute = async (nodeId, pluginId, params, mainWindow, send, a
|
|
|
9698
9697
|
}
|
|
9699
9698
|
};
|
|
9700
9699
|
//#endregion
|
|
9701
|
-
//#region src/plugins-registry.ts
|
|
9702
|
-
const enhancePluginDefinition = async (plugin, packageDir, fallbackName, fallbackVersion) => {
|
|
9703
|
-
if (!plugin) return plugin;
|
|
9704
|
-
let packageName = fallbackName;
|
|
9705
|
-
let version = fallbackVersion;
|
|
9706
|
-
let pipelabMeta = null;
|
|
9707
|
-
let pkgDescription = "";
|
|
9708
|
-
try {
|
|
9709
|
-
const pkgJsonPath = join(packageDir, "package.json");
|
|
9710
|
-
if (existsSync(pkgJsonPath)) {
|
|
9711
|
-
const pkgContent = await readFile(pkgJsonPath, "utf8");
|
|
9712
|
-
const pkg = JSON.parse(pkgContent);
|
|
9713
|
-
if (pkg.name) packageName = pkg.name;
|
|
9714
|
-
if (pkg.version) version = pkg.version;
|
|
9715
|
-
if (pkg.description) pkgDescription = pkg.description;
|
|
9716
|
-
if (pkg.pipelab) pipelabMeta = pkg.pipelab;
|
|
9717
|
-
}
|
|
9718
|
-
} catch (e) {
|
|
9719
|
-
console.error(`[Plugins] Failed to read package.json in ${packageDir}:`, e);
|
|
9720
|
-
}
|
|
9721
|
-
plugin.packageName = packageName;
|
|
9722
|
-
plugin.id = packageName;
|
|
9723
|
-
plugin.version = fallbackVersion === "local" ? "local" : version;
|
|
9724
|
-
plugin.isOfficial = packageName.startsWith("@pipelab/");
|
|
9725
|
-
plugin.name = pipelabMeta?.name || packageName;
|
|
9726
|
-
plugin.description = pipelabMeta?.description || pkgDescription || "";
|
|
9727
|
-
if (pipelabMeta?.icon) if (typeof pipelabMeta.icon === "string") {
|
|
9728
|
-
let iconPath = pipelabMeta.icon;
|
|
9729
|
-
if (iconPath.startsWith(".")) iconPath = pathToFileURL(join(packageDir, iconPath)).href;
|
|
9730
|
-
plugin.icon = {
|
|
9731
|
-
type: "image",
|
|
9732
|
-
image: iconPath
|
|
9733
|
-
};
|
|
9734
|
-
} else plugin.icon = pipelabMeta.icon;
|
|
9735
|
-
else plugin.icon = {
|
|
9736
|
-
type: "icon",
|
|
9737
|
-
icon: "pi pi-box"
|
|
9738
|
-
};
|
|
9739
|
-
return plugin;
|
|
9740
|
-
};
|
|
9741
|
-
const loadPipelabPlugin = async (id, options) => {
|
|
9742
|
-
const start = Date.now();
|
|
9743
|
-
try {
|
|
9744
|
-
const packageName = id;
|
|
9745
|
-
const fetchStart = Date.now();
|
|
9746
|
-
const { packageDir, entryPoint } = await fetchPipelabPlugin(packageName, options.context.releaseTag, {
|
|
9747
|
-
context: options.context,
|
|
9748
|
-
installDeps: false
|
|
9749
|
-
});
|
|
9750
|
-
const fetchDuration = Date.now() - fetchStart;
|
|
9751
|
-
console.log(`[Plugins] [${id}] Attempting to import from: ${entryPoint}`);
|
|
9752
|
-
if (!existsSync(entryPoint)) {
|
|
9753
|
-
console.error(`[Plugins] [${id}] CRITICAL: Plugin entry point not found at ${entryPoint}`);
|
|
9754
|
-
try {
|
|
9755
|
-
const files = await readdir(packageDir, { recursive: true });
|
|
9756
|
-
console.log(`[Plugins] [${id}] Directory contents:`, files);
|
|
9757
|
-
} catch (e) {}
|
|
9758
|
-
}
|
|
9759
|
-
const importStart = Date.now();
|
|
9760
|
-
const pluginModule = await import(pathToFileURL(entryPoint).href);
|
|
9761
|
-
const importDuration = Date.now() - importStart;
|
|
9762
|
-
const totalDuration = Date.now() - start;
|
|
9763
|
-
console.log(`[Plugins] [${id}] Successfully loaded from: ${packageDir} (fetch: ${fetchDuration}ms, import: ${importDuration}ms, total: ${totalDuration}ms)`);
|
|
9764
|
-
const plugin = pluginModule.default;
|
|
9765
|
-
await enhancePluginDefinition(plugin, packageDir, packageName, options.context.releaseTag);
|
|
9766
|
-
return plugin;
|
|
9767
|
-
} catch (e) {
|
|
9768
|
-
console.error(`[Plugins] [${id}] CRITICAL: Failed to load after ${Date.now() - start}ms:`, e);
|
|
9769
|
-
if (e.code === "ERR_MODULE_NOT_FOUND") console.error(`[Plugins] [${id}] This usually means a dependency is missing in the plugin's node_modules.`);
|
|
9770
|
-
return null;
|
|
9771
|
-
}
|
|
9772
|
-
};
|
|
9773
|
-
const loadCustomPlugin = async (packageName, version, options) => {
|
|
9774
|
-
const start = Date.now();
|
|
9775
|
-
try {
|
|
9776
|
-
const fetchStart = Date.now();
|
|
9777
|
-
const { packageDir, entryPoint } = await fetchPipelabPlugin(packageName, version, {
|
|
9778
|
-
context: options.context,
|
|
9779
|
-
installDeps: false
|
|
9780
|
-
});
|
|
9781
|
-
const fetchDuration = Date.now() - fetchStart;
|
|
9782
|
-
console.log(`[Plugins] [${packageName}] Attempting to import custom plugin from: ${entryPoint}`);
|
|
9783
|
-
if (!existsSync(entryPoint)) {
|
|
9784
|
-
console.error(`[Plugins] [${packageName}] CRITICAL: Plugin entry point not found at ${entryPoint}`);
|
|
9785
|
-
return null;
|
|
9786
|
-
}
|
|
9787
|
-
const importStart = Date.now();
|
|
9788
|
-
const pluginModule = await import(pathToFileURL(entryPoint).href);
|
|
9789
|
-
const importDuration = Date.now() - importStart;
|
|
9790
|
-
const totalDuration = Date.now() - start;
|
|
9791
|
-
console.log(`[Plugins] [${packageName}] Successfully loaded custom plugin from: ${packageDir} (fetch: ${fetchDuration}ms, import: ${importDuration}ms, total: ${totalDuration}ms)`);
|
|
9792
|
-
const plugin = pluginModule.default;
|
|
9793
|
-
await enhancePluginDefinition(plugin, packageDir, packageName, version);
|
|
9794
|
-
return plugin;
|
|
9795
|
-
} catch (e) {
|
|
9796
|
-
console.error(`[Plugins] [${packageName}] CRITICAL: Failed to load after ${Date.now() - start}ms:`, e);
|
|
9797
|
-
return null;
|
|
9798
|
-
}
|
|
9799
|
-
};
|
|
9800
|
-
async function findInstalledPlugins(packagesDir) {
|
|
9801
|
-
const installed = [];
|
|
9802
|
-
if (!existsSync(packagesDir)) return installed;
|
|
9803
|
-
async function scan(dir, depth = 0) {
|
|
9804
|
-
if (depth > 4) return;
|
|
9805
|
-
try {
|
|
9806
|
-
const entries = await readdir(dir, { withFileTypes: true });
|
|
9807
|
-
if (entries.some((e) => e.isFile() && e.name === "package.json")) {
|
|
9808
|
-
try {
|
|
9809
|
-
const content = await readFile(join(dir, "package.json"), "utf8");
|
|
9810
|
-
const pkg = JSON.parse(content);
|
|
9811
|
-
if (pkg.name && pkg.name !== "pnpm") installed.push({
|
|
9812
|
-
name: pkg.name,
|
|
9813
|
-
version: pkg.version || "0.0.0",
|
|
9814
|
-
packageDir: dir,
|
|
9815
|
-
description: pkg.description || ""
|
|
9816
|
-
});
|
|
9817
|
-
} catch (e) {}
|
|
9818
|
-
return;
|
|
9819
|
-
}
|
|
9820
|
-
for (const entry of entries) if (entry.isDirectory() && entry.name !== "node_modules" && !entry.name.startsWith(".")) await scan(join(dir, entry.name), depth + 1);
|
|
9821
|
-
} catch (e) {}
|
|
9822
|
-
}
|
|
9823
|
-
await scan(packagesDir);
|
|
9824
|
-
return installed;
|
|
9825
|
-
}
|
|
9826
|
-
const builtInPlugins = async (options) => {
|
|
9827
|
-
console.log("[Plugins] Starting background plugin loading...");
|
|
9828
|
-
sendStartupProgress("Preparing environment...");
|
|
9829
|
-
const envStart = Date.now();
|
|
9830
|
-
await Promise.all([ensureNodeJS(options.context), ensurePNPM(options.context)]);
|
|
9831
|
-
console.log(`[Plugins] Environment preparation took ${Date.now() - envStart}ms`);
|
|
9832
|
-
const { usePlugins } = await import("@pipelab/shared");
|
|
9833
|
-
const { registerPlugins } = usePlugins();
|
|
9834
|
-
const { webSocketServer } = await import("./index.mjs");
|
|
9835
|
-
webSocketServer.broadcast("startup:progress", { type: "ready" });
|
|
9836
|
-
(async () => {
|
|
9837
|
-
const totalStart = Date.now();
|
|
9838
|
-
const pluginsToLoad = /* @__PURE__ */ new Map();
|
|
9839
|
-
for (const name of [
|
|
9840
|
-
"@pipelab/plugin-construct",
|
|
9841
|
-
"@pipelab/plugin-filesystem",
|
|
9842
|
-
"@pipelab/plugin-system",
|
|
9843
|
-
"@pipelab/plugin-steam",
|
|
9844
|
-
"@pipelab/plugin-itch",
|
|
9845
|
-
"@pipelab/plugin-electron",
|
|
9846
|
-
"@pipelab/plugin-discord",
|
|
9847
|
-
"@pipelab/plugin-poki",
|
|
9848
|
-
"@pipelab/plugin-nvpatch",
|
|
9849
|
-
"@pipelab/plugin-tauri",
|
|
9850
|
-
"@pipelab/plugin-minify",
|
|
9851
|
-
"@pipelab/plugin-netlify"
|
|
9852
|
-
]) pluginsToLoad.set(name, "latest");
|
|
9853
|
-
if (isDev && projectRoot) {
|
|
9854
|
-
const pluginsDir = join(projectRoot, "plugins");
|
|
9855
|
-
if (existsSync(pluginsDir)) try {
|
|
9856
|
-
const entries = await readdir(pluginsDir, { withFileTypes: true });
|
|
9857
|
-
for (const entry of entries) if (entry.isDirectory()) {
|
|
9858
|
-
const pkgPath = join(pluginsDir, entry.name, "package.json");
|
|
9859
|
-
if (existsSync(pkgPath)) try {
|
|
9860
|
-
const pkgContent = await readFile(pkgPath, "utf-8");
|
|
9861
|
-
const pkg = JSON.parse(pkgContent);
|
|
9862
|
-
if (pkg.name && pkg.name.startsWith("@pipelab/plugin-") && pkg.name !== "@pipelab/plugin-core") pluginsToLoad.set(pkg.name, "local");
|
|
9863
|
-
} catch (e) {
|
|
9864
|
-
console.error(`[Plugins] Failed to parse package.json for ${entry.name}:`, e);
|
|
9865
|
-
}
|
|
9866
|
-
}
|
|
9867
|
-
} catch (e) {
|
|
9868
|
-
console.error(`[Plugins] Failed to scan local workspace plugins directory:`, e);
|
|
9869
|
-
}
|
|
9870
|
-
}
|
|
9871
|
-
try {
|
|
9872
|
-
const { setupSettingsConfigFile } = await import("./config-DRifo1Uc.mjs");
|
|
9873
|
-
const settingsPlugins = (await (await setupSettingsConfigFile(options.context)).getConfig())?.plugins || [];
|
|
9874
|
-
for (const plugin of settingsPlugins) if (plugin.name) if (plugin.enabled) {
|
|
9875
|
-
if (!pluginsToLoad.has(plugin.name)) pluginsToLoad.set(plugin.name, "latest");
|
|
9876
|
-
} else pluginsToLoad.delete(plugin.name);
|
|
9877
|
-
} catch (e) {
|
|
9878
|
-
console.error(`[Plugins] Failed to load settings config on startup:`, e);
|
|
9879
|
-
}
|
|
9880
|
-
console.log(`[Plugins] Total plugins to load on startup:`, Array.from(pluginsToLoad.entries()));
|
|
9881
|
-
const loadPromises = Array.from(pluginsToLoad.entries()).map(async ([packageName, version]) => {
|
|
9882
|
-
sendStartupProgress(`Loading plugin: ${packageName}`);
|
|
9883
|
-
const pluginStart = Date.now();
|
|
9884
|
-
try {
|
|
9885
|
-
const plugin = await loadCustomPlugin(packageName, version, options);
|
|
9886
|
-
if (plugin) {
|
|
9887
|
-
registerPlugins([plugin]);
|
|
9888
|
-
webSocketServer.broadcast("plugin:loaded", { plugin });
|
|
9889
|
-
console.log(`[Plugins] Loaded ${packageName}@${version} in ${Date.now() - pluginStart}ms`);
|
|
9890
|
-
}
|
|
9891
|
-
} catch (err) {
|
|
9892
|
-
console.error(`[Plugins] Failed to load plugin ${packageName} at startup:`, err);
|
|
9893
|
-
}
|
|
9894
|
-
});
|
|
9895
|
-
await Promise.all(loadPromises);
|
|
9896
|
-
console.log(`[Plugins] All startup plugins loaded in ${Date.now() - totalStart}ms.`);
|
|
9897
|
-
sendStartupProgress("All plugins loaded.");
|
|
9898
|
-
setTimeout(() => {
|
|
9899
|
-
webSocketServer.broadcast("startup:progress", { type: "done" });
|
|
9900
|
-
}, 2e3);
|
|
9901
|
-
})();
|
|
9902
|
-
};
|
|
9903
|
-
//#endregion
|
|
9904
9700
|
//#region src/utils.ts
|
|
9905
9701
|
const getFinalPlugins = () => {
|
|
9906
9702
|
const { plugins } = usePlugins();
|
|
@@ -9960,13 +9756,12 @@ const executeGraphWithHistory = async ({ graph, variables, projectName, projectP
|
|
|
9960
9756
|
let completedSteps = 0;
|
|
9961
9757
|
const { registerPlugins, plugins: registeredPlugins } = usePlugins();
|
|
9962
9758
|
const pluginIds = new Set(graph.map((node) => node.origin?.pluginId).filter(Boolean));
|
|
9963
|
-
|
|
9964
|
-
|
|
9965
|
-
|
|
9966
|
-
|
|
9967
|
-
|
|
9968
|
-
|
|
9969
|
-
} else logger().error(`[Runner] Failed to load or register plugin "${pluginId}"`);
|
|
9759
|
+
const missingPlugins = [];
|
|
9760
|
+
for (const pluginId of pluginIds) if (!registeredPlugins.value.some((p) => p.id === pluginId)) missingPlugins.push(pluginId);
|
|
9761
|
+
if (missingPlugins.length > 0) {
|
|
9762
|
+
const errorMsg = `Fail-fast: The following required plugins are not loaded: ${missingPlugins.join(", ")}. Please ensure they are installed and enabled in settings.`;
|
|
9763
|
+
logger().error(`[Runner] ${errorMsg}`);
|
|
9764
|
+
throw new Error(errorMsg);
|
|
9970
9765
|
}
|
|
9971
9766
|
logger().info(`[Sandbox] Execution sandbox created at: ${sandboxPath}`);
|
|
9972
9767
|
await (await setupSettingsConfigFile(ctx)).getConfig();
|
|
@@ -10828,6 +10623,200 @@ const registerSystemHandlers = (options) => {
|
|
|
10828
10623
|
});
|
|
10829
10624
|
};
|
|
10830
10625
|
//#endregion
|
|
10626
|
+
//#region src/plugins-registry.ts
|
|
10627
|
+
const enhancePluginDefinition = async (plugin, packageDir, fallbackName, fallbackVersion) => {
|
|
10628
|
+
if (!plugin) return plugin;
|
|
10629
|
+
let packageName = fallbackName;
|
|
10630
|
+
let version = fallbackVersion;
|
|
10631
|
+
let pipelabMeta = null;
|
|
10632
|
+
let pkgDescription = "";
|
|
10633
|
+
try {
|
|
10634
|
+
const pkgJsonPath = join(packageDir, "package.json");
|
|
10635
|
+
if (existsSync(pkgJsonPath)) {
|
|
10636
|
+
const pkgContent = await readFile(pkgJsonPath, "utf8");
|
|
10637
|
+
const pkg = JSON.parse(pkgContent);
|
|
10638
|
+
if (pkg.name) packageName = pkg.name;
|
|
10639
|
+
if (pkg.version) version = pkg.version;
|
|
10640
|
+
if (pkg.description) pkgDescription = pkg.description;
|
|
10641
|
+
if (pkg.pipelab) pipelabMeta = pkg.pipelab;
|
|
10642
|
+
}
|
|
10643
|
+
} catch (e) {
|
|
10644
|
+
console.error(`[Plugins] Failed to read package.json in ${packageDir}:`, e);
|
|
10645
|
+
}
|
|
10646
|
+
plugin.packageName = packageName;
|
|
10647
|
+
plugin.id = packageName;
|
|
10648
|
+
plugin.version = fallbackVersion === "local" ? "local" : version;
|
|
10649
|
+
plugin.isOfficial = packageName.startsWith("@pipelab/");
|
|
10650
|
+
plugin.name = pipelabMeta?.name || packageName;
|
|
10651
|
+
plugin.description = pipelabMeta?.description || pkgDescription || "";
|
|
10652
|
+
if (pipelabMeta?.icon) if (typeof pipelabMeta.icon === "string") {
|
|
10653
|
+
let iconPath = pipelabMeta.icon;
|
|
10654
|
+
if (iconPath.startsWith(".")) iconPath = pathToFileURL(join(packageDir, iconPath)).href;
|
|
10655
|
+
plugin.icon = {
|
|
10656
|
+
type: "image",
|
|
10657
|
+
image: iconPath
|
|
10658
|
+
};
|
|
10659
|
+
} else plugin.icon = pipelabMeta.icon;
|
|
10660
|
+
else plugin.icon = {
|
|
10661
|
+
type: "icon",
|
|
10662
|
+
icon: "pi pi-box"
|
|
10663
|
+
};
|
|
10664
|
+
return plugin;
|
|
10665
|
+
};
|
|
10666
|
+
const loadPipelabPlugin = async (id, options) => {
|
|
10667
|
+
const start = Date.now();
|
|
10668
|
+
try {
|
|
10669
|
+
const packageName = id;
|
|
10670
|
+
const fetchStart = Date.now();
|
|
10671
|
+
const { packageDir, entryPoint } = await fetchPipelabPlugin(packageName, options.context.releaseTag, {
|
|
10672
|
+
context: options.context,
|
|
10673
|
+
installDeps: false
|
|
10674
|
+
});
|
|
10675
|
+
const fetchDuration = Date.now() - fetchStart;
|
|
10676
|
+
console.debug(`[Plugins] [${id}] Attempting to import from: ${entryPoint}`);
|
|
10677
|
+
if (!existsSync(entryPoint)) {
|
|
10678
|
+
console.error(`[Plugins] [${id}] CRITICAL: Plugin entry point not found at ${entryPoint}`);
|
|
10679
|
+
try {
|
|
10680
|
+
const files = await readdir(packageDir, { recursive: true });
|
|
10681
|
+
console.debug(`[Plugins] [${id}] Directory contents:`, files);
|
|
10682
|
+
} catch (e) {}
|
|
10683
|
+
}
|
|
10684
|
+
const importStart = Date.now();
|
|
10685
|
+
const pluginModule = await import(pathToFileURL(entryPoint).href);
|
|
10686
|
+
const importDuration = Date.now() - importStart;
|
|
10687
|
+
const totalDuration = Date.now() - start;
|
|
10688
|
+
console.debug(`[Plugins] [${id}] Successfully loaded from: ${packageDir} (fetch: ${fetchDuration}ms, import: ${importDuration}ms, total: ${totalDuration}ms)`);
|
|
10689
|
+
const plugin = pluginModule.default;
|
|
10690
|
+
await enhancePluginDefinition(plugin, packageDir, packageName, options.context.releaseTag);
|
|
10691
|
+
return plugin;
|
|
10692
|
+
} catch (e) {
|
|
10693
|
+
console.error(`[Plugins] [${id}] CRITICAL: Failed to load after ${Date.now() - start}ms:`, e);
|
|
10694
|
+
if (e.code === "ERR_MODULE_NOT_FOUND") console.error(`[Plugins] [${id}] This usually means a dependency is missing in the plugin's node_modules.`);
|
|
10695
|
+
return null;
|
|
10696
|
+
}
|
|
10697
|
+
};
|
|
10698
|
+
const loadCustomPlugin = async (packageName, version, options) => {
|
|
10699
|
+
const start = Date.now();
|
|
10700
|
+
try {
|
|
10701
|
+
const fetchStart = Date.now();
|
|
10702
|
+
const { packageDir, entryPoint } = await fetchPipelabPlugin(packageName, version, {
|
|
10703
|
+
context: options.context,
|
|
10704
|
+
installDeps: false
|
|
10705
|
+
});
|
|
10706
|
+
const fetchDuration = Date.now() - fetchStart;
|
|
10707
|
+
console.debug(`[Plugins] [${packageName}] Attempting to import custom plugin from: ${entryPoint}`);
|
|
10708
|
+
if (!existsSync(entryPoint)) {
|
|
10709
|
+
console.error(`[Plugins] [${packageName}] CRITICAL: Plugin entry point not found at ${entryPoint}`);
|
|
10710
|
+
return null;
|
|
10711
|
+
}
|
|
10712
|
+
const importStart = Date.now();
|
|
10713
|
+
const pluginModule = await import(pathToFileURL(entryPoint).href);
|
|
10714
|
+
const importDuration = Date.now() - importStart;
|
|
10715
|
+
const totalDuration = Date.now() - start;
|
|
10716
|
+
console.debug(`[Plugins] [${packageName}] Successfully loaded custom plugin from: ${packageDir} (fetch: ${fetchDuration}ms, import: ${importDuration}ms, total: ${totalDuration}ms)`);
|
|
10717
|
+
const plugin = pluginModule.default;
|
|
10718
|
+
await enhancePluginDefinition(plugin, packageDir, packageName, version);
|
|
10719
|
+
return plugin;
|
|
10720
|
+
} catch (e) {
|
|
10721
|
+
console.error(`[Plugins] [${packageName}] CRITICAL: Failed to load after ${Date.now() - start}ms:`, e);
|
|
10722
|
+
return null;
|
|
10723
|
+
}
|
|
10724
|
+
};
|
|
10725
|
+
async function findInstalledPlugins(packagesDir) {
|
|
10726
|
+
const installed = [];
|
|
10727
|
+
if (!existsSync(packagesDir)) return installed;
|
|
10728
|
+
async function scan(dir, depth = 0) {
|
|
10729
|
+
if (depth > 4) return;
|
|
10730
|
+
try {
|
|
10731
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
10732
|
+
if (entries.some((e) => e.isFile() && e.name === "package.json")) {
|
|
10733
|
+
try {
|
|
10734
|
+
const content = await readFile(join(dir, "package.json"), "utf8");
|
|
10735
|
+
const pkg = JSON.parse(content);
|
|
10736
|
+
if (pkg.name && pkg.name !== "pnpm" && (pkg.pipelab || pkg.keywords && pkg.keywords.includes("pipelab-plugin"))) installed.push({
|
|
10737
|
+
name: pkg.name,
|
|
10738
|
+
version: pkg.version || "0.0.0",
|
|
10739
|
+
packageDir: dir,
|
|
10740
|
+
description: pkg.description || ""
|
|
10741
|
+
});
|
|
10742
|
+
} catch (e) {}
|
|
10743
|
+
return;
|
|
10744
|
+
}
|
|
10745
|
+
for (const entry of entries) if (entry.isDirectory() && entry.name !== "node_modules" && !entry.name.startsWith(".")) await scan(join(dir, entry.name), depth + 1);
|
|
10746
|
+
} catch (e) {}
|
|
10747
|
+
}
|
|
10748
|
+
await scan(packagesDir);
|
|
10749
|
+
return installed;
|
|
10750
|
+
}
|
|
10751
|
+
const builtInPlugins = async (options) => {
|
|
10752
|
+
console.debug("[Plugins] Starting background plugin loading...");
|
|
10753
|
+
sendStartupProgress("Preparing environment...");
|
|
10754
|
+
const envStart = Date.now();
|
|
10755
|
+
await Promise.all([ensureNodeJS(options.context), ensurePNPM(options.context)]);
|
|
10756
|
+
console.debug(`[Plugins] Environment preparation took ${Date.now() - envStart}ms`);
|
|
10757
|
+
const { usePlugins } = await import("@pipelab/shared");
|
|
10758
|
+
const { registerPlugins } = usePlugins();
|
|
10759
|
+
const { webSocketServer } = await import("./index.mjs");
|
|
10760
|
+
webSocketServer.broadcast("startup:progress", { type: "ready" });
|
|
10761
|
+
return (async () => {
|
|
10762
|
+
const totalStart = Date.now();
|
|
10763
|
+
const pluginsToLoad = /* @__PURE__ */ new Map();
|
|
10764
|
+
const { DEFAULT_PLUGIN_IDS, DEV_ONLY_PLUGIN_IDS } = await import("@pipelab/shared");
|
|
10765
|
+
const defaultPlugins = [...DEFAULT_PLUGIN_IDS].map((id) => `@pipelab/plugin-${id}`);
|
|
10766
|
+
if (isDev) defaultPlugins.push(...DEV_ONLY_PLUGIN_IDS.map((id) => `@pipelab/plugin-${id}`));
|
|
10767
|
+
for (const name of defaultPlugins) pluginsToLoad.set(name, "latest");
|
|
10768
|
+
if (isDev && projectRoot) {
|
|
10769
|
+
const pluginsDir = join(projectRoot, "plugins");
|
|
10770
|
+
if (existsSync(pluginsDir)) try {
|
|
10771
|
+
const entries = await readdir(pluginsDir, { withFileTypes: true });
|
|
10772
|
+
for (const entry of entries) if (entry.isDirectory()) {
|
|
10773
|
+
const pkgPath = join(pluginsDir, entry.name, "package.json");
|
|
10774
|
+
if (existsSync(pkgPath)) try {
|
|
10775
|
+
const pkgContent = await readFile(pkgPath, "utf-8");
|
|
10776
|
+
const pkg = JSON.parse(pkgContent);
|
|
10777
|
+
if (pkg.name && pkg.name.startsWith("@pipelab/plugin-") && pkg.name !== "@pipelab/plugin-core") pluginsToLoad.set(pkg.name, "local");
|
|
10778
|
+
} catch (e) {
|
|
10779
|
+
console.error(`[Plugins] Failed to parse package.json for ${entry.name}:`, e);
|
|
10780
|
+
}
|
|
10781
|
+
}
|
|
10782
|
+
} catch (e) {
|
|
10783
|
+
console.error(`[Plugins] Failed to scan local workspace plugins directory:`, e);
|
|
10784
|
+
}
|
|
10785
|
+
}
|
|
10786
|
+
try {
|
|
10787
|
+
const { setupSettingsConfigFile } = await import("./config-DRifo1Uc.mjs");
|
|
10788
|
+
const settingsPlugins = (await (await setupSettingsConfigFile(options.context)).getConfig())?.plugins || [];
|
|
10789
|
+
for (const plugin of settingsPlugins) if (plugin.name) if (plugin.enabled) {
|
|
10790
|
+
if (!pluginsToLoad.has(plugin.name)) pluginsToLoad.set(plugin.name, "latest");
|
|
10791
|
+
} else pluginsToLoad.delete(plugin.name);
|
|
10792
|
+
} catch (e) {
|
|
10793
|
+
console.error(`[Plugins] Failed to load settings config on startup:`, e);
|
|
10794
|
+
}
|
|
10795
|
+
const pluginList = Array.from(pluginsToLoad.keys()).map((p) => ` - ${p}`).join("\n");
|
|
10796
|
+
console.log(`\n[Plugins] Loading plugins in background:\n${pluginList}\n`);
|
|
10797
|
+
const loadPromises = Array.from(pluginsToLoad.entries()).map(async ([packageName, version]) => {
|
|
10798
|
+
sendStartupProgress(`Loading plugin: ${packageName}`);
|
|
10799
|
+
const pluginStart = Date.now();
|
|
10800
|
+
try {
|
|
10801
|
+
const plugin = await loadCustomPlugin(packageName, version, options);
|
|
10802
|
+
if (plugin) {
|
|
10803
|
+
registerPlugins([plugin]);
|
|
10804
|
+
webSocketServer.broadcast("plugin:loaded", { plugin });
|
|
10805
|
+
console.debug(`[Plugins] Loaded ${packageName}@${version} in ${Date.now() - pluginStart}ms`);
|
|
10806
|
+
}
|
|
10807
|
+
} catch (err) {
|
|
10808
|
+
console.error(`[Plugins] Failed to load plugin ${packageName} at startup:`, err);
|
|
10809
|
+
}
|
|
10810
|
+
});
|
|
10811
|
+
await Promise.all(loadPromises);
|
|
10812
|
+
console.log(`\n[Plugins] All startup plugins loaded in ${Date.now() - totalStart}ms.\n`);
|
|
10813
|
+
sendStartupProgress("All plugins loaded.");
|
|
10814
|
+
setTimeout(() => {
|
|
10815
|
+
webSocketServer.broadcast("startup:progress", { type: "done" });
|
|
10816
|
+
}, 2e3);
|
|
10817
|
+
})();
|
|
10818
|
+
};
|
|
10819
|
+
//#endregion
|
|
10831
10820
|
//#region src/handlers/plugins.ts
|
|
10832
10821
|
const localPluginsMap = /* @__PURE__ */ new Map();
|
|
10833
10822
|
if (isDev && projectRoot) {
|
|
@@ -10977,26 +10966,15 @@ const registerPluginsHandlers = (context) => {
|
|
|
10977
10966
|
handle("plugin:list-installed", async (_, { send }) => {
|
|
10978
10967
|
try {
|
|
10979
10968
|
const rawInstalled = await findInstalledPlugins(context.getPackagesPath());
|
|
10980
|
-
const DEFAULT_PLUGIN_IDS =
|
|
10981
|
-
|
|
10982
|
-
|
|
10983
|
-
"system",
|
|
10984
|
-
"steam",
|
|
10985
|
-
"itch",
|
|
10986
|
-
"electron",
|
|
10987
|
-
"discord",
|
|
10988
|
-
"poki",
|
|
10989
|
-
"nvpatch",
|
|
10990
|
-
"tauri",
|
|
10991
|
-
"minify",
|
|
10992
|
-
"netlify"
|
|
10993
|
-
];
|
|
10969
|
+
const { DEFAULT_PLUGIN_IDS, DEV_ONLY_PLUGIN_IDS } = await import("@pipelab/shared");
|
|
10970
|
+
const defaultPluginIds = [...DEFAULT_PLUGIN_IDS];
|
|
10971
|
+
if (isDev) defaultPluginIds.push(...DEV_ONLY_PLUGIN_IDS);
|
|
10994
10972
|
send({
|
|
10995
10973
|
type: "end",
|
|
10996
10974
|
data: {
|
|
10997
10975
|
type: "success",
|
|
10998
10976
|
result: { installed: rawInstalled.filter((item) => {
|
|
10999
|
-
return !
|
|
10977
|
+
return !defaultPluginIds.some((id) => item.name === `@pipelab/plugin-${id}`);
|
|
11000
10978
|
}).map((item) => ({
|
|
11001
10979
|
name: item.name,
|
|
11002
10980
|
version: item.version,
|
|
@@ -11029,23 +11007,12 @@ const registerPluginsHandlers = (context) => {
|
|
|
11029
11007
|
if (p.packageName !== packageName) return false;
|
|
11030
11008
|
if (mappedVersion === "latest") return true;
|
|
11031
11009
|
return p.version === mappedVersion;
|
|
11032
|
-
}))
|
|
11033
|
-
|
|
11034
|
-
|
|
11035
|
-
const plugin = await loadCustomPlugin(packageName, mappedVersion, { context });
|
|
11036
|
-
if (plugin) {
|
|
11037
|
-
registerPlugins([plugin]);
|
|
11038
|
-
webSocketServer.broadcast("plugin:loaded", { plugin });
|
|
11039
|
-
loaded.push(packageName);
|
|
11040
|
-
console.log(`[Plugins] JIT loaded "${packageName}" successfully.`);
|
|
11041
|
-
} else {
|
|
11042
|
-
console.warn(`[Plugins] JIT load for "${packageName}" returned no plugin.`);
|
|
11043
|
-
failed.push(packageName);
|
|
11044
|
-
}
|
|
11045
|
-
} catch (e) {
|
|
11046
|
-
console.error(`[Plugins] JIT load failed for "${packageName}":`, e);
|
|
11047
|
-
failed.push(packageName);
|
|
11010
|
+
})) {
|
|
11011
|
+
loaded.push(packageName);
|
|
11012
|
+
continue;
|
|
11048
11013
|
}
|
|
11014
|
+
console.warn(`[Plugins] Plugin "${packageName}" is required but not loaded at startup.`);
|
|
11015
|
+
failed.push(packageName);
|
|
11049
11016
|
}
|
|
11050
11017
|
send({
|
|
11051
11018
|
type: "end",
|
|
@@ -11552,7 +11519,8 @@ const registerAllHandlers = async (options) => {
|
|
|
11552
11519
|
registerPluginsHandlers(context);
|
|
11553
11520
|
registerMigrationHandlers(context);
|
|
11554
11521
|
const { registerPlugins } = usePlugins();
|
|
11555
|
-
builtInPlugins({ context });
|
|
11522
|
+
const pluginsPromise = builtInPlugins({ context });
|
|
11523
|
+
if (options.waitForPlugins) await pluginsPromise;
|
|
11556
11524
|
};
|
|
11557
11525
|
//#endregion
|
|
11558
11526
|
//#region ../../node_modules/klona/dist/index.mjs
|
|
@@ -53825,7 +53793,8 @@ async function runPipelineCommand(file, options, version) {
|
|
|
53825
53793
|
});
|
|
53826
53794
|
await registerAllHandlers({
|
|
53827
53795
|
version,
|
|
53828
|
-
context
|
|
53796
|
+
context,
|
|
53797
|
+
waitForPlugins: true
|
|
53829
53798
|
});
|
|
53830
53799
|
const cachePath = context.getCachePath(CacheFolder.Pipelines, effectivePipelineId);
|
|
53831
53800
|
await mkdir(cachePath, { recursive: true });
|