@pipelab/shared 2.0.1-beta.20

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.
Files changed (54) hide show
  1. package/.turbo/turbo-build.log +41 -0
  2. package/.turbo/turbo-lint.log +136 -0
  3. package/CHANGELOG.md +167 -0
  4. package/LICENSE +110 -0
  5. package/LICENSE.md +110 -0
  6. package/README.md +3 -0
  7. package/dist/index.d.mts +3603 -0
  8. package/dist/index.d.mts.map +1 -0
  9. package/dist/index.mjs +43763 -0
  10. package/dist/index.mjs.map +1 -0
  11. package/package.json +53 -0
  12. package/src/apis.ts +191 -0
  13. package/src/build-history.ts +127 -0
  14. package/src/config/migrators.ts +308 -0
  15. package/src/config/projects-definition.ts +25 -0
  16. package/src/config/projects-types.ts +25 -0
  17. package/src/config/projects.ts +1 -0
  18. package/src/config/settings-definition.ts +21 -0
  19. package/src/config/settings.ts +21 -0
  20. package/src/config.schema.ts +149 -0
  21. package/src/database.types.ts +95 -0
  22. package/src/errors.ts +11 -0
  23. package/src/evaluator.ts +58 -0
  24. package/src/fmt.ts +5 -0
  25. package/src/graph.ts +207 -0
  26. package/src/i18n/de_DE.json +86 -0
  27. package/src/i18n/en_US.json +147 -0
  28. package/src/i18n/es_ES.json +86 -0
  29. package/src/i18n/fr_FR.json +89 -0
  30. package/src/i18n/pt_BR.json +86 -0
  31. package/src/i18n/zh_CN.json +86 -0
  32. package/src/i18n-utils.ts +10 -0
  33. package/src/index.ts +51 -0
  34. package/src/ipc.types.ts +73 -0
  35. package/src/logger.ts +20 -0
  36. package/src/migrations/model.ts +1 -0
  37. package/src/migrations/projects.ts +1 -0
  38. package/src/migrations/settings.ts +1 -0
  39. package/src/model.test.ts +214 -0
  40. package/src/model.ts +233 -0
  41. package/src/plugins/definitions.ts +472 -0
  42. package/src/plugins.ts +20 -0
  43. package/src/quickjs.ts +98 -0
  44. package/src/save-location.ts +42 -0
  45. package/src/subscription-errors.ts +87 -0
  46. package/src/supabase.ts +28 -0
  47. package/src/tests/helpers.ts +5 -0
  48. package/src/types.ts +3 -0
  49. package/src/utils.ts +3 -0
  50. package/src/validation.ts +16 -0
  51. package/src/variables.ts +27 -0
  52. package/src/wasm.d.ts +9 -0
  53. package/src/websocket.types.ts +186 -0
  54. package/tsconfig.json +13 -0
@@ -0,0 +1,25 @@
1
+ import { SaveLocationValidator } from "../save-location";
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>;
@@ -0,0 +1 @@
1
+ export * from "./projects-types";
@@ -0,0 +1,21 @@
1
+ import type {
2
+ AppConfig,
3
+ AppConfigV1,
4
+ AppConfigV2,
5
+ AppConfigV3,
6
+ AppConfigV4,
7
+ AppConfigV5,
8
+ AppConfigV6,
9
+ AppConfigV7,
10
+ } from "../config.schema";
11
+
12
+ export type {
13
+ AppConfig,
14
+ AppConfigV1,
15
+ AppConfigV2,
16
+ AppConfigV3,
17
+ AppConfigV4,
18
+ AppConfigV5,
19
+ AppConfigV6,
20
+ AppConfigV7,
21
+ };
@@ -0,0 +1,21 @@
1
+ import type {
2
+ AppConfig,
3
+ AppConfigV1,
4
+ AppConfigV2,
5
+ AppConfigV3,
6
+ AppConfigV4,
7
+ AppConfigV5,
8
+ AppConfigV6,
9
+ AppConfigV7,
10
+ } from "../config.schema";
11
+
12
+ export type {
13
+ AppConfig,
14
+ AppConfigV1,
15
+ AppConfigV2,
16
+ AppConfigV3,
17
+ AppConfigV4,
18
+ AppConfigV5,
19
+ AppConfigV6,
20
+ AppConfigV7,
21
+ };
@@ -0,0 +1,149 @@
1
+ import {
2
+ union,
3
+ literal,
4
+ InferInput,
5
+ string,
6
+ boolean,
7
+ object,
8
+ number,
9
+ array,
10
+ GenericSchema,
11
+ } from "valibot";
12
+
13
+ export const createVersionSchema = <T extends GenericSchema<any, any>>(schema: T) => schema;
14
+
15
+ export const AppSettingsValidatorV1 = object({
16
+ cacheFolder: string(),
17
+ theme: union([literal("light"), literal("dark")]),
18
+ version: literal("1.0.0"),
19
+ });
20
+
21
+ export const AppSettingsValidatorV2 = object({
22
+ cacheFolder: string(),
23
+ theme: union([literal("light"), literal("dark")]),
24
+ version: literal("2.0.0"),
25
+ });
26
+
27
+ export const AppSettingsValidatorV3 = object({
28
+ cacheFolder: string(),
29
+ theme: union([literal("light"), literal("dark")]),
30
+ version: literal("3.0.0"),
31
+ clearTemporaryFoldersOnPipelineEnd: boolean(),
32
+ });
33
+
34
+ export const AppSettingsValidatorV4 = object({
35
+ theme: union([literal("light"), literal("dark")]),
36
+ version: literal("4.0.0"),
37
+ cacheFolder: string(),
38
+ clearTemporaryFoldersOnPipelineEnd: boolean(),
39
+ locale: union([
40
+ literal("en-US"),
41
+ literal("fr-FR"),
42
+ literal("pt-BR"),
43
+ literal("zh-CN"),
44
+ literal("es-ES"),
45
+ literal("de-DE"),
46
+ ]),
47
+ });
48
+
49
+ export const AppSettingsValidatorV5 = object({
50
+ theme: union([literal("light"), literal("dark")]),
51
+ version: literal("5.0.0"),
52
+ cacheFolder: string(),
53
+ clearTemporaryFoldersOnPipelineEnd: boolean(),
54
+ locale: union([
55
+ literal("en-US"),
56
+ literal("fr-FR"),
57
+ literal("pt-BR"),
58
+ literal("zh-CN"),
59
+ literal("es-ES"),
60
+ literal("de-DE"),
61
+ ]),
62
+ tours: object({
63
+ dashboard: object({
64
+ step: number(),
65
+ completed: boolean(),
66
+ }),
67
+ editor: object({
68
+ step: number(),
69
+ completed: boolean(),
70
+ }),
71
+ }),
72
+ });
73
+
74
+ export const AppSettingsValidatorV6 = object({
75
+ theme: union([literal("light"), literal("dark")]),
76
+ version: literal("6.0.0"),
77
+ cacheFolder: string(),
78
+ clearTemporaryFoldersOnPipelineEnd: boolean(),
79
+ locale: union([
80
+ literal("en-US"),
81
+ literal("fr-FR"),
82
+ literal("pt-BR"),
83
+ literal("zh-CN"),
84
+ literal("es-ES"),
85
+ literal("de-DE"),
86
+ ]),
87
+ tours: object({
88
+ dashboard: object({
89
+ step: number(),
90
+ completed: boolean(),
91
+ }),
92
+ editor: object({
93
+ step: number(),
94
+ completed: boolean(),
95
+ }),
96
+ }),
97
+ autosave: boolean(),
98
+ });
99
+
100
+ export const AppSettingsValidatorV7 = object({
101
+ theme: union([literal("light"), literal("dark")]),
102
+ version: literal("7.0.0"),
103
+ cacheFolder: string(),
104
+ clearTemporaryFoldersOnPipelineEnd: boolean(),
105
+ locale: union([
106
+ literal("en-US"),
107
+ literal("fr-FR"),
108
+ literal("pt-BR"),
109
+ literal("zh-CN"),
110
+ literal("es-ES"),
111
+ literal("de-DE"),
112
+ ]),
113
+ tours: object({
114
+ dashboard: object({
115
+ step: number(),
116
+ completed: boolean(),
117
+ }),
118
+ editor: object({
119
+ step: number(),
120
+ completed: boolean(),
121
+ }),
122
+ }),
123
+ autosave: boolean(),
124
+ agents: array(
125
+ object({
126
+ id: string(),
127
+ name: string(),
128
+ url: string(),
129
+ }),
130
+ ),
131
+ buildHistory: object({
132
+ retentionPolicy: object({
133
+ enabled: boolean(),
134
+ maxEntries: number(), // Maximum number of entries per pipeline
135
+ maxAge: number(), // Maximum age of entries in days
136
+ }),
137
+ }),
138
+ });
139
+
140
+ export type AppConfigV1 = InferInput<typeof AppSettingsValidatorV1>;
141
+ export type AppConfigV2 = InferInput<typeof AppSettingsValidatorV2>;
142
+ export type AppConfigV3 = InferInput<typeof AppSettingsValidatorV3>;
143
+ export type AppConfigV4 = InferInput<typeof AppSettingsValidatorV4>;
144
+ export type AppConfigV5 = InferInput<typeof AppSettingsValidatorV5>;
145
+ export type AppConfigV6 = InferInput<typeof AppSettingsValidatorV6>;
146
+ export type AppConfigV7 = InferInput<typeof AppSettingsValidatorV7>;
147
+
148
+ export type AppConfig = AppConfigV7;
149
+ export const AppSettingsValidator = AppSettingsValidatorV7;
@@ -0,0 +1,95 @@
1
+ export type Json = string | number | boolean | null | { [key: string]: Json | undefined } | Json[];
2
+
3
+ export type Database = {
4
+ public: {
5
+ Tables: {
6
+ [_ in never]: never;
7
+ };
8
+ Views: {
9
+ [_ in never]: never;
10
+ };
11
+ Functions: {
12
+ [_ in never]: never;
13
+ };
14
+ Enums: {
15
+ [_ in never]: never;
16
+ };
17
+ CompositeTypes: {
18
+ [_ in never]: never;
19
+ };
20
+ };
21
+ };
22
+
23
+ type PublicSchema = Database[Extract<keyof Database, "public">];
24
+
25
+ export type Tables<
26
+ PublicTableNameOrOptions extends
27
+ | keyof (PublicSchema["Tables"] & PublicSchema["Views"])
28
+ | { schema: keyof Database },
29
+ TableName extends PublicTableNameOrOptions extends { schema: keyof Database }
30
+ ? keyof (Database[PublicTableNameOrOptions["schema"]]["Tables"] &
31
+ Database[PublicTableNameOrOptions["schema"]]["Views"])
32
+ : never = never,
33
+ > = PublicTableNameOrOptions extends { schema: keyof Database }
34
+ ? (Database[PublicTableNameOrOptions["schema"]]["Tables"] &
35
+ Database[PublicTableNameOrOptions["schema"]]["Views"])[TableName] extends {
36
+ Row: infer R;
37
+ }
38
+ ? R
39
+ : never
40
+ : PublicTableNameOrOptions extends keyof (PublicSchema["Tables"] & PublicSchema["Views"])
41
+ ? (PublicSchema["Tables"] & PublicSchema["Views"])[PublicTableNameOrOptions] extends {
42
+ Row: infer R;
43
+ }
44
+ ? R
45
+ : never
46
+ : never;
47
+
48
+ export type TablesInsert<
49
+ PublicTableNameOrOptions extends keyof PublicSchema["Tables"] | { schema: keyof Database },
50
+ TableName extends PublicTableNameOrOptions extends { schema: keyof Database }
51
+ ? keyof Database[PublicTableNameOrOptions["schema"]]["Tables"]
52
+ : never = never,
53
+ > = PublicTableNameOrOptions extends { schema: keyof Database }
54
+ ? Database[PublicTableNameOrOptions["schema"]]["Tables"][TableName] extends {
55
+ Insert: infer I;
56
+ }
57
+ ? I
58
+ : never
59
+ : PublicTableNameOrOptions extends keyof PublicSchema["Tables"]
60
+ ? PublicSchema["Tables"][PublicTableNameOrOptions] extends {
61
+ Insert: infer I;
62
+ }
63
+ ? I
64
+ : never
65
+ : never;
66
+
67
+ export type TablesUpdate<
68
+ PublicTableNameOrOptions extends keyof PublicSchema["Tables"] | { schema: keyof Database },
69
+ TableName extends PublicTableNameOrOptions extends { schema: keyof Database }
70
+ ? keyof Database[PublicTableNameOrOptions["schema"]]["Tables"]
71
+ : never = never,
72
+ > = PublicTableNameOrOptions extends { schema: keyof Database }
73
+ ? Database[PublicTableNameOrOptions["schema"]]["Tables"][TableName] extends {
74
+ Update: infer U;
75
+ }
76
+ ? U
77
+ : never
78
+ : PublicTableNameOrOptions extends keyof PublicSchema["Tables"]
79
+ ? PublicSchema["Tables"][PublicTableNameOrOptions] extends {
80
+ Update: infer U;
81
+ }
82
+ ? U
83
+ : never
84
+ : never;
85
+
86
+ export type Enums<
87
+ PublicEnumNameOrOptions extends keyof PublicSchema["Enums"] | { schema: keyof Database },
88
+ EnumName extends PublicEnumNameOrOptions extends { schema: keyof Database }
89
+ ? keyof Database[PublicEnumNameOrOptions["schema"]]["Enums"]
90
+ : never = never,
91
+ > = PublicEnumNameOrOptions extends { schema: keyof Database }
92
+ ? Database[PublicEnumNameOrOptions["schema"]]["Enums"][EnumName]
93
+ : PublicEnumNameOrOptions extends keyof PublicSchema["Enums"]
94
+ ? PublicSchema["Enums"][PublicEnumNameOrOptions]
95
+ : never;
package/src/errors.ts ADDED
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Defines standardized exit codes for the Pipelab CLI.
3
+ */
4
+ export enum CLIExitCode {
5
+ Success = 0,
6
+ UnknownError = 1,
7
+ PipelineNotFound = 2,
8
+ InvalidPipelineFile = 3,
9
+ PipelineExecutionError = 4,
10
+ InvalidArguments = 5,
11
+ }
@@ -0,0 +1,58 @@
1
+ import { BlockAction, Steps } from "./model";
2
+ import { createQuickJs, CreateQuickJSFn } from "./quickjs";
3
+ import { useLogger } from "./logger";
4
+
5
+ export const makeResolvedParams = async (
6
+ data: {
7
+ params: BlockAction["params"];
8
+ steps: Steps;
9
+ variables: Record<string, string>;
10
+ context: Record<string, unknown>;
11
+ },
12
+ onItem: (item: any) => string = (item: any) => item,
13
+ _vm?: Awaited<CreateQuickJSFn> | undefined,
14
+ ) => {
15
+ const { logger } = useLogger();
16
+ const vm = _vm ?? (await createQuickJs());
17
+
18
+ const result: Record<string, any> = {};
19
+
20
+ const ctx = "createContext" in vm ? (vm as any).createContext() : null;
21
+
22
+ for (const [paramName, param] of Object.entries(data.params)) {
23
+ try {
24
+ const parameterCodeValue = (param.value ?? "").toString();
25
+
26
+ // Bypass QuickJS for simple static values
27
+ try {
28
+ result[paramName] = JSON.parse(parameterCodeValue);
29
+ continue;
30
+ } catch (e) {
31
+ // Not a simple JSON value, proceed to QuickJS evaluation
32
+ }
33
+
34
+ const runParams = {
35
+ steps: data.steps,
36
+ params: {},
37
+ variables: data.variables,
38
+ };
39
+
40
+ const output = ctx
41
+ ? ctx.run(parameterCodeValue, runParams)
42
+ : await vm.run(parameterCodeValue, runParams);
43
+
44
+ const outputResult = onItem(output);
45
+
46
+ result[paramName] = outputResult;
47
+ } catch (e) {
48
+ logger().error("error", e);
49
+ result[paramName] = "";
50
+ }
51
+ }
52
+
53
+ if (ctx) {
54
+ ctx.dispose();
55
+ }
56
+
57
+ return result;
58
+ };
package/src/fmt.ts ADDED
@@ -0,0 +1,5 @@
1
+ export const fmt = {
2
+ param: (value: string, variant?: "primary" | "secondary" | undefined, ifEmpty: string = "") => {
3
+ return `<span class="param ${variant ? variant : ""}">${value ? value : ifEmpty}</span>`;
4
+ },
5
+ };
package/src/graph.ts ADDED
@@ -0,0 +1,207 @@
1
+ import { makeResolvedParams } from "./evaluator";
2
+ import { Steps } from "./model";
3
+ import { Variable } from "./variables";
4
+ import { RendererPluginDefinition } from "./plugins/definitions";
5
+ import { Block } from "./model";
6
+ import { Context } from "./types";
7
+ import { End } from "./apis";
8
+ import { useLogger } from "./logger";
9
+ import { variableToFormattedVariable } from "./variables";
10
+ import { createQuickJs } from "./quickjs";
11
+
12
+ const getPluginDefinition = (pluginId: string, definitions: Array<RendererPluginDefinition>) => {
13
+ const result = definitions.find((nodeDef) => {
14
+ return nodeDef.id === pluginId;
15
+ });
16
+ return result;
17
+ };
18
+
19
+ const getNodeDefinition = (
20
+ nodeId: string,
21
+ pluginId: string,
22
+ definitions: Array<RendererPluginDefinition>,
23
+ ) => {
24
+ // const getNodeDefinition = <T extends Block>(node: T extends Block ? T : never) => {
25
+ const plugin = getPluginDefinition(pluginId, definitions);
26
+ if (plugin) {
27
+ return plugin.nodes.find((pluginNode) => pluginNode.node.id === nodeId);
28
+ }
29
+ return undefined;
30
+ };
31
+
32
+ export const processGraph = async (options: {
33
+ graph: Array<Block>;
34
+ definitions: Array<RendererPluginDefinition>;
35
+ // editor user defined variables
36
+ variables: Array<Variable>;
37
+ // steps outputs
38
+ steps: Steps;
39
+ // context like loopindex
40
+ context: Context;
41
+ onExecuteItem: (
42
+ node: Block,
43
+ params: Record<string, string>,
44
+ steps: Steps,
45
+ ) => Promise<End<"condition:execute"> | End<"action:execute">>;
46
+ onNodeEnter: (node: Block) => void;
47
+ onNodeExit: (node: Block) => void;
48
+ abortSignal?: AbortSignal;
49
+ }) => {
50
+ const { logger } = useLogger();
51
+
52
+ console.log("options.graph", options.graph);
53
+
54
+ for (const node of options.graph) {
55
+ // Check if operation was aborted
56
+ if (options.abortSignal?.aborted) {
57
+ const abortError = new Error("Aborted");
58
+ abortError.name = "AbortError";
59
+ throw abortError;
60
+ }
61
+
62
+ const rawNode = node;
63
+
64
+ const pluginDefinition = getPluginDefinition(node.origin.pluginId, options.definitions);
65
+ const nodeDefinition = getNodeDefinition(
66
+ node.origin.nodeId,
67
+ node.origin.pluginId,
68
+ options.definitions,
69
+ );
70
+
71
+ /* if (rawNode.type === 'condition') {
72
+ options.onNodeEnter(rawNode)
73
+
74
+ const newParams = await makeResolvedParams({
75
+ params: rawNode.params,
76
+ variables: options.variables,
77
+ steps: options.steps,
78
+ context: options.context
79
+ })
80
+
81
+ const result = await options.onExecuteItem(node, newParams, options.steps) as End<'condition:execute'>
82
+
83
+ if ('result' in result) {
84
+ logger().error(result.result)
85
+ options.onNodeExit(rawNode)
86
+ throw new Error('Condition error')
87
+ } else {
88
+ const { value, outputs } = result
89
+ if (!options.steps[rawNode.uid]) {
90
+ options.steps[rawNode.uid] = {
91
+ outputs: {}
92
+ }
93
+ }
94
+ options.steps[rawNode.uid].outputs = outputs
95
+
96
+ if (value === true) {
97
+ await processGraph({
98
+ graph: rawNode.branchTrue,
99
+ ...options,
100
+ abortSignal: options.abortSignal
101
+ })
102
+ } else {
103
+ await processGraph({
104
+ graph: rawNode.branchFalse,
105
+ ...options,
106
+ abortSignal: options.abortSignal
107
+ })
108
+ }
109
+ }
110
+ options.onNodeExit(rawNode)
111
+ } else */ if (rawNode.type === "action") {
112
+ if (rawNode.disabled === true) {
113
+ console.warn(
114
+ `Node ${rawNode.uid} (${rawNode.origin.pluginId}::${rawNode.origin.nodeId}) is disabled`,
115
+ );
116
+ continue;
117
+ }
118
+
119
+ options.onNodeEnter(rawNode);
120
+
121
+ const vm = await createQuickJs();
122
+
123
+ const variables = await variableToFormattedVariable(vm, options.variables);
124
+ console.log("variables", variables);
125
+
126
+ const newParams = await makeResolvedParams(
127
+ {
128
+ params: rawNode.params,
129
+ variables,
130
+ steps: options.steps,
131
+ context: options.context,
132
+ },
133
+ undefined,
134
+ vm,
135
+ );
136
+
137
+ const result = (await options.onExecuteItem(
138
+ node,
139
+ newParams,
140
+ options.steps,
141
+ )) as End<"action:execute">;
142
+
143
+ if (result.type === "error") {
144
+ logger().error(result.ipcError);
145
+ options.onNodeExit(rawNode);
146
+ // Check if it's an AbortError from cancellation
147
+ if (
148
+ result.ipcError &&
149
+ typeof result.ipcError === "object" &&
150
+ (result.ipcError as Error).name === "AbortError"
151
+ ) {
152
+ throw result.ipcError;
153
+ }
154
+ throw new Error(`"${nodeDefinition.node.name}" action error: ${result.ipcError}`);
155
+ }
156
+
157
+ if (result.type === "success") {
158
+ if (!options.steps[rawNode.uid]) {
159
+ options.steps[rawNode.uid] = {
160
+ outputs: {},
161
+ };
162
+ }
163
+ options.steps[rawNode.uid].outputs = result.result.outputs;
164
+ }
165
+ options.onNodeExit(rawNode);
166
+ } else if (rawNode.type === "loop") {
167
+ options.onNodeEnter(rawNode);
168
+
169
+ // const context = {}
170
+
171
+ // const arrayToLoopOn = await evaluate(rawNode.params.value, context)
172
+
173
+ // element is the value of the element at loopindex
174
+ // let loopindex = 0
175
+ // for (const _element of arrayToLoopOn) {
176
+ // await processGraph(rawNode.children, definitions, variables, steps, {
177
+ // ...context,
178
+ // loopindex
179
+ // })
180
+
181
+ // loopindex += 1
182
+ // }
183
+
184
+ // continue after loop
185
+
186
+ // TODO: process loop
187
+ // const result = await api.execute('node:execute', {
188
+ // nodeId: rawNode.origin.nodeId,
189
+ // pluginId: rawNode.origin.pluginId,
190
+ // params: rawNode.params
191
+ // })
192
+ // console.log('result', result)
193
+ options.onNodeExit(rawNode);
194
+ } else if (rawNode.type === "comment") {
195
+ // pass
196
+ } else if (rawNode.type === "event") {
197
+ options.onNodeEnter(rawNode);
198
+ // pass
199
+ options.onNodeExit(rawNode);
200
+ } else {
201
+ logger().error("Unknown node type", rawNode.type);
202
+ }
203
+
204
+ logger().info("steps", options.steps);
205
+ }
206
+ return options;
207
+ };
@@ -0,0 +1,86 @@
1
+ {
2
+ "settings": {
3
+ "darkTheme": "Dark theme",
4
+ "language": "Language",
5
+ "languageOptions": {
6
+ "en-US": "English",
7
+ "fr-FR": "French",
8
+ "pt-BR": "Portuguese",
9
+ "zh-CN": "Chinese",
10
+ "es-ES": "Spanish",
11
+ "de-DE": "German"
12
+ },
13
+ "tabs": {
14
+ "general": "General",
15
+ "storage": "Storage",
16
+ "integrations": "Integrations",
17
+ "advanced": "Advanced",
18
+ "billing": "Billing"
19
+ },
20
+ "clearTempFolders": "Automatically clean up temporary files",
21
+ "clearTempFoldersDescription": "Wenn aktiviert, werden alle temporären Dateien, die während der Pipeline-Ausführung erstellt wurden, automatisch gelöscht, nachdem die Pipeline abgeschlossen ist. Dies hilft, Speicherplatz auf der Festplatte zu sparen, aber möglicherweise müssen Sie selbst Artefakte kopieren, um sie zu bewahren.",
22
+ "pipeline-cache-folder": "Pipeline Cache Folder:",
23
+ "enter-or-browse-for-a-folder": "Enter or browse for a folder",
24
+ "browse": "Browse",
25
+ "manage-where-the-app-stores-temporary-and-cache-files": "Manage where the app stores temporary and cache files.",
26
+ "clear-cache": "Clear cache",
27
+ "reset-to-default": "Reset to default",
28
+ "manage-subscription": "Manage Subscription",
29
+ "renewal-date": "Renewal Date",
30
+ "start-date": "Start Date:",
31
+ "cache-cleared-successfully": "Cache cleared successfully",
32
+ "failed-to-clear-cache-error-message": "Failed to clear cache: {0}",
33
+ "failed-to-reset-cache-folder-error-message": "Failed to reset cache folder: {0}",
34
+ "select-cache-folder": "Select Cache Folder"
35
+ },
36
+ "headers": {
37
+ "dashboard": "Dashboard",
38
+ "scenarios": "Scenarios",
39
+ "editor": "Editor",
40
+ "billing": "Billing",
41
+ "team": "Team"
42
+ },
43
+ "base": {
44
+ "close": "Schließen",
45
+ "save": "Speichern",
46
+ "run": "Ausführen",
47
+ "cancel": "Abbrechen",
48
+ "end": "Ende",
49
+ "delete": "Löschen",
50
+ "logs": "Protokolle",
51
+ "ok": "OK",
52
+ "add": "Hinzufügen"
53
+ },
54
+ "editor": {
55
+ "invalid-file-content": "Invalid file content",
56
+ "welcome-back": "Welcome back!",
57
+ "please-log-in-to-run-a-scenario": "Please log in to run a scenario",
58
+ "execution-done": "Execution done",
59
+ "your-project-has-been-executed-successfully": "Your project has been executed successfully",
60
+ "execution-failed": "Execution failed",
61
+ "project-has-encountered-an-error": "Project has encountered an error:",
62
+ "project-saved": "Project saved",
63
+ "your-project-has-be-saved-successfully": "Your project has be saved successfully"
64
+ },
65
+ "home": {
66
+ "invalid-preset": "Invalid preset",
67
+ "store-project-on-the-cloud": "Store project on the cloud",
68
+ "cloud": "Cloud",
69
+ "store-project-locally": "Store project locally",
70
+ "local": "Local",
71
+ "invalid-number-of-paths-selected": "Invalid number of paths selected",
72
+ "pipelab-project": "Pipelab Project",
73
+ "choose-a-new-path": "Choose a new path",
74
+ "invalid-file-type": "Invalid file type",
75
+ "create-project": "Create project",
76
+ "duplicate-project": "Duplicate project",
77
+ "project-name": "Project Name",
78
+ "new-project": "New Project",
79
+ "open": "Open",
80
+ "your-projects": "Your projects",
81
+ "no-projects-yet": "No projects yet"
82
+ },
83
+ "scenarios": {
84
+ "scenarios": "Scenarios"
85
+ }
86
+ }