@pipelab/core-node 1.0.0-beta.17 → 1.0.0-beta.19

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.
@@ -1,8 +1,7 @@
1
1
  import { PipelabContext } from "../context";
2
2
  import { join } from "node:path";
3
- import { writeFile, readFile, unlink, mkdir, stat, readdir } from "node:fs/promises";
3
+ import { writeFile, readFile, unlink, mkdir, stat, readdir, rm } from "node:fs/promises";
4
4
  import { useLogger, BuildHistoryEntry, IBuildHistoryStorage, AppConfig } from "@pipelab/shared";
5
- import { setupConfigFile } from "../config";
6
5
  import checkDiskSpace from "check-disk-space";
7
6
  import { getFolderSize } from "../utils/fs-extras";
8
7
  import { SandboxFolder } from "@pipelab/constants";
@@ -17,18 +16,11 @@ export class BuildHistoryStorage implements IBuildHistoryStorage {
17
16
  }
18
17
 
19
18
  private getStoragePath() {
20
- return join(this.context.userDataPath, "build-history");
19
+ return this.context.getConfigPath("pipelines");
21
20
  }
22
21
 
23
22
  private getPipelinePath(pipelineId: string): string {
24
- // Sanitize the pipelineId to create a valid filename
25
- // Replace invalid filename characters with underscores
26
- const sanitizedId = pipelineId
27
- .replace(/[/\:*?"<>|]/g, "_")
28
- .replace(/__/g, "_") // Replace multiple underscores with single
29
- .replace(/^_+|_+$/g, ""); // Remove leading/trailing underscores
30
-
31
- return join(this.getStoragePath(), `pipeline-${sanitizedId}.json`);
23
+ return join(this.getStoragePath(), `${pipelineId}.history.json`);
32
24
  }
33
25
 
34
26
  private async ensureStoragePath(): Promise<void> {
@@ -65,51 +57,6 @@ export class BuildHistoryStorage implements IBuildHistoryStorage {
65
57
  }
66
58
  }
67
59
 
68
- async applyRetentionPolicy(): Promise<void> {
69
- try {
70
- this.logger.logger().info("Applying build history retention policy...");
71
- const settings = await setupConfigFile<AppConfig>("settings", { context: this.context });
72
- const config = await settings.getConfig();
73
- const policy = config?.buildHistory?.retentionPolicy;
74
-
75
- if (!policy || !policy.enabled) {
76
- this.logger.logger().info("Retention policy is disabled. Skipping.");
77
- return;
78
- }
79
-
80
- const { maxAge, maxEntries } = policy;
81
- const pipelineFiles = await this.getAllPipelineFiles();
82
-
83
- for (const file of pipelineFiles) {
84
- const pipelineId = file.replace("pipeline-", "").replace(".json", "");
85
- let entries = await this.loadPipelineHistory(pipelineId);
86
- const originalCount = entries.length;
87
-
88
- // 1. Filter by maxAge
89
- if (maxAge > 0) {
90
- const minDate = Date.now() - maxAge * 24 * 60 * 60 * 1000;
91
- entries = entries.filter((entry) => entry.createdAt >= minDate);
92
- }
93
-
94
- // 2. Filter by maxEntries (sort by date first to keep the newest)
95
- if (maxEntries > 0 && entries.length > maxEntries) {
96
- entries = entries.sort((a, b) => b.createdAt - a.createdAt).slice(0, maxEntries);
97
- }
98
-
99
- if (entries.length < originalCount) {
100
- this.logger
101
- .logger()
102
- .info(`[${pipelineId}] Pruned ${originalCount - entries.length} history entries.`);
103
- await this.savePipelineHistory(pipelineId, entries);
104
- }
105
- }
106
- this.logger.logger().info("Retention policy applied successfully.");
107
- } catch (error) {
108
- this.logger.logger().error("Failed to apply retention policy:", error);
109
- // We don't re-throw here as this is a background task and shouldn't crash the app
110
- }
111
- }
112
-
113
60
  async save(entry: BuildHistoryEntry): Promise<void> {
114
61
  try {
115
62
  const entries = await this.loadPipelineHistory(entry.pipelineId);
@@ -125,11 +72,6 @@ export class BuildHistoryStorage implements IBuildHistoryStorage {
125
72
  this.logger
126
73
  .logger()
127
74
  .info(`Saved build history entry: ${entry.id} for pipeline: ${entry.pipelineId}`);
128
-
129
- // Apply retention policy after each save
130
- this.applyRetentionPolicy().catch((err) => {
131
- this.logger.logger().error("Failed to apply retention policy after save:", err);
132
- });
133
75
  } catch (error) {
134
76
  this.logger.logger().error("Failed to save build history entry:", error);
135
77
  throw new Error(`Failed to save build history entry: ${error}`);
@@ -145,7 +87,8 @@ export class BuildHistoryStorage implements IBuildHistoryStorage {
145
87
 
146
88
  const files = await this.getAllPipelineFiles();
147
89
  for (const file of files) {
148
- const pId = file.replace("pipeline-", "").replace(".json", "");
90
+ const pId = this.parsePipelineIdFromFilename(file);
91
+ if (!pId) continue;
149
92
  const entries = await this.loadPipelineHistory(pId);
150
93
  const entry = entries.find((e) => e.id === id);
151
94
  if (entry) return entry;
@@ -162,7 +105,8 @@ export class BuildHistoryStorage implements IBuildHistoryStorage {
162
105
  const files = await this.getAllPipelineFiles();
163
106
  const allEntries: BuildHistoryEntry[] = [];
164
107
  for (const file of files) {
165
- const pipelineId = file.replace("pipeline-", "").replace(".json", "");
108
+ const pipelineId = this.parsePipelineIdFromFilename(file);
109
+ if (!pipelineId) continue;
166
110
  const entries = await this.loadPipelineHistory(pipelineId);
167
111
  allEntries.push(...entries);
168
112
  }
@@ -200,7 +144,8 @@ export class BuildHistoryStorage implements IBuildHistoryStorage {
200
144
  } else {
201
145
  const files = await this.getAllPipelineFiles();
202
146
  for (const file of files) {
203
- const pId = file.replace("pipeline-", "").replace(".json", "");
147
+ const pId = this.parsePipelineIdFromFilename(file);
148
+ if (!pId) continue;
204
149
  const entries = await this.loadPipelineHistory(pId);
205
150
  const entryIndex = entries.findIndex((e) => e.id === id);
206
151
  if (entryIndex >= 0) {
@@ -231,7 +176,8 @@ export class BuildHistoryStorage implements IBuildHistoryStorage {
231
176
  } else {
232
177
  const files = await this.getAllPipelineFiles();
233
178
  for (const file of files) {
234
- const pId = file.replace("pipeline-", "").replace(".json", "");
179
+ const pId = this.parsePipelineIdFromFilename(file);
180
+ if (!pId) continue;
235
181
  const entries = await this.loadPipelineHistory(pId);
236
182
  const entryIndex = entries.findIndex((e) => e.id === id);
237
183
  if (entryIndex >= 0) {
@@ -253,8 +199,26 @@ export class BuildHistoryStorage implements IBuildHistoryStorage {
253
199
  try {
254
200
  await this.ensureStoragePath();
255
201
  const files = await this.getAllPipelineFiles();
256
- await Promise.all(files.map((file) => unlink(join(this.getStoragePath(), file))));
202
+ const cachePathsToDelete = new Set<string>();
203
+
204
+ for (const file of files) {
205
+ const pipelineId = this.parsePipelineIdFromFilename(file);
206
+ if (pipelineId) {
207
+ const entries = await this.loadPipelineHistory(pipelineId);
208
+ for (const entry of entries) {
209
+ if (entry.cachePath) {
210
+ cachePathsToDelete.add(entry.cachePath);
211
+ }
212
+ }
213
+ }
214
+ await unlink(join(this.getStoragePath(), file));
215
+ }
216
+
257
217
  this.logger.logger().info("Cleared all build history");
218
+
219
+ for (const cachePath of cachePathsToDelete) {
220
+ await rm(cachePath, { recursive: true, force: true }).catch(() => {});
221
+ }
258
222
  } catch (error) {
259
223
  this.logger.logger().error("Failed to clear build history:", error);
260
224
  throw new Error(`Failed to clear build history: ${error}`);
@@ -264,8 +228,19 @@ export class BuildHistoryStorage implements IBuildHistoryStorage {
264
228
  async clearByPipeline(pipelineId: string): Promise<void> {
265
229
  try {
266
230
  const pipelinePath = this.getPipelinePath(pipelineId);
231
+ const entries = await this.loadPipelineHistory(pipelineId);
267
232
  await unlink(pipelinePath);
268
233
  this.logger.logger().info(`Cleared history for pipeline "${pipelineId}"`);
234
+
235
+ const cachePathsToDelete = new Set<string>();
236
+ for (const entry of entries) {
237
+ if (entry.cachePath) {
238
+ cachePathsToDelete.add(entry.cachePath);
239
+ }
240
+ }
241
+ for (const cachePath of cachePathsToDelete) {
242
+ await rm(cachePath, { recursive: true, force: true }).catch(() => {});
243
+ }
269
244
  } catch (error: any) {
270
245
  if (error.code === "ENOENT") {
271
246
  this.logger
@@ -285,11 +260,6 @@ export class BuildHistoryStorage implements IBuildHistoryStorage {
285
260
  newestEntry?: number;
286
261
  numberOfPipelines: number;
287
262
  userDataPath: string;
288
- retentionPolicy: {
289
- enabled: boolean;
290
- maxEntries: number;
291
- maxAge: number;
292
- };
293
263
  disk: {
294
264
  total: number;
295
265
  free: number;
@@ -314,25 +284,12 @@ export class BuildHistoryStorage implements IBuildHistoryStorage {
314
284
  });
315
285
  }
316
286
 
317
- const settings = await setupConfigFile<AppConfig>("settings", { context: this.context });
318
- const config = await settings.getConfig();
319
- const policy = config?.buildHistory?.retentionPolicy || {
320
- enabled: false,
321
- maxEntries: 50,
322
- maxAge: 30,
323
- };
324
-
325
287
  if (allEntries.length === 0) {
326
288
  return {
327
289
  totalEntries: 0,
328
290
  totalSize: 0,
329
291
  numberOfPipelines: files.length,
330
292
  userDataPath: this.context.userDataPath,
331
- retentionPolicy: {
332
- enabled: policy.enabled,
333
- maxEntries: policy.maxEntries,
334
- maxAge: policy.maxAge,
335
- },
336
293
  disk: {
337
294
  total: diskSpace.size,
338
295
  free: diskSpace.free,
@@ -362,11 +319,6 @@ export class BuildHistoryStorage implements IBuildHistoryStorage {
362
319
  newestEntry: sortedEntries[sortedEntries.length - 1]?.createdAt,
363
320
  numberOfPipelines: files.length,
364
321
  userDataPath: this.context.userDataPath,
365
- retentionPolicy: {
366
- enabled: policy.enabled,
367
- maxEntries: policy.maxEntries,
368
- maxAge: policy.maxAge,
369
- },
370
322
  disk: {
371
323
  total: diskSpace.size,
372
324
  free: diskSpace.free,
@@ -384,9 +336,14 @@ export class BuildHistoryStorage implements IBuildHistoryStorage {
384
336
  try {
385
337
  await this.ensureStoragePath();
386
338
  const files = await readdir(this.getStoragePath());
387
- return files.filter((file) => file.startsWith("pipeline-") && file.endsWith(".json"));
339
+ return files.filter((file) => file.endsWith(".history.json"));
388
340
  } catch (error) {
389
341
  return [];
390
342
  }
391
343
  }
344
+
345
+ private parsePipelineIdFromFilename(filename: string): string | null {
346
+ const match = filename.match(/^(.+)\.history\.json$/);
347
+ return match ? match[1] : null;
348
+ }
392
349
  }
@@ -1,157 +1,318 @@
1
1
  import { useAPI } from "../ipc-core";
2
- import { useLogger, configRegistry } from "@pipelab/shared";
3
- import { setupConfigFile, getMigrator } from "../config";
2
+ import {
3
+ useLogger,
4
+ appSettingsMigrator,
5
+ connectionsMigrator,
6
+ fileRepoMigrations,
7
+ } from "@pipelab/shared";
8
+ import {
9
+ setupSettingsConfigFile,
10
+ setupConnectionsConfigFile,
11
+ setupProjectsConfigFile,
12
+ setupPipelineConfigFileByName,
13
+ setupPipelineConfigFileByPath,
14
+ deletePipelineConfigFileByName,
15
+ deletePipelineConfigFileByPath,
16
+ } from "../config";
4
17
  import { PipelabContext } from "../context";
5
- import fs from "node:fs/promises";
6
- import path from "node:path";
7
18
 
8
19
  export const registerConfigHandlers = (context: PipelabContext) => {
9
20
  const { handle } = useAPI();
10
21
  const { logger } = useLogger();
11
22
 
12
- handle("config:load", async (_, { send, value }) => {
13
- const { config: name } = value;
14
- logger().info("config:load", name);
15
-
23
+ // Settings
24
+ handle("settings:load", async (_, { send }) => {
25
+ logger().info("settings:load");
16
26
  try {
17
- const manager = await setupConfigFile(name, { context });
27
+ const manager = await setupSettingsConfigFile(context);
18
28
  const json = await manager.getConfig();
19
-
20
29
  send({
21
30
  type: "end",
22
- data: {
23
- type: "success",
24
- result: {
25
- result: json,
26
- },
27
- },
31
+ data: { type: "success", result: json },
28
32
  });
29
33
  } catch (e) {
30
- logger().error(`config:load error for ${name}:`, e);
34
+ logger().error("settings:load error:", e);
31
35
  send({
32
36
  type: "end",
33
- data: {
34
- type: "error",
35
- ipcError: e instanceof Error ? e.message : `Unable to load config ${name}`,
36
- },
37
+ data: { type: "error", ipcError: e instanceof Error ? e.message : "Unable to load settings" },
37
38
  });
38
39
  }
39
40
  });
40
41
 
41
- handle("config:save", async (_, { send, value }) => {
42
- const { data, config: name } = value;
43
-
42
+ handle("settings:save", async (_, { send, value }) => {
43
+ const { data } = value;
44
44
  try {
45
- const manager = await setupConfigFile(name, { context });
45
+ const manager = await setupSettingsConfigFile(context);
46
46
  const json = typeof data === "string" ? JSON.parse(data) : data;
47
47
  await manager.setConfig(json);
48
+ send({
49
+ type: "end",
50
+ data: { type: "success", result: "ok" },
51
+ });
52
+ } catch (e) {
53
+ logger().error("settings:save error:", e);
54
+ send({
55
+ type: "end",
56
+ data: { type: "error", ipcError: e instanceof Error ? e.message : "Unable to save settings" },
57
+ });
58
+ }
59
+ });
48
60
 
61
+ handle("settings:reset", async (_, { send, value }) => {
62
+ const { key } = value;
63
+ try {
64
+ const manager = await setupSettingsConfigFile(context);
65
+ const currentConfig = await manager.getConfig();
66
+ const defaultValue = (appSettingsMigrator.defaultValue as any)[key];
67
+ await manager.setConfig({
68
+ ...(currentConfig ? (currentConfig as any) : {}),
69
+ [key]: defaultValue,
70
+ } as any);
49
71
  send({
50
72
  type: "end",
51
- data: {
52
- type: "success",
53
- result: {
54
- result: "ok",
55
- },
56
- },
73
+ data: { type: "success", result: "ok" },
57
74
  });
58
75
  } catch (e) {
59
- logger().error(`config:save error for ${name}:`, e);
76
+ logger().error("settings:reset error:", e);
60
77
  send({
61
78
  type: "end",
62
- data: {
63
- type: "error",
64
- ipcError: e instanceof Error ? e.message : `Unable to save config ${name}`,
65
- },
79
+ data: { type: "error", ipcError: e instanceof Error ? e.message : "Unable to reset settings" },
66
80
  });
67
81
  }
68
82
  });
69
83
 
70
- handle("config:reset", async (event, { value, send }) => {
71
- const { config: name, key } = value;
72
- logger().info("config:reset", name, key);
84
+ // Connections
85
+ handle("connections:load", async (_, { send }) => {
86
+ logger().info("connections:load");
87
+ try {
88
+ const manager = await setupConnectionsConfigFile(context);
89
+ const json = await manager.getConfig();
90
+ send({
91
+ type: "end",
92
+ data: { type: "success", result: json },
93
+ });
94
+ } catch (e) {
95
+ logger().error("connections:load error:", e);
96
+ send({
97
+ type: "end",
98
+ data: { type: "error", ipcError: e instanceof Error ? e.message : "Unable to load connections" },
99
+ });
100
+ }
101
+ });
73
102
 
103
+ handle("connections:save", async (_, { send, value }) => {
104
+ const { data } = value;
74
105
  try {
75
- const manager = await setupConfigFile(name, { context });
76
- const currentConfig = await manager.getConfig();
106
+ const manager = await setupConnectionsConfigFile(context);
107
+ const json = typeof data === "string" ? JSON.parse(data) : data;
108
+ await manager.setConfig(json);
109
+ send({
110
+ type: "end",
111
+ data: { type: "success", result: "ok" },
112
+ });
113
+ } catch (e) {
114
+ logger().error("connections:save error:", e);
115
+ send({
116
+ type: "end",
117
+ data: { type: "error", ipcError: e instanceof Error ? e.message : "Unable to save connections" },
118
+ });
119
+ }
120
+ });
77
121
 
78
- const migrator = getMigrator(name);
122
+ handle("connections:reset", async (_, { send, value }) => {
123
+ const { key } = value;
124
+ try {
125
+ const manager = await setupConnectionsConfigFile(context);
126
+ const currentConfig = await manager.getConfig();
127
+ const defaultValue = (connectionsMigrator.defaultValue as any)[key];
128
+ await manager.setConfig({
129
+ ...(currentConfig ? (currentConfig as any) : {}),
130
+ [key]: defaultValue,
131
+ } as any);
132
+ send({
133
+ type: "end",
134
+ data: { type: "success", result: "ok" },
135
+ });
136
+ } catch (e) {
137
+ logger().error("connections:reset error:", e);
138
+ send({
139
+ type: "end",
140
+ data: { type: "error", ipcError: e instanceof Error ? e.message : "Unable to reset connections" },
141
+ });
142
+ }
143
+ });
79
144
 
80
- if (!migrator) {
81
- throw new Error(`No migrator found for configuration: ${name}`);
82
- }
145
+ // Projects
146
+ handle("projects:load", async (_, { send }) => {
147
+ logger().info("projects:load");
148
+ try {
149
+ const manager = await setupProjectsConfigFile(context);
150
+ const json = await manager.getConfig();
151
+ send({
152
+ type: "end",
153
+ data: { type: "success", result: json },
154
+ });
155
+ } catch (e) {
156
+ logger().error("projects:load error:", e);
157
+ send({
158
+ type: "end",
159
+ data: { type: "error", ipcError: e instanceof Error ? e.message : "Unable to load projects" },
160
+ });
161
+ }
162
+ });
83
163
 
84
- const defaultValue = (migrator.defaultValue as any)[key];
164
+ handle("projects:save", async (_, { send, value }) => {
165
+ const { data } = value;
166
+ try {
167
+ const manager = await setupProjectsConfigFile(context);
168
+ const json = typeof data === "string" ? JSON.parse(data) : data;
169
+ await manager.setConfig(json);
170
+ send({
171
+ type: "end",
172
+ data: { type: "success", result: "ok" },
173
+ });
174
+ } catch (e) {
175
+ logger().error("projects:save error:", e);
176
+ send({
177
+ type: "end",
178
+ data: { type: "error", ipcError: e instanceof Error ? e.message : "Unable to save projects" },
179
+ });
180
+ }
181
+ });
85
182
 
183
+ handle("projects:reset", async (_, { send, value }) => {
184
+ const { key } = value;
185
+ try {
186
+ const manager = await setupProjectsConfigFile(context);
187
+ const currentConfig = await manager.getConfig();
188
+ const defaultValue = (fileRepoMigrations.defaultValue as any)[key];
86
189
  await manager.setConfig({
87
190
  ...(currentConfig ? (currentConfig as any) : {}),
88
191
  [key]: defaultValue,
89
192
  } as any);
193
+ send({
194
+ type: "end",
195
+ data: { type: "success", result: "ok" },
196
+ });
197
+ } catch (e) {
198
+ logger().error("projects:reset error:", e);
199
+ send({
200
+ type: "end",
201
+ data: { type: "error", ipcError: e instanceof Error ? e.message : "Unable to reset projects" },
202
+ });
203
+ }
204
+ });
90
205
 
206
+ // Pipeline (ByName)
207
+ handle("pipeline:load-by-name", async (_, { send, value }) => {
208
+ const { name } = value;
209
+ logger().info("pipeline:load-by-name", name);
210
+ try {
211
+ const manager = await setupPipelineConfigFileByName(name, context);
212
+ const json = await manager.getConfig();
91
213
  send({
92
214
  type: "end",
93
- data: {
94
- type: "success",
95
- result: {
96
- result: "ok",
97
- },
98
- },
215
+ data: { type: "success", result: json },
99
216
  });
100
217
  } catch (e) {
101
- logger().error(`config:reset error for ${name}:`, e);
218
+ logger().error(`pipeline:load-by-name error for ${name}:`, e);
102
219
  send({
103
220
  type: "end",
104
- data: {
105
- type: "error",
106
- ipcError: e instanceof Error ? e.message : `Unable to reset config ${name}`,
107
- },
221
+ data: { type: "error", ipcError: e instanceof Error ? e.message : `Unable to load pipeline ${name}` },
108
222
  });
109
223
  }
110
224
  });
111
225
 
112
- handle("config:delete", async (_, { send, value }) => {
113
- const { config: name } = value;
114
- logger().info("config:delete", name);
226
+ // Pipeline (ByPath)
227
+ handle("pipeline:load-by-path", async (_, { send, value }) => {
228
+ const { path: absolutePath } = value;
229
+ logger().info("pipeline:load-by-path", absolutePath);
230
+ try {
231
+ const manager = await setupPipelineConfigFileByPath(absolutePath, context);
232
+ const json = await manager.getConfig();
233
+ send({
234
+ type: "end",
235
+ data: { type: "success", result: json },
236
+ });
237
+ } catch (e) {
238
+ logger().error(`pipeline:load-by-path error for ${absolutePath}:`, e);
239
+ send({
240
+ type: "end",
241
+ data: { type: "error", ipcError: e instanceof Error ? e.message : `Unable to load pipeline ${absolutePath}` },
242
+ });
243
+ }
244
+ });
115
245
 
246
+ handle("pipeline:save-by-name", async (_, { send, value }) => {
247
+ const { data, name } = value;
116
248
  try {
117
- // Config could be an absolute path (for external files/pipelines)
118
- // or a name/identifier (for internal config files stored in Pipelab's app data directory).
119
- const isAbsolutePath = path.isAbsolute(name);
120
- const filesPath = isAbsolutePath ? name : context.getConfigPath(`${name}.json`);
121
-
122
- await fs.rm(filesPath, { force: true });
123
-
124
- // Clean up versioned backups too
125
- const parsedPath = path.parse(filesPath);
126
- const dirEntries = await fs.readdir(parsedPath.dir).catch(() => [] as string[]);
127
- const prefix = `${parsedPath.name}.v`;
128
- const suffix = `.json`;
129
- for (const entry of dirEntries) {
130
- if (entry.startsWith(prefix) && entry.endsWith(suffix)) {
131
- const backupPath = path.join(parsedPath.dir, entry);
132
- await fs.rm(backupPath, { force: true }).catch((err) => {
133
- logger().error(`Failed to delete backup ${backupPath}:`, err);
134
- });
135
- }
136
- }
137
-
138
- send({
139
- type: "end",
140
- data: {
141
- type: "success",
142
- result: {
143
- result: "ok",
144
- },
145
- },
249
+ const manager = await setupPipelineConfigFileByName(name, context);
250
+ const json = typeof data === "string" ? JSON.parse(data) : data;
251
+ await manager.setConfig(json);
252
+ send({
253
+ type: "end",
254
+ data: { type: "success", result: "ok" },
255
+ });
256
+ } catch (e) {
257
+ logger().error(`pipeline:save-by-name error for ${name}:`, e);
258
+ send({
259
+ type: "end",
260
+ data: { type: "error", ipcError: e instanceof Error ? e.message : `Unable to save pipeline ${name}` },
261
+ });
262
+ }
263
+ });
264
+
265
+ handle("pipeline:save-by-path", async (_, { send, value }) => {
266
+ const { data, path: absolutePath } = value;
267
+ try {
268
+ const manager = await setupPipelineConfigFileByPath(absolutePath, context);
269
+ const json = typeof data === "string" ? JSON.parse(data) : data;
270
+ await manager.setConfig(json);
271
+ send({
272
+ type: "end",
273
+ data: { type: "success", result: "ok" },
274
+ });
275
+ } catch (e) {
276
+ logger().error(`pipeline:save-by-path error for ${absolutePath}:`, e);
277
+ send({
278
+ type: "end",
279
+ data: { type: "error", ipcError: e instanceof Error ? e.message : `Unable to save pipeline ${absolutePath}` },
280
+ });
281
+ }
282
+ });
283
+
284
+ handle("pipeline:delete-by-name", async (_, { send, value }) => {
285
+ const { name } = value;
286
+ logger().info("pipeline:delete-by-name", name);
287
+ try {
288
+ await deletePipelineConfigFileByName(name, context);
289
+ send({
290
+ type: "end",
291
+ data: { type: "success", result: "ok" },
292
+ });
293
+ } catch (e) {
294
+ logger().error(`pipeline:delete-by-name error for ${name}:`, e);
295
+ send({
296
+ type: "end",
297
+ data: { type: "error", ipcError: e instanceof Error ? e.message : `Unable to delete pipeline ${name}` },
298
+ });
299
+ }
300
+ });
301
+
302
+ handle("pipeline:delete-by-path", async (_, { send, value }) => {
303
+ const { path: absolutePath } = value;
304
+ logger().info("pipeline:delete-by-path", absolutePath);
305
+ try {
306
+ await deletePipelineConfigFileByPath(absolutePath, context);
307
+ send({
308
+ type: "end",
309
+ data: { type: "success", result: "ok" },
146
310
  });
147
311
  } catch (e) {
148
- logger().error(`config:delete error for ${name}:`, e);
312
+ logger().error(`pipeline:delete-by-path error for ${absolutePath}:`, e);
149
313
  send({
150
314
  type: "end",
151
- data: {
152
- type: "error",
153
- ipcError: e instanceof Error ? e.message : `Unable to delete config ${name}`,
154
- },
315
+ data: { type: "error", ipcError: e instanceof Error ? e.message : `Unable to delete pipeline ${absolutePath}` },
155
316
  });
156
317
  }
157
318
  });