windmill-components 1.542.4 → 1.550.0

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 (189) hide show
  1. package/package/common.d.ts +4 -1
  2. package/package/components/AIAgentLogViewer.svelte +1 -1
  3. package/package/components/ArgEnum.svelte +14 -5
  4. package/package/components/ArgInput.svelte +23 -15
  5. package/package/components/ArgInput.svelte.d.ts +1 -1
  6. package/package/components/ChannelSelector.svelte +92 -18
  7. package/package/components/ChannelSelector.svelte.d.ts +2 -0
  8. package/package/components/ConnectionSection.svelte +12 -1
  9. package/package/components/Dev.svelte +18 -5
  10. package/package/components/Dev.svelte.d.ts +23 -1
  11. package/package/components/DisplayResult.svelte +36 -23
  12. package/package/components/DropdownV2.svelte +8 -2
  13. package/package/components/DropdownV2.svelte.d.ts +1 -0
  14. package/package/components/DynamicInput.svelte +10 -10
  15. package/package/components/EditableSchemaForm.svelte +21 -7
  16. package/package/components/EditorSettings.svelte +11 -9
  17. package/package/components/ErrorOrRecoveryHandler.svelte +14 -20
  18. package/package/components/FlowHistoryJobPicker.svelte +3 -0
  19. package/package/components/FlowHistoryJobPicker.svelte.d.ts +1 -0
  20. package/package/components/FlowJobResult.svelte +5 -5
  21. package/package/components/FlowLogRow.svelte +2 -2
  22. package/package/components/FlowLogViewer.svelte +228 -57
  23. package/package/components/FlowLogViewer.svelte.d.ts +16 -5
  24. package/package/components/FlowLogViewerWrapper.svelte +56 -3
  25. package/package/components/FlowLogViewerWrapper.svelte.d.ts +4 -3
  26. package/package/components/FlowLoopIterationPreview.svelte +4 -4
  27. package/package/components/FlowMetadata.svelte +3 -4
  28. package/package/components/FlowMetadata.svelte.d.ts +4 -18
  29. package/package/components/FlowPreviewContent.svelte +9 -3
  30. package/package/components/FlowPreviewContent.svelte.d.ts +1 -1
  31. package/package/components/FlowStatusViewer.svelte +62 -59
  32. package/package/components/FlowStatusViewer.svelte.d.ts +2 -2
  33. package/package/components/FlowStatusViewerInner.svelte +186 -94
  34. package/package/components/FlowStatusViewerInner.svelte.d.ts +10 -3
  35. package/package/components/FlowTimeline.svelte +110 -131
  36. package/package/components/FlowTimeline.svelte.d.ts +13 -4
  37. package/package/components/FlowTimelineBar.svelte +227 -0
  38. package/package/components/FlowTimelineBar.svelte.d.ts +24 -0
  39. package/package/components/InputTransformForm.svelte +119 -3
  40. package/package/components/InputTransformForm.svelte.d.ts +3 -0
  41. package/package/components/InputTransformSchemaForm.svelte +5 -1
  42. package/package/components/InputTransformSchemaForm.svelte.d.ts +2 -0
  43. package/package/components/InstanceSetting.svelte +17 -42
  44. package/package/components/InstanceSettings.svelte +12 -21
  45. package/package/components/JobArgs.svelte +15 -16
  46. package/package/components/JobArgs.svelte.d.ts +4 -18
  47. package/package/components/JobLoader.svelte +23 -42
  48. package/package/components/JobLoader.svelte.d.ts +2 -0
  49. package/package/components/JobStatus.svelte +1 -1
  50. package/package/components/JobStatus.svelte.d.ts +4 -18
  51. package/package/components/ModulePreviewResultViewer.svelte +1 -7
  52. package/package/components/NextcloudSetting.svelte +6 -1
  53. package/package/components/Password.svelte +7 -11
  54. package/package/components/Password.svelte.d.ts +5 -20
  55. package/package/components/PasswordArgInput.svelte +35 -15
  56. package/package/components/PasswordArgInput.svelte.d.ts +4 -18
  57. package/package/components/QueuePosition.svelte +6 -2
  58. package/package/components/RunForm.svelte +5 -14
  59. package/package/components/S3ArrayHelperButton.svelte +12 -0
  60. package/package/components/S3ArrayHelperButton.svelte.d.ts +8 -0
  61. package/package/components/ScriptEditor.svelte +5 -6
  62. package/package/components/StringTypeNarrowing.svelte +39 -24
  63. package/package/components/StringTypeNarrowing.svelte.d.ts +1 -1
  64. package/package/components/TeamSelector.svelte +83 -37
  65. package/package/components/TeamSelector.svelte.d.ts +0 -1
  66. package/package/components/apps/components/buttons/AppButton.svelte +11 -1
  67. package/package/components/apps/components/display/table/AppAggridInfiniteTable.svelte +13 -4
  68. package/package/components/apps/components/display/table/SyncColumnDefs.svelte +2 -2
  69. package/package/components/apps/components/display/table/utils.js +1 -1
  70. package/package/components/apps/components/helpers/RefreshButton.svelte +5 -1
  71. package/package/components/apps/components/helpers/RunnableComponent.svelte +0 -2
  72. package/package/components/apps/components/helpers/RunnableWrapper.svelte.d.ts +1 -0
  73. package/package/components/apps/components/layout/AppTabs.svelte +116 -71
  74. package/package/components/apps/components/layout/AppTabs.svelte.d.ts +1 -0
  75. package/package/components/apps/editor/component/ComponentInner.svelte +1 -0
  76. package/package/components/apps/editor/component/components.d.ts +16 -1
  77. package/package/components/apps/editor/component/components.js +22 -2
  78. package/package/components/apps/editor/settingsPanel/ComponentPanel.svelte +2 -0
  79. package/package/components/apps/editor/settingsPanel/GridTab.svelte +19 -1
  80. package/package/components/apps/editor/settingsPanel/GridTab.svelte.d.ts +3 -1
  81. package/package/components/apps/editor/settingsPanel/GridTabHidden.svelte +52 -0
  82. package/package/components/apps/editor/settingsPanel/GridTabHidden.svelte.d.ts +9 -0
  83. package/package/components/auditLogs/AuditLogsFilters.svelte +6 -0
  84. package/package/components/auditLogs/AuditLogsTable.svelte +17 -7
  85. package/package/components/auditLogs/AuditLogsTable.svelte.d.ts +1 -0
  86. package/package/components/common/CloseButton.svelte +2 -2
  87. package/package/components/common/CloseButton.svelte.d.ts +1 -0
  88. package/package/components/common/layout/List.svelte +3 -7
  89. package/package/components/common/layout/List.svelte.d.ts +7 -29
  90. package/package/components/common/popup/PopupV2.svelte +8 -25
  91. package/package/components/common/popup/PopupV2.svelte.d.ts +4 -2
  92. package/package/components/common/table/ScriptRow.svelte +22 -2
  93. package/package/components/copilot/FlowCopilotInputsModal.svelte +26 -23
  94. package/package/components/copilot/chat/AIChatManager.svelte.js +3 -2
  95. package/package/components/copilot/chat/ProviderModelSelector.svelte +1 -1
  96. package/package/components/copilot/chat/flow/FlowAIChat.svelte +4 -2
  97. package/package/components/copilot/chat/script/core.d.ts +4 -4
  98. package/package/components/copilot/chat/script/core.js +93 -34
  99. package/package/components/copilot/lib.d.ts +1 -0
  100. package/package/components/copilot/lib.js +6 -3
  101. package/package/components/custom_ui.d.ts +2 -0
  102. package/package/components/flows/FlowProgressBar.svelte +16 -16
  103. package/package/components/flows/FlowProgressBar.svelte.d.ts +7 -22
  104. package/package/components/flows/content/FlowInputsQuick.svelte +3 -2
  105. package/package/components/flows/content/FlowInputsQuick.svelte.d.ts +1 -0
  106. package/package/components/flows/content/FlowModuleComponent.svelte +24 -1
  107. package/package/components/flows/flowInfers.js +34 -8
  108. package/package/components/flows/flowStore.d.ts +4 -1
  109. package/package/components/flows/map/FlowJobsMenu.svelte +3 -3
  110. package/package/components/flows/map/FlowJobsMenu.svelte.d.ts +1 -1
  111. package/package/components/flows/map/InsertModuleButton.svelte +4 -14
  112. package/package/components/flows/map/InsertModuleButton.svelte.d.ts +0 -1
  113. package/package/components/flows/map/InsertModuleInner.svelte +17 -20
  114. package/package/components/flows/map/MapItem.svelte +1 -1
  115. package/package/components/flows/pickers/PickHubScriptQuick.svelte +38 -52
  116. package/package/components/flows/pickers/PickHubScriptQuick.svelte.d.ts +1 -0
  117. package/package/components/flows/pickers/WorkspaceScriptPickerQuick.svelte +27 -15
  118. package/package/components/flows/pickers/WorkspaceScriptPickerQuick.svelte.d.ts +1 -0
  119. package/package/components/flows/propPicker/OutputPicker.svelte +2 -0
  120. package/package/components/git_sync/DetectionFlow.svelte +33 -44
  121. package/package/components/git_sync/DetectionFlow.svelte.d.ts +1 -0
  122. package/package/components/git_sync/GitSyncContext.svelte.d.ts +22 -0
  123. package/package/components/git_sync/GitSyncContext.svelte.js +145 -5
  124. package/package/components/git_sync/GitSyncModeDisplay.svelte +14 -0
  125. package/package/components/git_sync/GitSyncModeDisplay.svelte.d.ts +9 -0
  126. package/package/components/git_sync/GitSyncRepositoryCard.svelte +365 -253
  127. package/package/components/git_sync/GitSyncRepositoryCard.svelte.d.ts +10 -1
  128. package/package/components/git_sync/GitSyncSection.svelte +134 -14
  129. package/package/components/git_sync/PullWorkspaceModal.svelte +24 -32
  130. package/package/components/git_sync/PushWorkspaceModal.svelte +24 -32
  131. package/package/components/graph/model.d.ts +5 -5
  132. package/package/components/graph/renderers/edges/EmptyEdge.svelte +3 -10
  133. package/package/components/graph/renderers/edges/EmptyEdge.svelte.d.ts +4 -18
  134. package/package/components/graph/renderers/nodes/AIToolNode.svelte +2 -2
  135. package/package/components/graph/renderers/nodes/NewAIToolNode.svelte +5 -10
  136. package/package/components/home/ItemsList.svelte +1 -1
  137. package/package/components/jobs/JobProgressBar.svelte +27 -21
  138. package/package/components/jobs/JobProgressBar.svelte.d.ts +9 -24
  139. package/package/components/meltComponents/MenuSingleItem.svelte +3 -8
  140. package/package/components/meltComponents/MenuSingleItem.svelte.d.ts +0 -3
  141. package/package/components/meltComponents/Popover.svelte +3 -2
  142. package/package/components/meltComponents/Popover.svelte.d.ts +1 -0
  143. package/package/components/meltComponents/Tooltip.svelte +1 -1
  144. package/package/components/progressBar/ProgressBar.svelte +39 -53
  145. package/package/components/progressBar/ProgressBar.svelte.d.ts +11 -26
  146. package/package/components/runs/JobsLoader.svelte +1 -1
  147. package/package/components/runs/NoWorkerWithTagWarning.svelte +3 -3
  148. package/package/components/runs/NoWorkerWithTagWarning.svelte.d.ts +1 -1
  149. package/package/components/schema/AddPropertyV2.svelte +7 -4
  150. package/package/components/schema/PropertyEditor.svelte.d.ts +1 -1
  151. package/package/components/select/MultiSelect.svelte +2 -2
  152. package/package/components/select/MultiSelect.svelte.d.ts +1 -0
  153. package/package/components/settings/WorkspaceUserSettings.svelte +92 -1
  154. package/package/components/sidebar/MenuLink.svelte +2 -1
  155. package/package/components/sidebar/MenuLink.svelte.d.ts +1 -0
  156. package/package/components/sidebar/SidebarContent.svelte +27 -27
  157. package/package/components/table/Cell.svelte +7 -14
  158. package/package/components/table/Cell.svelte.d.ts +13 -35
  159. package/package/components/triggers/AddTriggersButton.svelte +1 -0
  160. package/package/components/triggers/gcp/GcpTriggerEditorConfigSection.svelte +1 -1
  161. package/package/components/triggers/gcp/GcpTriggerEditorConfigSection.svelte.d.ts +2 -1
  162. package/package/components/triggers/gcp/GcpTriggerEditorInner.svelte +28 -5
  163. package/package/components/triggers/gcp/utils.js +1 -0
  164. package/package/components/triggers/schedules/ScheduleEditorInner.svelte +1 -0
  165. package/package/components/triggers/webhook/WebhooksConfigSection.svelte +143 -63
  166. package/package/components/triggers/websocket/WebsocketTriggerEditorInner.svelte +22 -0
  167. package/package/components/triggers/websocket/utils.js +1 -0
  168. package/package/components/workspaceSettings/AISettings.svelte +8 -2
  169. package/package/components/workspaceSettings/AISettings.svelte.d.ts +2 -1
  170. package/package/components/workspaceSettings/ModelTokenLimits.svelte +165 -0
  171. package/package/components/workspaceSettings/ModelTokenLimits.svelte.d.ts +8 -0
  172. package/package/components/workspaceSettings/StorageSettings.svelte +123 -51
  173. package/package/gen/core/OpenAPI.js +1 -1
  174. package/package/gen/schemas.gen.d.ts +141 -16
  175. package/package/gen/schemas.gen.js +144 -16
  176. package/package/gen/services.gen.d.ts +62 -42
  177. package/package/gen/services.gen.js +131 -82
  178. package/package/gen/types.gen.d.ts +218 -144
  179. package/package/hubPaths.json +2 -1
  180. package/package/services/JobManager.js +10 -7
  181. package/package/stores.d.ts +1 -0
  182. package/package/stores.js +6 -3
  183. package/package/timelineCompute.svelte.d.ts +21 -0
  184. package/package/timelineCompute.svelte.js +113 -0
  185. package/package/utils.d.ts +15 -8
  186. package/package/utils.js +62 -12
  187. package/package/workspace_settings.d.ts +13 -8
  188. package/package/workspace_settings.js +46 -11
  189. package/package.json +2 -2
@@ -50,6 +50,7 @@ export declare const copilotInfo: import("svelte/store").Writable<{
50
50
  defaultModel?: AIProviderModel;
51
51
  aiModels: AIProviderModel[];
52
52
  customPrompts?: Record<string, string>;
53
+ maxTokensPerModel?: Record<string, number>;
53
54
  }>;
54
55
  export declare function loadCopilot(workspace: string): Promise<void>;
55
56
  export declare function setCopilotInfo(aiConfig: AIConfig): void;
package/package/stores.js CHANGED
@@ -62,7 +62,8 @@ export const copilotInfo = writable({
62
62
  codeCompletionModel: undefined,
63
63
  defaultModel: undefined,
64
64
  aiModels: [],
65
- customPrompts: {}
65
+ customPrompts: {},
66
+ maxTokensPerModel: {}
66
67
  });
67
68
  export async function loadCopilot(workspace) {
68
69
  workspaceAIClients.init(workspace);
@@ -90,7 +91,8 @@ export function setCopilotInfo(aiConfig) {
90
91
  codeCompletionModel: aiConfig.code_completion_model,
91
92
  defaultModel: aiConfig.default_model,
92
93
  aiModels: aiModels,
93
- customPrompts: aiConfig.custom_prompts ?? {}
94
+ customPrompts: aiConfig.custom_prompts ?? {},
95
+ maxTokensPerModel: aiConfig.max_tokens_per_model ?? {}
94
96
  });
95
97
  }
96
98
  else {
@@ -100,7 +102,8 @@ export function setCopilotInfo(aiConfig) {
100
102
  codeCompletionModel: undefined,
101
103
  defaultModel: undefined,
102
104
  aiModels: [],
103
- customPrompts: {}
105
+ customPrompts: {},
106
+ maxTokensPerModel: {}
104
107
  });
105
108
  }
106
109
  }
@@ -0,0 +1,21 @@
1
+ import type { DurationStatus } from './components/graph/model';
2
+ export type TimelineItems = Record<string, Array<{
3
+ created_at?: number;
4
+ started_at?: number;
5
+ duration_ms?: number;
6
+ id: string;
7
+ }>>;
8
+ export declare class TimelineCompute {
9
+ #private;
10
+ min: number | undefined;
11
+ max: number | undefined;
12
+ total: number | undefined;
13
+ items: TimelineItems | undefined;
14
+ now: number;
15
+ constructor(flowModules: string[], durationStatuses: Record<string, DurationStatus>, flowDone?: boolean);
16
+ reset(): void;
17
+ updateInputs(flowModules: string[], durationStatuses: Record<string, DurationStatus>, flowDone?: boolean): void;
18
+ setFlowDone(flowDone: boolean): void;
19
+ destroy(): void;
20
+ private computeItems;
21
+ }
@@ -0,0 +1,113 @@
1
+ import { debounce, readFieldsRecursively } from './utils';
2
+ import { untrack } from 'svelte';
3
+ import { getDbClockNow } from './forLater';
4
+ export class TimelineCompute {
5
+ #flowModules = $state([]);
6
+ #durationStatuses = $state({});
7
+ #flowDone = $state(false);
8
+ #interval = undefined;
9
+ #debounceInstance;
10
+ min = $state(undefined);
11
+ max = $state(undefined);
12
+ total = $state(undefined);
13
+ items = $state(undefined);
14
+ now = $state(getDbClockNow().getTime());
15
+ constructor(flowModules, durationStatuses, flowDone = false) {
16
+ this.#flowModules = flowModules;
17
+ this.#durationStatuses = durationStatuses;
18
+ this.#flowDone = flowDone;
19
+ this.#debounceInstance = debounce(() => this.computeItems(this.#durationStatuses), 30);
20
+ // Set up reactivity using $effect
21
+ $effect(() => {
22
+ readFieldsRecursively(this.#durationStatuses);
23
+ this.#flowDone != undefined &&
24
+ this.#durationStatuses &&
25
+ untrack(() => this.#debounceInstance.debounced());
26
+ });
27
+ // Set up interval for updating now and total for running jobs
28
+ this.#interval = setInterval(() => {
29
+ if (!this.max) {
30
+ this.now = getDbClockNow().getTime();
31
+ }
32
+ if (this.min && (!this.max || this.total == undefined)) {
33
+ this.total = this.max ? this.max - this.min : Math.max(this.now - this.min, 2000);
34
+ }
35
+ }, 30);
36
+ }
37
+ reset() {
38
+ this.min = undefined;
39
+ this.max = undefined;
40
+ this.#flowDone = false;
41
+ this.items = this.computeItems(this.#durationStatuses);
42
+ }
43
+ updateInputs(flowModules, durationStatuses, flowDone = false) {
44
+ this.#flowModules = flowModules;
45
+ this.#durationStatuses = durationStatuses;
46
+ this.#flowDone = flowDone;
47
+ }
48
+ setFlowDone(flowDone) {
49
+ this.#flowDone = flowDone;
50
+ }
51
+ destroy() {
52
+ if (this.#interval) {
53
+ clearInterval(this.#interval);
54
+ }
55
+ this.#debounceInstance.clearDebounce();
56
+ }
57
+ computeItems(durationStatuses) {
58
+ let nmin = undefined;
59
+ let nmax = undefined;
60
+ let isStillRunning = false;
61
+ let cnt = 0;
62
+ let nitems = {};
63
+ Object.entries(durationStatuses).forEach(([k, o]) => {
64
+ Object.values(o.byJob).forEach((v) => {
65
+ cnt++;
66
+ if (v.started_at) {
67
+ if (!nmin) {
68
+ nmin = v.started_at;
69
+ }
70
+ else {
71
+ nmin = Math.min(nmin, v.started_at);
72
+ }
73
+ }
74
+ if (!this.#flowDone && v.duration_ms == undefined) {
75
+ isStillRunning = true;
76
+ }
77
+ if (!isStillRunning) {
78
+ if (v.started_at && v.duration_ms != undefined) {
79
+ let lmax = v.started_at + v.duration_ms;
80
+ if (!nmax) {
81
+ nmax = lmax;
82
+ }
83
+ else {
84
+ nmax = Math.max(nmax, lmax);
85
+ }
86
+ }
87
+ }
88
+ });
89
+ let arr = Object.entries(o.byJob).map(([k, v]) => ({ ...v, id: k }));
90
+ arr.sort((x, y) => {
91
+ if (!x.started_at) {
92
+ return -1;
93
+ }
94
+ else if (!y.started_at) {
95
+ return 1;
96
+ }
97
+ else {
98
+ return x.started_at - y.started_at;
99
+ }
100
+ });
101
+ nitems[k] = arr;
102
+ });
103
+ this.items = nitems;
104
+ this.min = nmin;
105
+ this.max =
106
+ isStillRunning || (cnt < this.#flowModules.length && !this.#flowDone) ? undefined : nmax;
107
+ if (this.max && this.min) {
108
+ this.total = this.max - this.min;
109
+ this.total = Math.max(this.total, 2000);
110
+ }
111
+ return nitems;
112
+ }
113
+ }
@@ -1,6 +1,6 @@
1
1
  import { type UserExt } from './stores';
2
2
  import { sendUserToast } from './toast';
3
- import type { Job, Script, ScriptLang } from './gen';
3
+ import type { Job, RunnableKind, Script, ScriptLang } from './gen';
4
4
  import type { EnumType, SchemaProperty } from './common';
5
5
  import type { Schema } from './common';
6
6
  export { sendUserToast };
@@ -45,6 +45,7 @@ export declare function displaySize(sizeInBytes: number | undefined): string | u
45
45
  export declare function msToSec(ms: number | undefined, maximumFractionDigits?: number): string;
46
46
  export declare function removeTriggerKindIfUnused(length: number, triggerKind: TriggerKind, usedTriggerKinds: string[]): string[];
47
47
  export declare function msToReadableTime(ms: number | undefined, maximumFractionDigits?: number): string;
48
+ export declare function msToReadableTimeShort(ms: number | undefined, maximumFractionDigits?: number): string;
48
49
  export declare function getToday(): Date;
49
50
  export declare function truncateHash(hash: string): string;
50
51
  export declare function sleep(ms: number): Promise<void>;
@@ -55,6 +56,7 @@ interface ClickOutsideOptions {
55
56
  exclude?: (() => Promise<HTMLElement[]>) | HTMLElement[] | undefined;
56
57
  stopPropagation?: boolean;
57
58
  customEventName?: string;
59
+ eventToListenName?: 'click' | 'pointerdown';
58
60
  onClickOutside?: (event: MouseEvent) => void;
59
61
  }
60
62
  export declare function clickOutside(node: Node, options?: ClickOutsideOptions | boolean): {
@@ -100,13 +102,13 @@ export declare function isString(value: any): value is string | String;
100
102
  export type InputCat = 'string' | 'email' | 'number' | 'boolean' | 'list' | 'resource-object' | 'enum' | 'date' | 'base64' | 'resource-string' | 'object' | 'sql' | 'yaml' | 'currency' | 'oneOf' | 'dynamic' | 'json-schema' | 'ai-provider';
101
103
  export declare namespace DynamicInput {
102
104
  type HelperScript = {
103
- type: 'inline';
104
- path?: string;
105
- lang: Script['language'];
106
- code: string;
105
+ source: 'deployed';
106
+ path: string;
107
+ runnable_kind: RunnableKind;
107
108
  } | {
108
- type: 'hash';
109
- hash: string;
109
+ source: 'inline';
110
+ code: string;
111
+ lang: ScriptLang;
110
112
  };
111
113
  const generatePythonFnTemplate: (functionName: string) => string;
112
114
  const generateJsFnTemplate: (functionName: string) => string;
@@ -153,7 +155,7 @@ export declare function tryEvery({ tryCode, timeoutCode, interval, timeout }: {
153
155
  interval: number;
154
156
  timeout: number;
155
157
  }): Promise<void>;
156
- export declare function roughSizeOfObject(object: object | string): number;
158
+ export declare function roughSizeOfObject(object: object | string | any): number;
157
159
  export type Value = {
158
160
  language?: Script['language'];
159
161
  content?: string;
@@ -230,3 +232,8 @@ export declare function isS3Uri(uri: string): uri is S3Uri;
230
232
  export declare function uniqueBy<T>(array: T[], key: (t: T) => any): T[];
231
233
  export declare function pruneNullishArray<T>(array: (T | null | undefined)[]): T[];
232
234
  export declare function assert(msg: string, condition: boolean, value?: any): void;
235
+ export declare function createCache<Keys extends Record<string, any>, T, InitialKeys extends Keys = Keys>(compute: (keys: Keys) => T, params?: {
236
+ maxSize?: number;
237
+ initial?: InitialKeys;
238
+ invalidateMs?: number;
239
+ }): (keys: Keys) => T;
package/package/utils.js CHANGED
@@ -220,6 +220,26 @@ export function msToReadableTime(ms, maximumFractionDigits) {
220
220
  return `${msToSec(ms, maximumFractionDigits)}s`;
221
221
  }
222
222
  }
223
+ export function msToReadableTimeShort(ms, maximumFractionDigits) {
224
+ if (ms === undefined)
225
+ return '?';
226
+ const seconds = Math.floor(ms / 1000);
227
+ const minutes = Math.floor(seconds / 60);
228
+ const hours = Math.floor(minutes / 60);
229
+ const days = Math.floor(hours / 24);
230
+ if (days > 0) {
231
+ return `${days}d`;
232
+ }
233
+ else if (hours > 0) {
234
+ return `${hours}h`;
235
+ }
236
+ else if (minutes > 0) {
237
+ return `${minutes}m`;
238
+ }
239
+ else {
240
+ return `${msToSec(ms, maximumFractionDigits)}s`;
241
+ }
242
+ }
223
243
  export function getToday() {
224
244
  var today = new Date();
225
245
  return today;
@@ -286,13 +306,14 @@ export function clickOutside(node, options) {
286
306
  }
287
307
  };
288
308
  const capture = typeof options === 'boolean' ? options : (options?.capture ?? true);
289
- document.addEventListener('click', handleClick, capture ?? true);
309
+ const eventToListenName = (typeof options === 'object' && options.eventToListenName) || 'click';
310
+ document.addEventListener(eventToListenName, handleClick, capture ?? true);
290
311
  return {
291
312
  update(newOptions) {
292
313
  options = newOptions;
293
314
  },
294
315
  destroy() {
295
- document.removeEventListener('click', handleClick, capture ?? true);
316
+ document.removeEventListener(eventToListenName, handleClick, capture ?? true);
296
317
  }
297
318
  };
298
319
  }
@@ -890,14 +911,14 @@ export async function tryEvery({ tryCode, timeoutCode, interval, timeout }) {
890
911
  }
891
912
  }
892
913
  export function roughSizeOfObject(object) {
893
- if (typeof object == 'string') {
914
+ if (typeof object === 'string') {
894
915
  return object.length * 2;
895
916
  }
896
- var objectList = [];
897
- var stack = [object];
898
- var bytes = 0;
917
+ const visited = new Set();
918
+ const stack = [object];
919
+ let bytes = 0;
899
920
  while (stack.length) {
900
- let value = stack.pop();
921
+ const value = stack.pop();
901
922
  if (typeof value === 'boolean') {
902
923
  bytes += 4;
903
924
  }
@@ -907,11 +928,11 @@ export function roughSizeOfObject(object) {
907
928
  else if (typeof value === 'number') {
908
929
  bytes += 8;
909
930
  }
910
- else if (typeof value === 'object' && objectList.indexOf(value) === -1) {
911
- objectList.push(value);
912
- for (var i in value) {
913
- bytes += 2 * i.length;
914
- stack.push(value[i]);
931
+ else if (typeof value === 'object' && value !== null && !visited.has(value)) {
932
+ visited.add(value);
933
+ for (const key in value) {
934
+ bytes += 2 * key.length;
935
+ stack.push(value[key]);
915
936
  }
916
937
  }
917
938
  }
@@ -1307,3 +1328,32 @@ export function assert(msg, condition, value) {
1307
1328
  console.error(m);
1308
1329
  }
1309
1330
  }
1331
+ export function createCache(compute, params) {
1332
+ let cache = new Map();
1333
+ const maxSize = params?.maxSize ?? 15;
1334
+ if (params?.initial) {
1335
+ let key = JSON.stringify(params.initial, Object.keys(params.initial).sort());
1336
+ let value = compute(params.initial);
1337
+ cache.set(key, { value, timestamp: Date.now() });
1338
+ }
1339
+ return (keys) => {
1340
+ if (typeof params?.invalidateMs === 'number') {
1341
+ for (const [key, entry] of cache.entries()) {
1342
+ if (Date.now() - entry.timestamp > params.invalidateMs) {
1343
+ cache.delete(key);
1344
+ }
1345
+ }
1346
+ }
1347
+ let key = JSON.stringify(keys, Object.keys(keys).sort());
1348
+ if (!cache.get(key)) {
1349
+ let value = compute(keys);
1350
+ cache.set(key, { value, timestamp: Date.now() });
1351
+ if (cache.size > maxSize) {
1352
+ // remove the oldest entry (first inserted)
1353
+ const oldestKey = cache.keys().next().value;
1354
+ cache.delete(oldestKey);
1355
+ }
1356
+ }
1357
+ return cache.get(key).value;
1358
+ };
1359
+ }
@@ -1,15 +1,20 @@
1
1
  import type { GetSettingsResponse, LargeFileStorage } from './gen';
2
- type s3type = 's3' | 'azure_blob' | 's3_aws_oidc' | 'azure_workload_identity' | 'gcloud_storage';
3
- type s3ResourceSettingsItem = {
4
- resourceType: s3type;
2
+ type S3type = 's3' | 'azure_blob' | 's3_aws_oidc' | 'azure_workload_identity' | 'gcloud_storage';
3
+ export type S3ResourceSettingsItem = {
4
+ resourceType: S3type;
5
5
  resourcePath: string | undefined;
6
6
  publicResource: boolean | undefined;
7
+ advancedPermissions?: {
8
+ pattern: string;
9
+ allow: ('read' | 'write' | 'delete' | 'list')[];
10
+ }[];
7
11
  };
8
- export type S3ResourceSettings = s3ResourceSettingsItem & {
9
- secondaryStorage: [string, s3ResourceSettingsItem][] | undefined;
12
+ export type S3ResourceSettings = S3ResourceSettingsItem & {
13
+ secondaryStorage: [string, S3ResourceSettingsItem][] | undefined;
10
14
  };
11
- export declare function convertBackendSettingsToFrontendSettings(large_file_storage: GetSettingsResponse['large_file_storage']): S3ResourceSettings;
12
- export declare function convertBackendSettingsToFrontendSettingsItem(large_file_storage: GetSettingsResponse['large_file_storage']): s3ResourceSettingsItem;
15
+ export declare function convertBackendSettingsToFrontendSettings(large_file_storage: GetSettingsResponse['large_file_storage'], isEnterprise: boolean): S3ResourceSettings;
16
+ export declare function convertBackendSettingsToFrontendSettingsItem(large_file_storage: GetSettingsResponse['large_file_storage'], isEnterprise: boolean): S3ResourceSettingsItem;
13
17
  export declare function convertFrontendToBackendSetting(s3ResourceSettings: S3ResourceSettings): LargeFileStorage | undefined;
14
- export declare function convertFrontendToBackendettingsItem(s3ResourceSettings: s3ResourceSettingsItem): LargeFileStorage | undefined;
18
+ export declare function convertFrontendToBackendettingsItem(s3ResourceSettings: S3ResourceSettingsItem): LargeFileStorage | undefined;
19
+ export declare function defaultS3AdvancedPermissions(isEnterprise: boolean): S3ResourceSettingsItem['advancedPermissions'];
15
20
  export {};
@@ -1,50 +1,65 @@
1
1
  import { emptyString } from './utils';
2
- export function convertBackendSettingsToFrontendSettings(large_file_storage) {
3
- let settings = convertBackendSettingsToFrontendSettingsItem(large_file_storage);
4
- settings.secondaryStorage = Object.entries(large_file_storage?.secondary_storage ?? {}).map(([key, value]) => [key, convertBackendSettingsToFrontendSettingsItem(value)]);
2
+ export function convertBackendSettingsToFrontendSettings(large_file_storage, isEnterprise) {
3
+ let settings = convertBackendSettingsToFrontendSettingsItem(large_file_storage, isEnterprise);
4
+ settings.secondaryStorage = Object.entries(large_file_storage?.secondary_storage ?? {}).map(([key, value]) => [key, convertBackendSettingsToFrontendSettingsItem(value, isEnterprise)]);
5
5
  return settings;
6
6
  }
7
- export function convertBackendSettingsToFrontendSettingsItem(large_file_storage) {
7
+ export function convertBackendSettingsToFrontendSettingsItem(large_file_storage, isEnterprise) {
8
+ let advancedPermissions = large_file_storage?.advanced_permissions
9
+ ? large_file_storage.advanced_permissions.map((rule) => ({
10
+ ...rule,
11
+ allow: rule.allow
12
+ ?.split(',')
13
+ .filter((rule) => !!rule)
14
+ .map((rule) => rule)
15
+ }))
16
+ : undefined;
8
17
  if (large_file_storage?.type === 'S3Storage') {
9
18
  return {
10
19
  resourceType: 's3',
11
20
  resourcePath: large_file_storage?.s3_resource_path?.replace('$res:', ''),
12
- publicResource: large_file_storage?.public_resource
21
+ publicResource: large_file_storage?.public_resource,
22
+ advancedPermissions
13
23
  };
14
24
  }
15
25
  else if (large_file_storage?.type === 'AzureBlobStorage') {
16
26
  return {
17
27
  resourceType: 'azure_blob',
18
28
  resourcePath: large_file_storage?.azure_blob_resource_path?.replace('$res:', ''),
19
- publicResource: large_file_storage?.public_resource
29
+ publicResource: large_file_storage?.public_resource,
30
+ advancedPermissions
20
31
  };
21
32
  }
22
33
  else if (large_file_storage?.type === 'AzureWorkloadIdentity') {
23
34
  return {
24
35
  resourceType: 'azure_workload_identity',
25
36
  resourcePath: large_file_storage?.azure_blob_resource_path?.replace('$res:', ''),
26
- publicResource: large_file_storage?.public_resource
37
+ publicResource: large_file_storage?.public_resource,
38
+ advancedPermissions
27
39
  };
28
40
  }
29
41
  else if (large_file_storage?.type === 'S3AwsOidc') {
30
42
  return {
31
43
  resourceType: 's3_aws_oidc',
32
44
  resourcePath: large_file_storage?.s3_resource_path?.replace('$res:', ''),
33
- publicResource: large_file_storage?.public_resource
45
+ publicResource: large_file_storage?.public_resource,
46
+ advancedPermissions
34
47
  };
35
48
  }
36
49
  else if (large_file_storage?.type === 'GoogleCloudStorage') {
37
50
  return {
38
51
  resourceType: 'gcloud_storage',
39
52
  resourcePath: large_file_storage?.gcs_resource_path?.replace('$res:', ''),
40
- publicResource: large_file_storage?.public_resource
53
+ publicResource: large_file_storage?.public_resource,
54
+ advancedPermissions
41
55
  };
42
56
  }
43
57
  else {
44
58
  return {
45
59
  resourceType: 's3',
46
60
  resourcePath: undefined,
47
- publicResource: undefined
61
+ publicResource: undefined,
62
+ advancedPermissions: defaultS3AdvancedPermissions(isEnterprise)
48
63
  };
49
64
  }
50
65
  }
@@ -61,7 +76,15 @@ export function convertFrontendToBackendettingsItem(s3ResourceSettings) {
61
76
  if (!emptyString(s3ResourceSettings.resourcePath)) {
62
77
  let resourcePathWithPrefix = `$res:${s3ResourceSettings.resourcePath}`;
63
78
  let params = {
64
- public_resource: s3ResourceSettings.publicResource
79
+ public_resource: s3ResourceSettings.publicResource,
80
+ ...(s3ResourceSettings.advancedPermissions
81
+ ? {
82
+ advanced_permissions: s3ResourceSettings.advancedPermissions.map((rule) => ({
83
+ ...rule,
84
+ allow: rule.allow.join(',')
85
+ }))
86
+ }
87
+ : {})
65
88
  };
66
89
  if (s3ResourceSettings.resourceType === 'azure_blob') {
67
90
  let typ = 'AzureBlobStorage';
@@ -91,3 +114,15 @@ export function convertFrontendToBackendettingsItem(s3ResourceSettings) {
91
114
  return params;
92
115
  }
93
116
  }
117
+ export function defaultS3AdvancedPermissions(isEnterprise) {
118
+ if (!isEnterprise)
119
+ return undefined;
120
+ return [
121
+ { pattern: 'windmill_uploads/*', allow: ['read', 'write', 'delete'] },
122
+ { pattern: 'u/{username}/**/*', allow: ['read', 'write', 'delete', 'list'] },
123
+ { pattern: 'g/{group}/**/*', allow: ['read', 'write', 'delete', 'list'] },
124
+ { pattern: 'f/{folder_write}/**/*', allow: ['read', 'write', 'delete', 'list'] },
125
+ { pattern: 'f/{folder_read}/**/*', allow: ['read', 'list'] },
126
+ { pattern: '**/*', allow: [] }
127
+ ];
128
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "windmill-components",
3
- "version": "1.542.4",
3
+ "version": "1.550.0",
4
4
  "scripts": {
5
5
  "dev": "vite dev",
6
6
  "build": "vite build",
@@ -151,7 +151,7 @@
151
151
  "windmill-parser-wasm-ts": "1.538.0",
152
152
  "windmill-parser-wasm-yaml": "1.510.1",
153
153
  "windmill-sql-datatype-parser-wasm": "1.512.0",
154
- "windmill-utils-internal": "^1.3.0",
154
+ "windmill-utils-internal": "^1.3.1",
155
155
  "xterm": "^5.3.0",
156
156
  "xterm-readline": "^1.1.2",
157
157
  "y-monaco": "^0.1.4",