@pipelab/core-node 1.0.0-beta.13 → 1.0.0-beta.14
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/.oxfmtrc.json +1 -7
- package/CHANGELOG.md +9 -0
- package/dist/index.d.mts +23 -12
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +104 -41
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -5
- package/src/config.test.ts +176 -0
- package/src/config.ts +44 -24
- package/src/context.ts +51 -2
- package/src/handlers/build-history.ts +14 -1
- package/src/handlers/engine.ts +6 -7
- package/src/handlers/history.ts +1 -1
- package/src/handlers/plugins.ts +1 -6
- package/src/migrations.ts +3 -15
- package/src/plugins-registry.ts +1 -3
- package/src/runner.ts +0 -1
- package/src/server.ts +1 -0
- package/src/types/runner.ts +1 -0
- package/src/utils/fs-extras.ts +2 -23
- package/src/utils/github.test.ts +213 -0
- package/src/utils/remote.ts +3 -5
- package/src/utils.ts +2 -2
package/dist/index.mjs
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
2
|
import path, { delimiter, dirname, isAbsolute, join, resolve } from "node:path";
|
|
3
|
-
import { homedir, platform
|
|
3
|
+
import { homedir, platform } from "node:os";
|
|
4
4
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
5
5
|
import fs, { createWriteStream, existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
6
|
+
import fs$1, { access, chmod, cp, mkdir, mkdtemp, readFile, readdir, realpath, rename, rm, stat, unlink, writeFile } from "node:fs/promises";
|
|
7
|
+
import { DEFAULT_NODE_VERSION, DEFAULT_PNPM_VERSION, SandboxFolder, getUiDevServerMissingWarning, uiDevPort, websocketPort } from "@pipelab/constants";
|
|
6
8
|
import { WebSocket, WebSocketServer as WebSocketServer$1 } from "ws";
|
|
7
9
|
import http from "node:http";
|
|
8
10
|
import { nanoid } from "nanoid";
|
|
9
|
-
import { SubscriptionRequiredError, WebSocketError,
|
|
10
|
-
import { getUiDevServerMissingWarning, uiDevPort, websocketPort } from "@pipelab/constants";
|
|
11
|
-
import fs$1, { access, chmod, cp, mkdir, mkdtemp, readFile, readdir, realpath, rename, rm, stat, unlink, writeFile } from "node:fs/promises";
|
|
11
|
+
import { SubscriptionRequiredError, WebSocketError, configRegistry, isRequired, isSupabaseAvailable, isWebSocketRequestMessage, normalizePipelineConfig, processGraph, savedFileMigrator, supabase, transformUrl, useLogger, usePlugins } from "@pipelab/shared";
|
|
12
12
|
import { execa } from "execa";
|
|
13
13
|
import tar from "tar";
|
|
14
14
|
import yauzl from "yauzl";
|
|
@@ -53,7 +53,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
53
53
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
54
54
|
//#endregion
|
|
55
55
|
//#region src/context.ts
|
|
56
|
-
const
|
|
56
|
+
const metaUrl = typeof import.meta !== "undefined" ? import.meta.url : void 0;
|
|
57
|
+
const _dirname = typeof __dirname !== "undefined" ? __dirname : metaUrl ? dirname(fileURLToPath(metaUrl)) : process.cwd();
|
|
57
58
|
const isDev = process.env.NODE_ENV === "development";
|
|
58
59
|
const getDefaultUserDataPath = (env) => {
|
|
59
60
|
const base = (() => {
|
|
@@ -94,6 +95,59 @@ var PipelabContext = class {
|
|
|
94
95
|
getConfigPath(...subpaths) {
|
|
95
96
|
return join(this.userDataPath, "config", ...subpaths);
|
|
96
97
|
}
|
|
98
|
+
getTempPath(...subpaths) {
|
|
99
|
+
return join(this.userDataPath, "temp", ...subpaths);
|
|
100
|
+
}
|
|
101
|
+
async createTempFolder(prefix = "pipelab-") {
|
|
102
|
+
const baseDir = this.getTempPath();
|
|
103
|
+
await mkdir(baseDir, { recursive: true });
|
|
104
|
+
return await mkdtemp(join(await realpath(baseDir), prefix));
|
|
105
|
+
}
|
|
106
|
+
getCachePath(...subpaths) {
|
|
107
|
+
return join(this.userDataPath, "cache", ...subpaths);
|
|
108
|
+
}
|
|
109
|
+
getPnpmPath(...subpaths) {
|
|
110
|
+
return join(this.userDataPath, "pnpm", ...subpaths);
|
|
111
|
+
}
|
|
112
|
+
getNodePath(version = DEFAULT_NODE_VERSION) {
|
|
113
|
+
const isWindows = process.platform === "win32";
|
|
114
|
+
return this.getThirdPartyPath("node", version, isWindows ? "node.exe" : "bin/node");
|
|
115
|
+
}
|
|
116
|
+
getPnpmBinPath(version = DEFAULT_PNPM_VERSION) {
|
|
117
|
+
return this.getPackagesPath("pnpm", version, "bin", "pnpm.cjs");
|
|
118
|
+
}
|
|
119
|
+
getSandboxFolders() {
|
|
120
|
+
const foldersRecord = {
|
|
121
|
+
[SandboxFolder.Packages]: {
|
|
122
|
+
label: "Packages",
|
|
123
|
+
path: this.getPackagesPath()
|
|
124
|
+
},
|
|
125
|
+
[SandboxFolder.ThirdParty]: {
|
|
126
|
+
label: "Third-Party Tools",
|
|
127
|
+
path: this.getThirdPartyPath()
|
|
128
|
+
},
|
|
129
|
+
[SandboxFolder.Config]: {
|
|
130
|
+
label: "Configuration",
|
|
131
|
+
path: this.getConfigPath()
|
|
132
|
+
},
|
|
133
|
+
[SandboxFolder.Temp]: {
|
|
134
|
+
label: "Temporary Files",
|
|
135
|
+
path: this.getTempPath()
|
|
136
|
+
},
|
|
137
|
+
[SandboxFolder.Cache]: {
|
|
138
|
+
label: "Cache",
|
|
139
|
+
path: this.getCachePath()
|
|
140
|
+
},
|
|
141
|
+
[SandboxFolder.Pnpm]: {
|
|
142
|
+
label: "PNPM Home",
|
|
143
|
+
path: this.getPnpmPath()
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
return Object.keys(foldersRecord).map((key) => ({
|
|
147
|
+
name: key,
|
|
148
|
+
...foldersRecord[key]
|
|
149
|
+
}));
|
|
150
|
+
}
|
|
97
151
|
};
|
|
98
152
|
//#endregion
|
|
99
153
|
//#region src/ipc-core.ts
|
|
@@ -460,14 +514,6 @@ const ensure = async (filesPath, defaultContent = "{}") => {
|
|
|
460
514
|
}
|
|
461
515
|
};
|
|
462
516
|
/**
|
|
463
|
-
* Generates a unique temporary folder.
|
|
464
|
-
*/
|
|
465
|
-
const generateTempFolder = async (base) => {
|
|
466
|
-
const targetBase = base || tmpdir();
|
|
467
|
-
await mkdir(targetBase, { recursive: true });
|
|
468
|
-
return await mkdtemp(join(await realpath(targetBase), "pipelab-"));
|
|
469
|
-
};
|
|
470
|
-
/**
|
|
471
517
|
* Extracts a .tar.gz archive.
|
|
472
518
|
*/
|
|
473
519
|
async function extractTarGz(archivePath, destinationDir) {
|
|
@@ -600,8 +646,7 @@ async function getFolderSize(dirPath) {
|
|
|
600
646
|
//#endregion
|
|
601
647
|
//#region src/config.ts
|
|
602
648
|
const getMigrator = (name) => {
|
|
603
|
-
|
|
604
|
-
if (name.startsWith("pipeline-") || path.isAbsolute(name) || name.endsWith(".json")) return configRegistry["pipeline"];
|
|
649
|
+
return configRegistry[name] || configRegistry["pipeline"];
|
|
605
650
|
};
|
|
606
651
|
const setupConfigFile = async (name, options) => {
|
|
607
652
|
const ctx = options.context;
|
|
@@ -633,8 +678,9 @@ const setupConfigFile = async (name, options) => {
|
|
|
633
678
|
parseFailed = true;
|
|
634
679
|
}
|
|
635
680
|
let json = void 0;
|
|
681
|
+
let migrationFailed = false;
|
|
636
682
|
try {
|
|
637
|
-
json = await migrator.migrate(originalJson, {
|
|
683
|
+
if (!parseFailed) json = await migrator.migrate(originalJson, {
|
|
638
684
|
debug: false,
|
|
639
685
|
onStep: async (state, version) => {
|
|
640
686
|
const parsedPath = path.parse(filesPath);
|
|
@@ -647,16 +693,30 @@ const setupConfigFile = async (name, options) => {
|
|
|
647
693
|
}
|
|
648
694
|
}
|
|
649
695
|
});
|
|
696
|
+
else json = migrator.defaultValue;
|
|
650
697
|
} catch (e) {
|
|
651
698
|
logger().error(`Error migrating config ${name}:`, e);
|
|
699
|
+
migrationFailed = true;
|
|
652
700
|
json = migrator.defaultValue;
|
|
653
701
|
}
|
|
654
702
|
let normalized = false;
|
|
655
703
|
if (name.startsWith("pipeline-") || path.isAbsolute(name) || name.endsWith(".json") || name === "pipeline") normalized = normalizePipelineConfig(json);
|
|
656
|
-
if (originalJson?.version !== json?.version || normalized || content === void 0 || parseFailed)
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
704
|
+
if (originalJson?.version !== json?.version || normalized || content === void 0 || parseFailed || migrationFailed) {
|
|
705
|
+
if (parseFailed || migrationFailed) try {
|
|
706
|
+
const parsedPath = path.parse(filesPath);
|
|
707
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
708
|
+
const corruptedPath = path.join(parsedPath.dir, `${parsedPath.name}.corrupted.${timestamp}.json`);
|
|
709
|
+
const backupContent = parseFailed ? content || "" : JSON.stringify(originalJson, null, 2);
|
|
710
|
+
await fs$1.writeFile(corruptedPath, backupContent);
|
|
711
|
+
logger().info(`Corrupted config file preserved at ${corruptedPath}`);
|
|
712
|
+
} catch (e) {
|
|
713
|
+
logger().error(`Failed to backup corrupted config ${name}:`, e);
|
|
714
|
+
}
|
|
715
|
+
try {
|
|
716
|
+
await fs$1.writeFile(filesPath, JSON.stringify(json));
|
|
717
|
+
} catch (e) {
|
|
718
|
+
logger().error(`Error saving migrated config ${name}:`, e);
|
|
719
|
+
}
|
|
660
720
|
}
|
|
661
721
|
return json;
|
|
662
722
|
}
|
|
@@ -999,6 +1059,15 @@ var BuildHistoryStorage = class {
|
|
|
999
1059
|
const files = await this.getAllPipelineFiles();
|
|
1000
1060
|
const diskSpace = await checkDiskSpace(this.context.userDataPath);
|
|
1001
1061
|
const pipelabSize = await getFolderSize(this.context.userDataPath);
|
|
1062
|
+
const folders = [];
|
|
1063
|
+
for (const folder of this.context.getSandboxFolders()) {
|
|
1064
|
+
const size = await getFolderSize(folder.path);
|
|
1065
|
+
folders.push({
|
|
1066
|
+
name: folder.name,
|
|
1067
|
+
label: folder.label,
|
|
1068
|
+
size
|
|
1069
|
+
});
|
|
1070
|
+
}
|
|
1002
1071
|
const policy = (await (await setupConfigFile("settings", { context: this.context })).getConfig())?.buildHistory?.retentionPolicy || {
|
|
1003
1072
|
enabled: false,
|
|
1004
1073
|
maxEntries: 50,
|
|
@@ -1017,7 +1086,8 @@ var BuildHistoryStorage = class {
|
|
|
1017
1086
|
disk: {
|
|
1018
1087
|
total: diskSpace.size,
|
|
1019
1088
|
free: diskSpace.free,
|
|
1020
|
-
pipelab: pipelabSize
|
|
1089
|
+
pipelab: pipelabSize,
|
|
1090
|
+
folders
|
|
1021
1091
|
}
|
|
1022
1092
|
};
|
|
1023
1093
|
let totalSize = 0;
|
|
@@ -1045,7 +1115,8 @@ var BuildHistoryStorage = class {
|
|
|
1045
1115
|
disk: {
|
|
1046
1116
|
total: diskSpace.size,
|
|
1047
1117
|
free: diskSpace.free,
|
|
1048
|
-
pipelab: pipelabSize
|
|
1118
|
+
pipelab: pipelabSize,
|
|
1119
|
+
folders
|
|
1049
1120
|
}
|
|
1050
1121
|
};
|
|
1051
1122
|
} catch (error) {
|
|
@@ -1357,7 +1428,7 @@ const registerHistoryHandlers = (context) => {
|
|
|
1357
1428
|
}
|
|
1358
1429
|
}
|
|
1359
1430
|
};
|
|
1360
|
-
await settings.
|
|
1431
|
+
await settings.setConfig(newConfig);
|
|
1361
1432
|
send({
|
|
1362
1433
|
type: "end",
|
|
1363
1434
|
data: {
|
|
@@ -8831,10 +8902,7 @@ function registerMigrationHandlers(context) {
|
|
|
8831
8902
|
const { config: name } = value;
|
|
8832
8903
|
logger().info("[CLI Migration] config:load", name);
|
|
8833
8904
|
try {
|
|
8834
|
-
|
|
8835
|
-
if (name === "projects") migrator = fileRepoMigrations;
|
|
8836
|
-
else if (name === "settings") migrator = appSettingsMigrator;
|
|
8837
|
-
else if (name.startsWith("pipeline-") || name.endsWith(".plb")) migrator = savedFileMigrator;
|
|
8905
|
+
const migrator = getMigrator(name);
|
|
8838
8906
|
if (!migrator) throw new Error(`No migrator found for configuration: ${name}. All files loaded via config:load MUST have a migration schema.`);
|
|
8839
8907
|
send({
|
|
8840
8908
|
type: "end",
|
|
@@ -8946,8 +9014,6 @@ async function serveCommand(options, version, _dirname) {
|
|
|
8946
9014
|
}
|
|
8947
9015
|
//#endregion
|
|
8948
9016
|
//#region src/utils/remote.ts
|
|
8949
|
-
const DEFAULT_NODE_VERSION = "24.14.1";
|
|
8950
|
-
const DEFAULT_PNPM_VERSION = "10.12.0";
|
|
8951
9017
|
function isPackageComplete(packageDir) {
|
|
8952
9018
|
return existsSync(join(packageDir, "package.json"));
|
|
8953
9019
|
}
|
|
@@ -9139,7 +9205,7 @@ async function ensureNodeJS(context, version = DEFAULT_NODE_VERSION) {
|
|
|
9139
9205
|
const extension = isWindows ? "zip" : "tar.gz";
|
|
9140
9206
|
const fileName = `node-v${version}-${platform === "osx" ? "darwin" : platform}-${arch}.${extension}`;
|
|
9141
9207
|
const downloadUrl = `https://nodejs.org/dist/v${version}/${fileName}`;
|
|
9142
|
-
const tempDir = await
|
|
9208
|
+
const tempDir = await context.createTempFolder("node-download-");
|
|
9143
9209
|
const archivePath = join(tempDir, fileName);
|
|
9144
9210
|
sendStartupProgress(`Downloading Node.js v${version}...`);
|
|
9145
9211
|
console.log(`Downloading Node.js from ${downloadUrl}...`);
|
|
@@ -9671,7 +9737,6 @@ const builtInPlugins = async (options) => {
|
|
|
9671
9737
|
webSocketServer.broadcast("startup:progress", { type: "ready" });
|
|
9672
9738
|
}, 2e3);
|
|
9673
9739
|
})();
|
|
9674
|
-
return [];
|
|
9675
9740
|
};
|
|
9676
9741
|
//#endregion
|
|
9677
9742
|
//#region src/utils.ts
|
|
@@ -9727,7 +9792,7 @@ const executeGraphWithHistory = async ({ graph, variables, projectName, projectP
|
|
|
9727
9792
|
const shouldDisableHistory = process.env.PIPELAB_DISABLE_HISTORY === "true";
|
|
9728
9793
|
if (!shouldDisableHistory) await buildHistoryStorage.save(initialEntry);
|
|
9729
9794
|
const logs = [];
|
|
9730
|
-
const sandboxPath = await
|
|
9795
|
+
const sandboxPath = await ctx.createTempFolder("pipeline-sandbox-");
|
|
9731
9796
|
const { logger } = useLogger();
|
|
9732
9797
|
let completedSteps = 0;
|
|
9733
9798
|
const { registerPlugins, plugins: registeredPlugins } = usePlugins();
|
|
@@ -10193,8 +10258,9 @@ const registerEngineHandlers = (context) => {
|
|
|
10193
10258
|
};
|
|
10194
10259
|
handle("action:execute", async (event, { send, value }) => {
|
|
10195
10260
|
const { nodeId, params, pluginId } = value;
|
|
10196
|
-
|
|
10197
|
-
const
|
|
10261
|
+
await (await setupConfigFile("settings", { context })).getConfig();
|
|
10262
|
+
const cachePath = join(context.userDataPath, "cache", "actions", pluginId, nodeId);
|
|
10263
|
+
const cwd = await context.createTempFolder("action-execute-");
|
|
10198
10264
|
const mainWindow = void 0;
|
|
10199
10265
|
abortControllerGraph = new AbortController();
|
|
10200
10266
|
const signalPromise = new Promise((resolve, reject) => {
|
|
@@ -10233,11 +10299,11 @@ const registerEngineHandlers = (context) => {
|
|
|
10233
10299
|
});
|
|
10234
10300
|
handle("graph:execute", async (event, { send, value }) => {
|
|
10235
10301
|
const { graph, variables, projectName, projectPath, pipelineId } = value;
|
|
10236
|
-
|
|
10302
|
+
await (await setupConfigFile("settings", { context })).getConfig();
|
|
10237
10303
|
const effectiveProjectName = projectName || "Unnamed Project";
|
|
10238
10304
|
const effectiveProjectPath = projectPath || "";
|
|
10239
10305
|
const effectivePipelineId = pipelineId || "unknown";
|
|
10240
|
-
const effectiveCachePath =
|
|
10306
|
+
const effectiveCachePath = join(context.userDataPath, "cache", effectivePipelineId);
|
|
10241
10307
|
const mainWindow = void 0;
|
|
10242
10308
|
abortControllerGraph = new AbortController();
|
|
10243
10309
|
try {
|
|
@@ -10741,14 +10807,11 @@ const registerPluginsHandlers = (context) => {
|
|
|
10741
10807
|
}
|
|
10742
10808
|
});
|
|
10743
10809
|
handle("plugin:ensure-loaded", async (_, { send, value }) => {
|
|
10744
|
-
const {
|
|
10810
|
+
const { plugins } = value;
|
|
10745
10811
|
const { plugins: registeredPlugins, registerPlugins } = usePlugins();
|
|
10746
10812
|
const loaded = [];
|
|
10747
10813
|
const failed = [];
|
|
10748
10814
|
const pluginsToEnsure = /* @__PURE__ */ new Set();
|
|
10749
|
-
if (Array.isArray(pluginIds)) {
|
|
10750
|
-
for (const id of pluginIds) if (id) pluginsToEnsure.add(id);
|
|
10751
|
-
}
|
|
10752
10815
|
if (plugins && typeof plugins === "object") {
|
|
10753
10816
|
for (const id of Object.keys(plugins)) if (id) pluginsToEnsure.add(id);
|
|
10754
10817
|
}
|
|
@@ -53238,6 +53301,6 @@ async function fetchLatestDesktopRelease(options = {}) {
|
|
|
53238
53301
|
return latest;
|
|
53239
53302
|
}
|
|
53240
53303
|
//#endregion
|
|
53241
|
-
export { BuildHistoryStorage,
|
|
53304
|
+
export { BuildHistoryStorage, PipelabContext, WebSocketServer, builtInPlugins, downloadFile, ensure, ensureNodeJS, ensurePNPM, executeGraphWithHistory, extractTarGz, extractZip, fetchLatestDesktopRelease, fetchLatestPackageRelease, fetchPackage, fetchPackageReleases, fetchPipelabAsset, fetchPipelabCli, fetchPipelabPlugin, findInstalledPlugins, getDefaultUserDataPath, getFinalPlugins, getFolderSize, getMigrator, handleActionExecute, isDev, loadCustomPlugin, loadPipelabPlugin, projectRoot, registerAgentsHandlers, registerAllHandlers, registerConfigHandlers, registerEngineHandlers, registerFsHandlers, registerHistoryHandlers, registerMigrationHandlers, registerShellHandlers, runPipelineCommand, runPnpm, runWithLiveLogs, sendStartupProgress, sendStartupReady, serveCommand, setupConfigFile, useAPI, usePluginAPI, webSocketServer, zipFolder };
|
|
53242
53305
|
|
|
53243
53306
|
//# sourceMappingURL=index.mjs.map
|