@pipelab/shared 1.0.0-beta.3 → 1.0.0-beta.30
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 -1
- package/CHANGELOG.md +234 -0
- package/dist/index.cjs +44534 -0
- package/dist/index.d.cts +4664 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +1514 -499
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1098 -436
- package/dist/index.mjs.map +1 -1
- package/package.json +8 -4
- package/src/apis.ts +126 -31
- package/src/build-history.ts +3 -23
- package/src/config/connections-definition.ts +3 -0
- package/src/config/migrators.ts +176 -25
- package/src/config/projects-definition.ts +8 -1
- package/src/config/projects-types.ts +1 -25
- package/src/config.schema.ts +29 -5
- package/src/evaluator.ts +0 -1
- package/src/graph.ts +2 -70
- package/src/i18n/de_DE.json +138 -51
- package/src/i18n/en_US.json +67 -52
- package/src/i18n/es_ES.json +139 -52
- package/src/i18n/fr_FR.json +128 -44
- package/src/i18n/pt_BR.json +136 -49
- package/src/i18n/zh_CN.json +142 -55
- package/src/index.ts +21 -1
- package/src/ipc.types.ts +2 -0
- package/src/model.test.ts +306 -1
- package/src/model.ts +54 -43
- package/src/plugins/definitions.ts +26 -55
- package/src/plugins-list.ts +17 -0
- package/src/plugins.ts +10 -1
- package/src/utils.ts +26 -0
- package/tsconfig.json +2 -4
- package/tsconfig.test.json +8 -0
- package/tsdown.config.ts +12 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pipelab/shared",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.30",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Shared logic and types for the Pipelab ecosystem",
|
|
6
6
|
"license": "FSL-1.1-MIT",
|
|
@@ -37,17 +37,21 @@
|
|
|
37
37
|
"tslog": "4.9.3",
|
|
38
38
|
"type-fest": "4.26.1",
|
|
39
39
|
"valibot": "0.42.1",
|
|
40
|
-
"@pipelab/
|
|
40
|
+
"@pipelab/constants": "1.0.0-beta.31",
|
|
41
|
+
"@pipelab/migration": "1.0.0-beta.29"
|
|
41
42
|
},
|
|
42
43
|
"devDependencies": {
|
|
43
44
|
"esbuild-plugin-wasm": "1.1.0",
|
|
44
45
|
"tsdown": "0.21.2",
|
|
45
46
|
"typescript": "5.9.3",
|
|
46
|
-
"
|
|
47
|
+
"vitest": "3.1.4",
|
|
48
|
+
"@pipelab/tsconfig": "1.0.0-beta.29"
|
|
47
49
|
},
|
|
48
50
|
"scripts": {
|
|
49
51
|
"build": "tsdown",
|
|
50
52
|
"format": "oxfmt .",
|
|
51
|
-
"lint": "oxlint ."
|
|
53
|
+
"lint": "oxlint .",
|
|
54
|
+
"typecheck": "tsc -b",
|
|
55
|
+
"test": "vitest run"
|
|
52
56
|
}
|
|
53
57
|
}
|
package/src/apis.ts
CHANGED
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
import { RendererPluginDefinition } from "./plugins/definitions";
|
|
2
2
|
import { User, UserResponse } from "@supabase/supabase-js";
|
|
3
3
|
import type { Tagged } from "type-fest";
|
|
4
|
-
import { PresetResult, Steps } from "./model";
|
|
5
|
-
import { AppConfig } from "./config.schema";
|
|
4
|
+
import { PresetResult, Steps, SavedFile } from "./model";
|
|
5
|
+
import { AppConfig, ConnectionsConfig } from "./config.schema";
|
|
6
|
+
import { FileRepo } from "./config/projects-definition";
|
|
6
7
|
import { Agent } from "./websocket.types";
|
|
7
|
-
import {
|
|
8
|
-
BuildHistoryEntry,
|
|
9
|
-
BuildHistoryQuery,
|
|
10
|
-
BuildHistoryResponse,
|
|
11
|
-
BuildHistoryConfig,
|
|
12
|
-
RetentionPolicy,
|
|
13
|
-
} from "./build-history";
|
|
8
|
+
import { BuildHistoryEntry, BuildHistoryQuery, BuildHistoryResponse } from "./build-history";
|
|
14
9
|
|
|
15
10
|
type Event<TYPE extends string, DATA> =
|
|
16
11
|
| { type: TYPE; data: DATA }
|
|
@@ -31,6 +26,62 @@ type EndEvent<DATA> = {
|
|
|
31
26
|
|
|
32
27
|
export type Presets = Record<string, PresetResult>;
|
|
33
28
|
|
|
29
|
+
export type StableDataReport = {
|
|
30
|
+
sourceChannel: "Stable" | "Beta" | "Dev";
|
|
31
|
+
targetChannel: "Stable" | "Beta" | "Dev";
|
|
32
|
+
|
|
33
|
+
// Settings
|
|
34
|
+
settingsExists: boolean;
|
|
35
|
+
settingsVersion: string | null;
|
|
36
|
+
settingsVersionTarget: string | null;
|
|
37
|
+
settingsMtimeSource: number;
|
|
38
|
+
settingsMtimeTarget: number;
|
|
39
|
+
settingsImportable: boolean;
|
|
40
|
+
|
|
41
|
+
// Connections
|
|
42
|
+
connectionsExists: boolean;
|
|
43
|
+
connectionsCount: number;
|
|
44
|
+
connectionsVersion: string | null;
|
|
45
|
+
connectionsVersionTarget: string | null;
|
|
46
|
+
connectionsMtimeSource: number;
|
|
47
|
+
connectionsMtimeTarget: number;
|
|
48
|
+
connectionsImportable: boolean;
|
|
49
|
+
|
|
50
|
+
// Projects
|
|
51
|
+
projectsExists: boolean;
|
|
52
|
+
projectsVersion: string | null;
|
|
53
|
+
projectsVersionTarget: string | null;
|
|
54
|
+
projectsMtimeSource: number;
|
|
55
|
+
projectsMtimeTarget: number;
|
|
56
|
+
projectsImportable: boolean;
|
|
57
|
+
|
|
58
|
+
projects: Array<{
|
|
59
|
+
id: string;
|
|
60
|
+
name: string;
|
|
61
|
+
description: string;
|
|
62
|
+
pipelines: Array<{
|
|
63
|
+
id: string;
|
|
64
|
+
name: string;
|
|
65
|
+
description: string;
|
|
66
|
+
type: "internal" | "external" | "pipelab-cloud";
|
|
67
|
+
lastModifiedStable?: string;
|
|
68
|
+
lastModifiedBeta?: string;
|
|
69
|
+
existsInBeta: boolean;
|
|
70
|
+
}>;
|
|
71
|
+
}>;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export type ReleaseChannel = "stable" | "beta" | "dev";
|
|
75
|
+
export type MigrationChannel = "stable" | "beta";
|
|
76
|
+
|
|
77
|
+
export type MigrationOptions = {
|
|
78
|
+
migrateSettings: boolean;
|
|
79
|
+
migrateConnections: boolean;
|
|
80
|
+
selectedProjects: string[];
|
|
81
|
+
selectedPipelines: string[];
|
|
82
|
+
sourceChannel?: MigrationChannel;
|
|
83
|
+
};
|
|
84
|
+
|
|
34
85
|
export type IpcDefinition = {
|
|
35
86
|
"fs:read": [
|
|
36
87
|
// input
|
|
@@ -72,6 +123,7 @@ export type IpcDefinition = {
|
|
|
72
123
|
}[];
|
|
73
124
|
}>,
|
|
74
125
|
];
|
|
126
|
+
"fs:isPathBlacklisted": [{ path: string }, EndEvent<{ isBlacklisted: boolean }>];
|
|
75
127
|
"fs:getHomeDirectory": [void, EndEvent<{ path: string }>];
|
|
76
128
|
"dialog:showOpenDialog": [
|
|
77
129
|
// input
|
|
@@ -98,24 +150,27 @@ export type IpcDefinition = {
|
|
|
98
150
|
| EndEvent<{ outputs: Record<string, unknown>; tmp: string }>
|
|
99
151
|
),
|
|
100
152
|
];
|
|
101
|
-
|
|
102
|
-
{
|
|
103
|
-
pluginId: string;
|
|
104
|
-
nodeId: string;
|
|
105
|
-
params: any;
|
|
106
|
-
steps: Steps;
|
|
107
|
-
},
|
|
108
|
-
(
|
|
109
|
-
| Event<"progress", unknown>
|
|
110
|
-
| Event<"progress", unknown>
|
|
111
|
-
| EndEvent<{ outputs: Record<string, unknown>; value: boolean }>
|
|
112
|
-
),
|
|
113
|
-
];
|
|
153
|
+
|
|
114
154
|
"constants:get": [void, EndEvent<{ result: { userData: string } }>];
|
|
115
155
|
|
|
116
|
-
"
|
|
117
|
-
"
|
|
118
|
-
"
|
|
156
|
+
"settings:load": [void, EndEvent<AppConfig>];
|
|
157
|
+
"settings:save": [{ data: AppConfig }, EndEvent<"ok">];
|
|
158
|
+
"settings:reset": [{ key: string }, EndEvent<"ok">];
|
|
159
|
+
|
|
160
|
+
"connections:load": [void, EndEvent<ConnectionsConfig>];
|
|
161
|
+
"connections:save": [{ data: ConnectionsConfig }, EndEvent<"ok">];
|
|
162
|
+
"connections:reset": [{ key: string }, EndEvent<"ok">];
|
|
163
|
+
|
|
164
|
+
"projects:load": [void, EndEvent<FileRepo>];
|
|
165
|
+
"projects:save": [{ data: FileRepo }, EndEvent<"ok">];
|
|
166
|
+
"projects:reset": [{ key: string }, EndEvent<"ok">];
|
|
167
|
+
|
|
168
|
+
"pipeline:load-by-name": [{ name: string }, EndEvent<SavedFile>];
|
|
169
|
+
"pipeline:load-by-path": [{ path: string }, EndEvent<SavedFile>];
|
|
170
|
+
"pipeline:save-by-name": [{ name: string; data: string }, EndEvent<"ok">];
|
|
171
|
+
"pipeline:save-by-path": [{ path: string; data: string }, EndEvent<"ok">];
|
|
172
|
+
"pipeline:delete-by-name": [{ name: string }, EndEvent<"ok">];
|
|
173
|
+
"pipeline:delete-by-path": [{ path: string }, EndEvent<"ok">];
|
|
119
174
|
"action:cancel": [void, EndEvent<{ result: "ok" | "ko" }>];
|
|
120
175
|
|
|
121
176
|
// Build History APIs
|
|
@@ -141,10 +196,6 @@ export type IpcDefinition = {
|
|
|
141
196
|
newestEntry?: number;
|
|
142
197
|
}>,
|
|
143
198
|
];
|
|
144
|
-
"build-history:configure": [
|
|
145
|
-
{ config: Partial<BuildHistoryConfig> },
|
|
146
|
-
EndEvent<{ result: "ok" | "ko" }>,
|
|
147
|
-
];
|
|
148
199
|
"agents:get": [void, EndEvent<{ agents: Agent[] }>];
|
|
149
200
|
"graph:execute": [
|
|
150
201
|
{
|
|
@@ -171,8 +222,52 @@ export type IpcDefinition = {
|
|
|
171
222
|
{ name: string; options?: any },
|
|
172
223
|
EndEvent<{ data: any | null; error: any | null }>,
|
|
173
224
|
];
|
|
174
|
-
"agent:version:get": [void, EndEvent<{ version: string }>];
|
|
175
|
-
"
|
|
225
|
+
"agent:version:get": [void, EndEvent<{ version: string; channel: ReleaseChannel }>];
|
|
226
|
+
"system:packages:cleanup": [void, EndEvent<boolean>];
|
|
227
|
+
"startup:progress": [
|
|
228
|
+
void,
|
|
229
|
+
{ type: "progress"; data: { message: string } } | { type: "ready" } | { type: "done" },
|
|
230
|
+
];
|
|
231
|
+
"plugin:loaded": [void, { plugin: RendererPluginDefinition }];
|
|
232
|
+
"plugin:search": [
|
|
233
|
+
{ query: string },
|
|
234
|
+
EndEvent<{
|
|
235
|
+
results: Array<{
|
|
236
|
+
name: string;
|
|
237
|
+
version: string;
|
|
238
|
+
description?: string;
|
|
239
|
+
keywords?: string[];
|
|
240
|
+
date?: string;
|
|
241
|
+
}>;
|
|
242
|
+
}>,
|
|
243
|
+
];
|
|
244
|
+
"plugin:get-details": [
|
|
245
|
+
{ packageName: string },
|
|
246
|
+
EndEvent<{
|
|
247
|
+
name: string;
|
|
248
|
+
latestVersion: string;
|
|
249
|
+
versions: string[];
|
|
250
|
+
description?: string;
|
|
251
|
+
}>,
|
|
252
|
+
];
|
|
253
|
+
"plugin:install": [{ packageName: string; version: string }, EndEvent<{ result: "ok" }>];
|
|
254
|
+
"plugin:uninstall": [{ packageName: string }, EndEvent<{ result: "ok" }>];
|
|
255
|
+
"plugin:list-installed": [
|
|
256
|
+
void,
|
|
257
|
+
EndEvent<{
|
|
258
|
+
installed: Array<{
|
|
259
|
+
name: string;
|
|
260
|
+
version: string;
|
|
261
|
+
description?: string;
|
|
262
|
+
}>;
|
|
263
|
+
}>,
|
|
264
|
+
];
|
|
265
|
+
"plugin:ensure-loaded": [
|
|
266
|
+
{ plugins: Record<string, string> },
|
|
267
|
+
EndEvent<{ loaded: string[]; failed: string[] }>,
|
|
268
|
+
];
|
|
269
|
+
"migration:scan-stable": [{ sourceChannel?: MigrationChannel }, EndEvent<StableDataReport>];
|
|
270
|
+
"migration:perform": [MigrationOptions, EndEvent<{ result: "ok" }>];
|
|
176
271
|
};
|
|
177
272
|
|
|
178
273
|
export type Channels = keyof IpcDefinition;
|
package/src/build-history.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// Build History Storage Types and Interfaces
|
|
2
|
+
import { SandboxFolder } from "@pipelab/constants";
|
|
2
3
|
|
|
3
4
|
export interface ExecutionStep {
|
|
4
5
|
id: string;
|
|
@@ -33,6 +34,7 @@ export interface BuildHistoryEntry {
|
|
|
33
34
|
pipelineId: string;
|
|
34
35
|
projectName: string;
|
|
35
36
|
projectPath: string;
|
|
37
|
+
cachePath?: string;
|
|
36
38
|
status: "running" | "completed" | "failed" | "cancelled";
|
|
37
39
|
startTime: number;
|
|
38
40
|
endTime?: number;
|
|
@@ -77,37 +79,15 @@ export interface IBuildHistoryStorage {
|
|
|
77
79
|
newestEntry?: number;
|
|
78
80
|
numberOfPipelines: number;
|
|
79
81
|
userDataPath: string;
|
|
80
|
-
retentionPolicy: {
|
|
81
|
-
enabled: boolean;
|
|
82
|
-
maxEntries: number;
|
|
83
|
-
maxAge: number;
|
|
84
|
-
};
|
|
85
82
|
disk: {
|
|
86
83
|
total: number;
|
|
87
84
|
free: number;
|
|
88
85
|
pipelab: number;
|
|
86
|
+
folders: Array<{ name: SandboxFolder; label: string; size: number }>;
|
|
89
87
|
};
|
|
90
88
|
}>;
|
|
91
89
|
}
|
|
92
90
|
|
|
93
|
-
// Retention policy configuration
|
|
94
|
-
export interface RetentionPolicy {
|
|
95
|
-
enabled: boolean;
|
|
96
|
-
maxEntries: number;
|
|
97
|
-
maxAge: number; // in milliseconds
|
|
98
|
-
maxSize: number; // in bytes
|
|
99
|
-
keepFailedBuilds: boolean;
|
|
100
|
-
keepSuccessfulBuilds: boolean;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Storage configuration
|
|
104
|
-
export interface BuildHistoryConfig {
|
|
105
|
-
storagePath: string;
|
|
106
|
-
indexFileName: string;
|
|
107
|
-
entryFilePrefix: string;
|
|
108
|
-
retentionPolicy: RetentionPolicy;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
91
|
// Authorization and subscription types
|
|
112
92
|
export interface SubscriptionBenefit {
|
|
113
93
|
id: string;
|
package/src/config/migrators.ts
CHANGED
|
@@ -16,17 +16,48 @@ import {
|
|
|
16
16
|
AppConfigV5,
|
|
17
17
|
AppConfigV6,
|
|
18
18
|
AppConfigV7,
|
|
19
|
+
ConnectionsConfig,
|
|
20
|
+
ConnectionsConfigV1,
|
|
19
21
|
} from "../config.schema";
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
|
|
23
|
+
const DEFAULT_PLUGINS: AppConfig["plugins"] = [
|
|
24
|
+
{
|
|
25
|
+
name: "@pipelab/plugin-construct",
|
|
26
|
+
enabled: true,
|
|
27
|
+
description: "Construct 3 export & packaging",
|
|
28
|
+
},
|
|
29
|
+
{ name: "@pipelab/plugin-filesystem", enabled: true, description: "Filesystem utilities" },
|
|
30
|
+
{ name: "@pipelab/plugin-system", enabled: true, description: "System & shell commands" },
|
|
31
|
+
{ name: "@pipelab/plugin-steam", enabled: true, description: "Steam publishing" },
|
|
32
|
+
{ name: "@pipelab/plugin-itch", enabled: true, description: "Itch.io publishing" },
|
|
33
|
+
{ name: "@pipelab/plugin-electron", enabled: true, description: "Electron packaging" },
|
|
34
|
+
{ name: "@pipelab/plugin-discord", enabled: true, description: "Discord Rich Presence" },
|
|
35
|
+
{ name: "@pipelab/plugin-poki", enabled: true, description: "Poki publishing" },
|
|
36
|
+
{ name: "@pipelab/plugin-nvpatch", enabled: true, description: "NW.js patching" },
|
|
37
|
+
{ name: "@pipelab/plugin-tauri", enabled: true, description: "Tauri packaging" },
|
|
38
|
+
{ name: "@pipelab/plugin-minify", enabled: true, description: "Asset minification" },
|
|
39
|
+
{ name: "@pipelab/plugin-netlify", enabled: true, description: "Netlify deployment" },
|
|
40
|
+
];
|
|
41
|
+
import { FileRepoV1, FileRepoV2, FileRepoV3, FileRepo } from "./projects-types";
|
|
42
|
+
import {
|
|
43
|
+
SavedFileV1,
|
|
44
|
+
SavedFileV2,
|
|
45
|
+
SavedFileV3,
|
|
46
|
+
SavedFileV4,
|
|
47
|
+
SavedFileV5,
|
|
48
|
+
SavedFile,
|
|
49
|
+
} from "../model";
|
|
22
50
|
|
|
23
51
|
// --- Types ---
|
|
24
52
|
|
|
25
53
|
export type Additive<T, P> = OmitVersion<T> & OmitVersion<P>;
|
|
26
54
|
|
|
55
|
+
type DistributiveOmit<T, K extends keyof any> = T extends any ? Omit<T, K> : never;
|
|
56
|
+
type DistributiveOmitVersion<T> = DistributiveOmit<T, keyof MigrationSchema>;
|
|
57
|
+
|
|
27
58
|
const createMigration = <From extends MigrationSchema, To extends MigrationSchema>(config: {
|
|
28
59
|
version: SemVer;
|
|
29
|
-
up: (state: OmitVersion<From>, targetVersion: string) => Awaitable<
|
|
60
|
+
up: (state: OmitVersion<From>, targetVersion: string) => Awaitable<OmitVersion<To>>;
|
|
30
61
|
}) => createMigrationBase<From, To>(config);
|
|
31
62
|
|
|
32
63
|
export interface Migrator<T> {
|
|
@@ -54,13 +85,7 @@ export const defaultAppSettings = settingsMigratorInternal.createDefault({
|
|
|
54
85
|
completed: false,
|
|
55
86
|
},
|
|
56
87
|
},
|
|
57
|
-
|
|
58
|
-
retentionPolicy: {
|
|
59
|
-
enabled: false,
|
|
60
|
-
maxEntries: 50,
|
|
61
|
-
maxAge: 30,
|
|
62
|
-
},
|
|
63
|
-
},
|
|
88
|
+
plugins: DEFAULT_PLUGINS,
|
|
64
89
|
});
|
|
65
90
|
|
|
66
91
|
export const appSettingsMigrator = settingsMigratorInternal.createMigrations({
|
|
@@ -112,18 +137,12 @@ export const appSettingsMigrator = settingsMigratorInternal.createMigrations({
|
|
|
112
137
|
createMigration<AppConfigV6, AppConfigV7>({
|
|
113
138
|
version: "6.0.0" as SemVer,
|
|
114
139
|
up: (state) => {
|
|
115
|
-
|
|
116
|
-
// (Additive only - keeping cacheFolder and clearTemporaryFoldersOnPipelineEnd)
|
|
140
|
+
const { cacheFolder, clearTemporaryFoldersOnPipelineEnd: __, ...rest } = state;
|
|
117
141
|
return {
|
|
118
|
-
...
|
|
142
|
+
...rest,
|
|
143
|
+
cacheFolder,
|
|
119
144
|
agents: [],
|
|
120
|
-
|
|
121
|
-
retentionPolicy: {
|
|
122
|
-
enabled: false,
|
|
123
|
-
maxEntries: 50,
|
|
124
|
-
maxAge: 30,
|
|
125
|
-
},
|
|
126
|
-
},
|
|
145
|
+
plugins: DEFAULT_PLUGINS,
|
|
127
146
|
};
|
|
128
147
|
},
|
|
129
148
|
}),
|
|
@@ -134,12 +153,31 @@ export const appSettingsMigrator = settingsMigratorInternal.createMigrations({
|
|
|
134
153
|
],
|
|
135
154
|
});
|
|
136
155
|
|
|
156
|
+
// --- Connections Migrator ---
|
|
157
|
+
|
|
158
|
+
const connectionsMigratorInternal = createMigrator<ConnectionsConfigV1, ConnectionsConfig>();
|
|
159
|
+
|
|
160
|
+
export const defaultConnections = connectionsMigratorInternal.createDefault({
|
|
161
|
+
version: "1.0.0",
|
|
162
|
+
connections: [],
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
export const connectionsMigrator = connectionsMigratorInternal.createMigrations({
|
|
166
|
+
defaultValue: defaultConnections,
|
|
167
|
+
migrations: [
|
|
168
|
+
createMigration<ConnectionsConfigV1, never>({
|
|
169
|
+
version: "1.0.0" as SemVer,
|
|
170
|
+
up: finalVersion,
|
|
171
|
+
}),
|
|
172
|
+
],
|
|
173
|
+
});
|
|
174
|
+
|
|
137
175
|
// --- Projects Migrator ---
|
|
138
176
|
|
|
139
177
|
const fileRepoMigratorInternal = createMigrator<FileRepoV1, FileRepo>();
|
|
140
178
|
|
|
141
179
|
export const defaultFileRepo = fileRepoMigratorInternal.createDefault({
|
|
142
|
-
version: "
|
|
180
|
+
version: "3.0.0",
|
|
143
181
|
projects: [
|
|
144
182
|
{
|
|
145
183
|
id: "main",
|
|
@@ -178,8 +216,16 @@ export const fileRepoMigrations = fileRepoMigratorInternal.createMigrations({
|
|
|
178
216
|
};
|
|
179
217
|
},
|
|
180
218
|
}),
|
|
181
|
-
createMigration<FileRepoV2,
|
|
219
|
+
createMigration<FileRepoV2, FileRepoV3>({
|
|
182
220
|
version: "2.0.0",
|
|
221
|
+
up: (state) => {
|
|
222
|
+
return {
|
|
223
|
+
...state,
|
|
224
|
+
};
|
|
225
|
+
},
|
|
226
|
+
}),
|
|
227
|
+
createMigration<FileRepoV3, never>({
|
|
228
|
+
version: "3.0.0",
|
|
183
229
|
up: finalVersion,
|
|
184
230
|
}),
|
|
185
231
|
],
|
|
@@ -196,8 +242,7 @@ const savedFileDefaultValue = savedFileMigratorInternal.createDefault({
|
|
|
196
242
|
description: "",
|
|
197
243
|
name: "",
|
|
198
244
|
variables: [],
|
|
199
|
-
|
|
200
|
-
version: "4.0.0",
|
|
245
|
+
version: "5.0.0",
|
|
201
246
|
});
|
|
202
247
|
|
|
203
248
|
export const savedFileMigrator = savedFileMigratorInternal.createMigrations({
|
|
@@ -275,17 +320,123 @@ export const savedFileMigrator = savedFileMigratorInternal.createMigrations({
|
|
|
275
320
|
type: "default",
|
|
276
321
|
}),
|
|
277
322
|
}),
|
|
278
|
-
createMigration<SavedFileV4,
|
|
323
|
+
createMigration<SavedFileV4, SavedFileV5>({
|
|
279
324
|
version: "4.0.0" as SemVer,
|
|
325
|
+
up: (_state) => {
|
|
326
|
+
const state = _state as DistributiveOmitVersion<SavedFileV4>;
|
|
327
|
+
if (state.type === "simple") {
|
|
328
|
+
return {
|
|
329
|
+
name: state.name,
|
|
330
|
+
description: state.description,
|
|
331
|
+
canvas: {
|
|
332
|
+
blocks: [],
|
|
333
|
+
triggers: [],
|
|
334
|
+
},
|
|
335
|
+
variables: [],
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
const migrateBlock = (block: any, pluginsMap: Record<string, string>) => {
|
|
340
|
+
if (!block) return;
|
|
341
|
+
if (block.origin?.pluginId) {
|
|
342
|
+
block.origin.pluginId = getStrictPluginId(block.origin.pluginId);
|
|
343
|
+
// Stamp the version from the old top-level plugins map, falling back to "latest"
|
|
344
|
+
block.origin.version = pluginsMap[block.origin.pluginId] ?? "latest";
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
// Normalise the old plugins map's keys first so lookups are consistent
|
|
349
|
+
const normalizedPlugins: Record<string, string> = {};
|
|
350
|
+
if (state.plugins) {
|
|
351
|
+
for (const [key, val] of Object.entries(state.plugins)) {
|
|
352
|
+
normalizedPlugins[getStrictPluginId(key)] = val;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// Stamp origin.version on every block and trigger
|
|
357
|
+
if (state.canvas) {
|
|
358
|
+
for (const block of state.canvas.blocks ?? []) {
|
|
359
|
+
migrateBlock(block, normalizedPlugins);
|
|
360
|
+
}
|
|
361
|
+
for (const trigger of state.canvas.triggers ?? []) {
|
|
362
|
+
migrateBlock(trigger, normalizedPlugins);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// Drop the top-level plugins map — version is now per-block. Omit type.
|
|
367
|
+
const { plugins: _dropped, type: _type, ...rest } = state;
|
|
368
|
+
return rest;
|
|
369
|
+
},
|
|
370
|
+
}),
|
|
371
|
+
createMigration<SavedFileV5, never>({
|
|
372
|
+
version: "5.0.0" as SemVer,
|
|
280
373
|
up: finalVersion,
|
|
281
374
|
}),
|
|
282
375
|
],
|
|
283
376
|
});
|
|
284
377
|
|
|
378
|
+
const LEGACY_ID_MAP: Record<string, string> = {
|
|
379
|
+
construct: "@pipelab/plugin-construct",
|
|
380
|
+
filesystem: "@pipelab/plugin-filesystem",
|
|
381
|
+
system: "@pipelab/plugin-system",
|
|
382
|
+
steam: "@pipelab/plugin-steam",
|
|
383
|
+
itch: "@pipelab/plugin-itch",
|
|
384
|
+
electron: "@pipelab/plugin-electron",
|
|
385
|
+
discord: "@pipelab/plugin-discord",
|
|
386
|
+
dicord: "@pipelab/plugin-discord",
|
|
387
|
+
"@pipelab/plugin-dicord": "@pipelab/plugin-discord",
|
|
388
|
+
poki: "@pipelab/plugin-poki",
|
|
389
|
+
nvpatch: "@pipelab/plugin-nvpatch",
|
|
390
|
+
tauri: "@pipelab/plugin-tauri",
|
|
391
|
+
minify: "@pipelab/plugin-minify",
|
|
392
|
+
netlify: "@pipelab/plugin-netlify",
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
export const getStrictPluginId = (pluginId: string): string => {
|
|
396
|
+
if (!pluginId) return pluginId;
|
|
397
|
+
return LEGACY_ID_MAP[pluginId] || pluginId;
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
const normalizeBlockPluginId = (block: any): boolean => {
|
|
401
|
+
if (!block) return false;
|
|
402
|
+
let changed = false;
|
|
403
|
+
if (block.origin?.pluginId) {
|
|
404
|
+
const strictId = getStrictPluginId(block.origin.pluginId);
|
|
405
|
+
if (block.origin.pluginId !== strictId) {
|
|
406
|
+
block.origin.pluginId = strictId;
|
|
407
|
+
changed = true;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
return changed;
|
|
411
|
+
};
|
|
412
|
+
|
|
413
|
+
export const normalizePipelineConfig = (state: any): boolean => {
|
|
414
|
+
if (!state) return false;
|
|
415
|
+
let changed = false;
|
|
416
|
+
|
|
417
|
+
// Normalise plugin IDs in block and trigger origins (pluginId field only;
|
|
418
|
+
// version strings don't need normalisation)
|
|
419
|
+
if (state.canvas) {
|
|
420
|
+
if (Array.isArray(state.canvas.blocks)) {
|
|
421
|
+
for (const block of state.canvas.blocks) {
|
|
422
|
+
if (normalizeBlockPluginId(block)) changed = true;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
if (Array.isArray(state.canvas.triggers)) {
|
|
426
|
+
for (const trigger of state.canvas.triggers) {
|
|
427
|
+
if (normalizeBlockPluginId(trigger)) changed = true;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
return changed;
|
|
433
|
+
};
|
|
434
|
+
|
|
285
435
|
// --- Registry ---
|
|
286
436
|
|
|
287
437
|
export const configRegistry: Record<string, Migrator<any>> = {
|
|
288
438
|
settings: appSettingsMigrator,
|
|
289
439
|
projects: fileRepoMigrations,
|
|
290
440
|
pipeline: savedFileMigrator,
|
|
441
|
+
connections: connectionsMigrator,
|
|
291
442
|
};
|
|
@@ -18,8 +18,15 @@ export const FileRepoValidatorV2 = object({
|
|
|
18
18
|
pipelines: optional(array(SaveLocationValidator), []),
|
|
19
19
|
});
|
|
20
20
|
|
|
21
|
+
export const FileRepoValidatorV3 = object({
|
|
22
|
+
version: literal("3.0.0"),
|
|
23
|
+
projects: array(FileRepoProjectValidatorV2),
|
|
24
|
+
pipelines: optional(array(SaveLocationValidator), []),
|
|
25
|
+
});
|
|
26
|
+
|
|
21
27
|
export type FileRepoV1 = InferInput<typeof FileRepoValidatorV1>;
|
|
22
28
|
export type FileRepoV2 = InferInput<typeof FileRepoValidatorV2>;
|
|
29
|
+
export type FileRepoV3 = InferInput<typeof FileRepoValidatorV3>;
|
|
23
30
|
|
|
24
|
-
export const FileRepoValidator =
|
|
31
|
+
export const FileRepoValidator = FileRepoValidatorV3;
|
|
25
32
|
export type FileRepo = InferInput<typeof FileRepoValidator>;
|
|
@@ -1,25 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { object, string, optional, record, InferInput, literal, array } from "valibot";
|
|
3
|
-
|
|
4
|
-
export const FileRepoValidatorV1 = object({
|
|
5
|
-
version: literal("1.0.0"),
|
|
6
|
-
data: optional(record(string(), SaveLocationValidator), {}),
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
export const FileRepoProjectValidatorV2 = object({
|
|
10
|
-
id: string(),
|
|
11
|
-
name: string(),
|
|
12
|
-
description: string(),
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
export const FileRepoValidatorV2 = object({
|
|
16
|
-
version: literal("2.0.0"),
|
|
17
|
-
projects: array(FileRepoProjectValidatorV2),
|
|
18
|
-
pipelines: optional(array(SaveLocationValidator), []),
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
export type FileRepoV1 = InferInput<typeof FileRepoValidatorV1>;
|
|
22
|
-
export type FileRepoV2 = InferInput<typeof FileRepoValidatorV2>;
|
|
23
|
-
|
|
24
|
-
export const FileRepoValidator = FileRepoValidatorV2;
|
|
25
|
-
export type FileRepo = InferInput<typeof FileRepoValidator>;
|
|
1
|
+
export * from "./projects-definition";
|
package/src/config.schema.ts
CHANGED
|
@@ -8,6 +8,8 @@ import {
|
|
|
8
8
|
number,
|
|
9
9
|
array,
|
|
10
10
|
GenericSchema,
|
|
11
|
+
optional,
|
|
12
|
+
looseObject,
|
|
11
13
|
} from "valibot";
|
|
12
14
|
|
|
13
15
|
export const createVersionSchema = <T extends GenericSchema<any, any>>(schema: T) => schema;
|
|
@@ -126,15 +128,37 @@ export const AppSettingsValidatorV7 = object({
|
|
|
126
128
|
url: string(),
|
|
127
129
|
}),
|
|
128
130
|
),
|
|
129
|
-
|
|
130
|
-
|
|
131
|
+
// Metadata list of plugins the user has enabled (official + community).
|
|
132
|
+
// No binaries are stored here — versions are resolved JIT at node-add time.
|
|
133
|
+
plugins: array(
|
|
134
|
+
object({
|
|
135
|
+
name: string(),
|
|
131
136
|
enabled: boolean(),
|
|
132
|
-
|
|
133
|
-
maxAge: number(), // Maximum age of entries in days
|
|
137
|
+
description: string(),
|
|
134
138
|
}),
|
|
135
|
-
|
|
139
|
+
),
|
|
140
|
+
cacheFolder: optional(string()),
|
|
141
|
+
tempFolder: optional(string()),
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
export const ConnectionValidator = looseObject({
|
|
145
|
+
id: string(),
|
|
146
|
+
pluginName: string(),
|
|
147
|
+
name: string(),
|
|
148
|
+
createdAt: string(),
|
|
149
|
+
isDefault: boolean(),
|
|
136
150
|
});
|
|
137
151
|
|
|
152
|
+
export const ConnectionsValidatorV1 = object({
|
|
153
|
+
version: literal("1.0.0"),
|
|
154
|
+
connections: array(ConnectionValidator),
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
export type Connection = InferInput<typeof ConnectionValidator>;
|
|
158
|
+
export type ConnectionsConfigV1 = InferInput<typeof ConnectionsValidatorV1>;
|
|
159
|
+
export type ConnectionsConfig = ConnectionsConfigV1;
|
|
160
|
+
export const ConnectionsValidator = ConnectionsValidatorV1;
|
|
161
|
+
|
|
138
162
|
export type AppConfigV1 = InferInput<typeof AppSettingsValidatorV1>;
|
|
139
163
|
export type AppConfigV2 = InferInput<typeof AppSettingsValidatorV2>;
|
|
140
164
|
export type AppConfigV3 = InferInput<typeof AppSettingsValidatorV3>;
|
package/src/evaluator.ts
CHANGED
|
@@ -22,7 +22,6 @@ export const makeResolvedParams = async (
|
|
|
22
22
|
for (const [paramName, param] of Object.entries(data.params)) {
|
|
23
23
|
try {
|
|
24
24
|
const parameterCodeValue = (param.value ?? "").toString();
|
|
25
|
-
|
|
26
25
|
// Bypass QuickJS for simple static values
|
|
27
26
|
try {
|
|
28
27
|
result[paramName] = JSON.parse(parameterCodeValue);
|