windmill-components 1.208.0 → 1.216.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 (152) hide show
  1. package/package/common.d.ts +29 -0
  2. package/package/common.js +20 -0
  3. package/package/components/ApiConnectForm.svelte +81 -1
  4. package/package/components/ArgEnum.svelte +23 -31
  5. package/package/components/ArgEnum.svelte.d.ts +1 -0
  6. package/package/components/ArgInfo.svelte +1 -1
  7. package/package/components/ArgInput.svelte +125 -26
  8. package/package/components/ArgInput.svelte.d.ts +1 -0
  9. package/package/components/DBSchemaExplorer.svelte +2 -2
  10. package/package/components/DiffEditor.svelte +1 -1
  11. package/package/components/DisplayResult.svelte +29 -2
  12. package/package/components/Editor.svelte +21 -8
  13. package/package/components/EditorBar.svelte +3 -0
  14. package/package/components/ErrorOrRecoveryHandler.svelte +6 -3
  15. package/package/components/FlowBuilder.svelte +90 -92
  16. package/package/components/FlowBuilderTutorials.svelte +1 -3
  17. package/package/components/FlowLoopIterationPreview.svelte +145 -0
  18. package/package/components/FlowLoopIterationPreview.svelte.d.ts +27 -0
  19. package/package/components/FlowPreviewContent.svelte +19 -9
  20. package/package/components/FlowStatusViewerInner.svelte +29 -20
  21. package/package/components/FlowStatusViewerInner.svelte.d.ts +1 -0
  22. package/package/components/FlowTimeline.svelte +7 -5
  23. package/package/components/FlowTimeline.svelte.d.ts +1 -0
  24. package/package/components/InputTransformForm.svelte +21 -10
  25. package/package/components/InstanceSettings.svelte +2 -2
  26. package/package/components/ItemPicker.svelte +27 -5
  27. package/package/components/LightweightArgInput.svelte +144 -78
  28. package/package/components/LightweightArgInput.svelte.d.ts +2 -0
  29. package/package/components/LightweightSchemaForm.svelte +2 -3
  30. package/package/components/LogViewer.svelte +29 -6
  31. package/package/components/NumberTypeNarrowing.svelte +21 -1
  32. package/package/components/NumberTypeNarrowing.svelte.d.ts +2 -0
  33. package/package/components/RunForm.svelte +38 -6
  34. package/package/components/S3FilePicker.svelte +354 -0
  35. package/package/components/S3FilePicker.svelte.d.ts +26 -0
  36. package/package/components/SchemaEditor.svelte +2 -15
  37. package/package/components/SchemaEditor.svelte.d.ts +1 -1
  38. package/package/components/SchemaForm.svelte +3 -1
  39. package/package/components/SchemaModal.svelte +55 -2
  40. package/package/components/SchemaModal.svelte.d.ts +1 -16
  41. package/package/components/ScriptBuilder.svelte +1 -1
  42. package/package/components/SimpleEditor.svelte +45 -31
  43. package/package/components/StringTypeNarrowing.svelte +38 -2
  44. package/package/components/StringTypeNarrowing.svelte.d.ts +1 -0
  45. package/package/components/TemplateEditor.svelte +72 -62
  46. package/package/components/TestJobLoader.svelte +0 -1
  47. package/package/components/UserSettings.svelte +6 -3
  48. package/package/components/WorkspaceGroup.svelte +3 -0
  49. package/package/components/apps/components/display/AppImage.svelte +7 -1
  50. package/package/components/apps/components/display/AppStatCard.svelte +125 -0
  51. package/package/components/apps/components/display/AppStatCard.svelte.d.ts +22 -0
  52. package/package/components/apps/components/display/table/AppTable.svelte +1 -1
  53. package/package/components/apps/components/helpers/ResolveStyle.svelte +1 -1
  54. package/package/components/apps/editor/AppEditor.svelte +1 -1
  55. package/package/components/apps/editor/AppEditorHeader.svelte +14 -4
  56. package/package/components/apps/editor/AppEditorTutorial.svelte +8 -1
  57. package/package/components/apps/editor/AppPreview.svelte +1 -0
  58. package/package/components/apps/editor/AppReportsDrawer.svelte +491 -0
  59. package/package/components/apps/editor/AppReportsDrawer.svelte.d.ts +17 -0
  60. package/package/components/apps/editor/component/Component.svelte +8 -0
  61. package/package/components/apps/editor/component/components.d.ts +150 -61
  62. package/package/components/apps/editor/component/components.js +89 -2
  63. package/package/components/apps/editor/component/sets.js +2 -1
  64. package/package/components/apps/editor/componentsPanel/CssProperty.svelte +184 -145
  65. package/package/components/apps/editor/componentsPanel/cssUtils.d.ts +0 -4
  66. package/package/components/apps/editor/componentsPanel/cssUtils.js +0 -25
  67. package/package/components/apps/editor/componentsPanel/quickStyleProperties.js +2 -1
  68. package/package/components/apps/editor/componentsPanel/tailwindUtils.d.ts +1 -0
  69. package/package/components/apps/editor/componentsPanel/tailwindUtils.js +4474 -0
  70. package/package/components/apps/editor/contextPanel/ComponentOutput.svelte +0 -1
  71. package/package/components/apps/editor/contextPanel/SubGridOutput.svelte +1 -2
  72. package/package/components/apps/editor/settingsPanel/OneOfInputSpecsEditor.svelte +1 -0
  73. package/package/components/apps/editor/settingsPanel/QuickAddColumn.svelte +1 -1
  74. package/package/components/apps/types.d.ts +2 -0
  75. package/package/components/apps/utils.d.ts +1 -0
  76. package/package/components/apps/utils.js +15 -0
  77. package/package/components/build_workers.js +9 -14
  78. package/package/components/common/alert/Alert.svelte +12 -10
  79. package/package/components/common/skeleton/Skeleton.svelte +11 -6
  80. package/package/components/common/skeleton/Skeleton.svelte.d.ts +1 -0
  81. package/package/components/copilot/CodeCompletionStatus.svelte +37 -0
  82. package/package/components/copilot/CodeCompletionStatus.svelte.d.ts +14 -0
  83. package/package/components/copilot/FlowCopilotDrawer.svelte +5 -2
  84. package/package/components/copilot/FlowCopilotStatus.svelte +1 -1
  85. package/package/components/copilot/RegexGen.svelte +172 -0
  86. package/package/components/copilot/RegexGen.svelte.d.ts +16 -0
  87. package/package/components/copilot/ScriptFix.svelte +1 -8
  88. package/package/components/copilot/ScriptGen.svelte +13 -7
  89. package/package/components/copilot/TestOpenaiKey.svelte +1 -1
  90. package/package/components/copilot/completion.js +5 -0
  91. package/package/components/copilot/flow.d.ts +13 -3
  92. package/package/components/copilot/flow.js +98 -32
  93. package/package/components/copilot/lib.d.ts +5 -5
  94. package/package/components/copilot/lib.js +3 -2
  95. package/package/components/copilot/prompts/edit.yaml +11 -9
  96. package/package/components/copilot/prompts/editPrompt.js +5 -5
  97. package/package/components/copilot/prompts/fix.yaml +11 -9
  98. package/package/components/copilot/prompts/fixPrompt.js +5 -5
  99. package/package/components/copilot/prompts/gen.yaml +73 -28
  100. package/package/components/copilot/prompts/genPrompt.js +14 -14
  101. package/package/components/flows/content/FlowLoop.svelte +25 -1
  102. package/package/components/flows/content/FlowSettings.svelte +42 -3
  103. package/package/components/flows/content/ScriptEditorDrawer.svelte +2 -7
  104. package/package/components/flows/header/FlowPreviewButtons.svelte +1 -0
  105. package/package/components/flows/map/InsertModuleButton.svelte +1 -1
  106. package/package/components/flows/map/VirtualItem.svelte.d.ts +1 -0
  107. package/package/components/graph/FlowGraph.svelte +1 -0
  108. package/package/components/graph/svelvet/types/index.js +1 -1
  109. package/package/components/instanceSettings.js +1 -1
  110. package/package/components/propertyPicker/ObjectViewer.svelte +28 -2
  111. package/package/components/runs/RunRow.svelte +1 -1
  112. package/package/components/runs/RunsFilter.svelte +329 -172
  113. package/package/components/runs/RunsFilter.svelte.d.ts +2 -0
  114. package/package/components/settings/WorkspaceUserSettings.svelte +94 -70
  115. package/package/components/sidebar/SidebarContent.svelte +71 -15
  116. package/package/components/sidebar/UserMenu.svelte +2 -2
  117. package/package/components/sidebar/WorkspaceMenu.svelte +16 -14
  118. package/package/components/tutorials/SkipTutorials.svelte +32 -0
  119. package/package/components/tutorials/SkipTutorials.svelte.d.ts +16 -0
  120. package/package/components/tutorials/Tutorial.svelte +46 -18
  121. package/package/components/tutorials/TutorialControls.svelte +45 -0
  122. package/package/components/tutorials/TutorialControls.svelte.d.ts +20 -0
  123. package/package/consts.d.ts +3 -0
  124. package/package/consts.js +3 -0
  125. package/package/gen/core/OpenAPI.js +1 -1
  126. package/package/gen/index.d.ts +7 -0
  127. package/package/gen/index.js +3 -0
  128. package/package/gen/models/FlowValue.d.ts +1 -0
  129. package/package/gen/models/LargeFileStorage.d.ts +9 -0
  130. package/package/gen/models/LargeFileStorage.js +11 -0
  131. package/package/gen/models/PolarsClientKwargs.d.ts +3 -0
  132. package/package/gen/models/PolarsClientKwargs.js +5 -0
  133. package/package/gen/models/S3Resource.d.ts +9 -0
  134. package/package/gen/models/S3Resource.js +5 -0
  135. package/package/gen/models/WindmillFileMetadata.d.ts +7 -0
  136. package/package/gen/models/WindmillFileMetadata.js +5 -0
  137. package/package/gen/models/WindmillFilePreview.d.ts +13 -0
  138. package/package/gen/models/WindmillFilePreview.js +14 -0
  139. package/package/gen/models/WindmillLargeFile.d.ts +3 -0
  140. package/package/gen/models/WindmillLargeFile.js +5 -0
  141. package/package/gen/services/HelpersService.d.ts +84 -0
  142. package/package/gen/services/HelpersService.js +107 -0
  143. package/package/gen/services/UserService.d.ts +9 -9
  144. package/package/gen/services/UserService.js +15 -15
  145. package/package/gen/services/WorkspaceService.d.ts +42 -0
  146. package/package/gen/services/WorkspaceService.js +58 -0
  147. package/package/infer.js +5 -5
  148. package/package/stores.d.ts +2 -0
  149. package/package/stores.js +2 -0
  150. package/package/utils.d.ts +2 -1
  151. package/package/utils.js +19 -0
  152. package/package.json +5 -6
@@ -23,11 +23,40 @@ export interface SchemaProperty {
23
23
  contentEncoding?: 'base64';
24
24
  enum?: string[];
25
25
  };
26
+ min?: number;
27
+ max?: number;
28
+ currency?: string;
29
+ currencyLocale?: string;
30
+ multiselect?: boolean;
31
+ customErrorMessage?: string;
26
32
  properties?: {
27
33
  [name: string]: SchemaProperty;
28
34
  };
29
35
  required?: string[];
30
36
  }
37
+ export interface ModalSchemaProperty {
38
+ selectedType?: string;
39
+ description: string;
40
+ name: string;
41
+ required: boolean;
42
+ min?: number;
43
+ max?: number;
44
+ currency?: string;
45
+ currencyLocale?: string;
46
+ multiselect?: boolean;
47
+ format?: string;
48
+ pattern?: string;
49
+ enum_?: string[];
50
+ default?: any;
51
+ items?: {
52
+ type?: 'string' | 'number';
53
+ enum?: string[];
54
+ };
55
+ contentEncoding?: 'base64' | 'binary';
56
+ schema?: Schema;
57
+ customErrorMessage?: string;
58
+ }
59
+ export declare function modalToSchema(schema: ModalSchemaProperty): SchemaProperty;
31
60
  export type Schema = {
32
61
  $schema: string | undefined;
33
62
  type: string;
package/package/common.js CHANGED
@@ -1,3 +1,23 @@
1
+ export function modalToSchema(schema) {
2
+ return {
3
+ type: schema.selectedType,
4
+ description: schema.description,
5
+ pattern: schema.pattern,
6
+ default: schema.default,
7
+ enum: schema.enum_,
8
+ items: schema.items,
9
+ contentEncoding: schema.contentEncoding,
10
+ format: schema.format,
11
+ customErrorMessage: schema.customErrorMessage,
12
+ properties: schema.schema?.properties,
13
+ required: schema.schema?.required,
14
+ min: schema.min,
15
+ max: schema.max,
16
+ currency: schema.currency,
17
+ currencyLocale: schema.currencyLocale,
18
+ multiselect: schema.multiselect
19
+ };
20
+ }
1
21
  export function pathToMeta(path) {
2
22
  const splitted = path.split('/');
3
23
  let ownerKind;
@@ -6,6 +6,8 @@ import SimpleEditor from './SimpleEditor.svelte';
6
6
  import Toggle from './Toggle.svelte';
7
7
  import TestConnection from './TestConnection.svelte';
8
8
  import SupabaseIcon from './icons/SupabaseIcon.svelte';
9
+ import Popup from './common/popup/Popup.svelte';
10
+ import Button from './common/button/Button.svelte';
9
11
  export let resource_type;
10
12
  export let args = {};
11
13
  export let linkedSecret = undefined;
@@ -61,6 +63,32 @@ function switchTab(asJson) {
61
63
  }
62
64
  }
63
65
  $: resource_type == 'postgresql' && isSupabaseAvailable();
66
+ let connectionString = '';
67
+ let validConnectionString = true;
68
+ function parseConnectionString(close) {
69
+ // parse postgres connection string
70
+ const regex = /postgres:\/\/(?<user>[^:@]+)(?::(?<password>[^@]+))?@(?<host>[^:\/?]+)(?::(?<port>\d+))?\/(?<dbname>[^\?]+)?(?:\?.*sslmode=(?<sslmode>[^&]+))?/;
71
+ const match = connectionString.match(regex);
72
+ if (match) {
73
+ validConnectionString = true;
74
+ const { user, password, host, port, dbname, sslmode } = match.groups;
75
+ rawCode = JSON.stringify({
76
+ ...args,
77
+ user,
78
+ password: password || args?.password,
79
+ host,
80
+ port: port || args?.port,
81
+ dbname: dbname || args?.dbname,
82
+ sslmode: sslmode || args?.sslmode
83
+ }, null, 2);
84
+ rawCodeEditor?.setCode(rawCode);
85
+ close(null);
86
+ }
87
+ else {
88
+ validConnectionString = false;
89
+ }
90
+ }
91
+ let rawCodeEditor = undefined;
64
92
  </script>
65
93
 
66
94
  {#if !notFound}
@@ -72,6 +100,52 @@ $: resource_type == 'postgresql' && isSupabaseAvailable();
72
100
  }}
73
101
  />
74
102
  <TestConnection {resource_type} {args} />
103
+ {#if resource_type == 'postgresql'}
104
+ <Popup
105
+ let:close
106
+ floatingConfig={{
107
+ placement: 'bottom'
108
+ }}
109
+ >
110
+ <svelte:fragment slot="button">
111
+ <Button
112
+ spacingSize="sm"
113
+ size="xs"
114
+ btnClasses="h-8"
115
+ color="light"
116
+ variant="border"
117
+ nonCaptureEvent
118
+ >
119
+ From connection string
120
+ </Button>
121
+ </svelte:fragment>
122
+ <div class="block text-primary">
123
+ <div class="w-[550px] flex flex-col items-start gap-1">
124
+ <div class="flex flex-row gap-1 w-full">
125
+ <input
126
+ type="text"
127
+ bind:value={connectionString}
128
+ placeholder="postgres://user:password@host:5432/dbname?sslmode=disable"
129
+ />
130
+ <Button
131
+ size="xs"
132
+ color="blue"
133
+ buttonType="button"
134
+ on:click={() => {
135
+ parseConnectionString(close)
136
+ }}
137
+ disabled={connectionString.length <= 0}
138
+ >
139
+ Apply
140
+ </Button>
141
+ </div>
142
+ {#if !validConnectionString}
143
+ <p class="text-red-500 text-xs">Could not parse connection string</p>
144
+ {/if}
145
+ </div>
146
+ </div>
147
+ </Popup>
148
+ {/if}
75
149
  {#if resource_type == 'postgresql' && supabaseWizard}
76
150
  <a
77
151
  target="_blank"
@@ -93,7 +167,13 @@ $: resource_type == 'postgresql' && isSupabaseAvailable();
93
167
  {#if !emptyString(error)}<span class="text-red-400 text-xs mb-1 flex flex-row-reverse"
94
168
  >{error}</span
95
169
  >{:else}<div class="py-2" />{/if}
96
- <SimpleEditor autoHeight lang="json" bind:code={rawCode} fixedOverflowWidgets={false} />
170
+ <SimpleEditor
171
+ bind:this={rawCodeEditor}
172
+ autoHeight
173
+ lang="json"
174
+ bind:code={rawCode}
175
+ fixedOverflowWidgets={false}
176
+ />
97
177
  {:else}
98
178
  <SchemaForm noDelete {linkedSecretCandidates} bind:linkedSecret isValid {schema} bind:args />
99
179
  {/if}
@@ -1,4 +1,5 @@
1
- <script>import { Pen } from 'lucide-svelte';
1
+ <script>import AutoComplete from 'simple-svelte-autocomplete';
2
+ import { Pen } from 'lucide-svelte';
2
3
  import { createEventDispatcher } from 'svelte';
3
4
  import { twMerge } from 'tailwind-merge';
4
5
  export let customValue;
@@ -8,40 +9,31 @@ export let enum_;
8
9
  export let autofocus;
9
10
  export let defaultValue;
10
11
  export let valid;
12
+ export let disableCustomValue = false;
11
13
  const dispatch = createEventDispatcher();
12
14
  </script>
13
15
 
14
- {#if !customValue}
15
- <select
16
- on:focus={(e) => {
17
- dispatch('focus')
18
- }}
19
- {disabled}
20
- class="px-6"
21
- bind:value
22
- >
23
- {#each enum_ ?? [] as e}
24
- <option>{e}</option>
25
- {/each}
26
- </select>
27
- {:else}
28
- <!-- svelte-ignore a11y-autofocus -->
29
- <input
30
- {autofocus}
31
- on:focus
32
- type="text"
33
- class={twMerge(
34
- 'bg-surface-secondary',
35
- valid
36
- ? ''
37
- : 'border border-red-700 border-opacity-30 focus:border-red-700 focus:border-opacity-30 bg-red-100'
38
- )}
39
- placeholder={defaultValue ?? ''}
40
- bind:value
41
- />
42
- {/if}
16
+ <AutoComplete
17
+ items={enum_ ?? []}
18
+ bind:selectedItem={value}
19
+ inputClassName={twMerge(
20
+ 'bg-surface-secondary flex',
21
+ valid
22
+ ? ''
23
+ : 'border border-red-700 border-opacity-30 focus:border-red-700 focus:border-opacity-30 bg-red-100'
24
+ )}
25
+ value={value ?? defaultValue}
26
+ hideArrow={true}
27
+ dropdownClassName="!text-sm !py-2 !rounded-sm !border-gray-200 !border !shadow-md"
28
+ className="w-full"
29
+ onFocus={() => {
30
+ dispatch('focus')
31
+ }}
32
+ {disabled}
33
+ {autofocus}
34
+ />
43
35
 
44
- {#if !disabled}
36
+ {#if !disabled && !disableCustomValue}
45
37
  <button
46
38
  class="min-w-min !px-2 items-center text-gray-800 bg-surface-secondary border rounded center-center hover:bg-gray-300 transition-all cursor-pointer"
47
39
  on:click={() => {
@@ -8,6 +8,7 @@ declare const __propDef: {
8
8
  autofocus: boolean;
9
9
  defaultValue: string | undefined;
10
10
  valid: boolean;
11
+ disableCustomValue?: boolean | undefined;
11
12
  };
12
13
  events: {
13
14
  focus: CustomEvent<any>;
@@ -2,10 +2,10 @@
2
2
  import { workspaceStore } from '../stores';
3
3
  import { copyToClipboard, truncate } from '../utils';
4
4
  import { ClipboardCopy, Expand } from 'lucide-svelte';
5
- import { Button, DrawerContent } from './common';
6
5
  import Drawer from './common/drawer/Drawer.svelte';
7
6
  import ObjectViewer from './propertyPicker/ObjectViewer.svelte';
8
7
  import Tooltip from './Tooltip.svelte';
8
+ import { Button, DrawerContent } from './common';
9
9
  export let value;
10
10
  let jsonViewer;
11
11
  let jsonViewerContent;
@@ -1,5 +1,5 @@
1
- <script>import { setInputCat as computeInputCat } from '../utils';
2
- import { ChevronDown, DollarSign, Plus, X } from 'lucide-svelte';
1
+ <script>import { setInputCat as computeInputCat, emptyString } from '../utils';
2
+ import { ChevronDown, DollarSign, Pipette, Plus, X } from 'lucide-svelte';
3
3
  import { createEventDispatcher } from 'svelte';
4
4
  import autosize from 'svelte-autosize';
5
5
  import Multiselect from 'svelte-multiselect';
@@ -21,6 +21,9 @@ import { twMerge } from 'tailwind-merge';
21
21
  import ArgEnum from './ArgEnum.svelte';
22
22
  import ArrayTypeNarrowing from './ArrayTypeNarrowing.svelte';
23
23
  import DateTimeInput from './DateTimeInput.svelte';
24
+ import S3FilePicker from './S3FilePicker.svelte';
25
+ import CurrencyInput from './apps/components/inputs/currency/CurrencyInput.svelte';
26
+ import Label from './Label.svelte';
24
27
  export let label = '';
25
28
  export let value;
26
29
  export let defaultValue = undefined;
@@ -52,9 +55,11 @@ export let resourceTypes;
52
55
  export let disablePortal = false;
53
56
  export let showSchemaExplorer = false;
54
57
  export let simpleTooltip = undefined;
58
+ export let customErrorMessage = undefined;
55
59
  let seeEditable = enum_ != undefined || pattern != undefined;
56
60
  const dispatch = createEventDispatcher();
57
61
  let error = '';
62
+ let s3FilePicker;
58
63
  let el = undefined;
59
64
  export let editor = undefined;
60
65
  let inputCat = computeInputCat(type, format, itemsType?.type, enum_, contentEncoding);
@@ -126,7 +131,15 @@ function validateInput(pattern, v, required) {
126
131
  }
127
132
  else {
128
133
  if (pattern && !testRegex(pattern, v)) {
129
- error = `Should match ${pattern}`;
134
+ if (!emptyString(customErrorMessage)) {
135
+ error = customErrorMessage ?? '';
136
+ }
137
+ else if (format == 'email') {
138
+ error = 'invalid email address';
139
+ }
140
+ else {
141
+ error = `Should match ${pattern}`;
142
+ }
130
143
  valid && (valid = false);
131
144
  }
132
145
  else {
@@ -156,6 +169,17 @@ let customValue = false;
156
169
  $: validateInput(pattern, value, required);
157
170
  </script>
158
171
 
172
+ <S3FilePicker
173
+ bind:this={s3FilePicker}
174
+ initialFileKey={value}
175
+ bind:selectedFileKey={value}
176
+ on:close={() => {
177
+ rawValue = JSON.stringify(value, null, 2)
178
+ editor?.setCode(rawValue)
179
+ }}
180
+ readOnlyMode={false}
181
+ />
182
+
159
183
  <!-- svelte-ignore a11y-autofocus -->
160
184
  <div class="flex flex-col w-full {minW ? 'min-w-[250px]' : ''}">
161
185
  <div>
@@ -185,6 +209,9 @@ $: validateInput(pattern, value, required);
185
209
 
186
210
  {#if type == 'array'}
187
211
  <ArrayTypeNarrowing bind:itemsType />
212
+ <Label label="Display using multiselect">
213
+ <Toggle disabled={itemsType?.enum == undefined} bind:checked={extra.multiselect} />
214
+ </Label>
188
215
  {:else if (type == 'string' && format != 'date-time') || ['number', 'object'].includes(type ?? '')}
189
216
  <div class="p-2 my-1 text-xs border-solid border border-gray-200 rounded-lg">
190
217
  <div class="w-min">
@@ -206,9 +233,20 @@ $: validateInput(pattern, value, required);
206
233
  {#if seeEditable}
207
234
  <div class="mt-2">
208
235
  {#if type == 'string' && format != 'date-time'}
209
- <StringTypeNarrowing bind:format bind:pattern bind:enum_ bind:contentEncoding />
236
+ <StringTypeNarrowing
237
+ bind:customErrorMessage
238
+ bind:format
239
+ bind:pattern
240
+ bind:enum_
241
+ bind:contentEncoding
242
+ />
210
243
  {:else if type == 'number'}
211
- <NumberTypeNarrowing bind:min={extra['min']} bind:max={extra['max']} />
244
+ <NumberTypeNarrowing
245
+ bind:min={extra['min']}
246
+ bind:max={extra['max']}
247
+ bind:currency={extra['currency']}
248
+ bind:currencyLocale={extra['currencyLocale']}
249
+ />
212
250
  {:else if type == 'object'}
213
251
  <ObjectTypeNarrowing bind:format />
214
252
  {/if}
@@ -238,20 +276,34 @@ $: validateInput(pattern, value, required);
238
276
  </div>
239
277
  {:else if extra['seconds'] !== undefined}
240
278
  <SecondsInput bind:seconds={value} on:focus />
241
- {:else}
242
- <input
243
- {autofocus}
244
- on:focus
245
- {disabled}
246
- type="number"
247
- class={valid
248
- ? ''
249
- : 'border border-red-700 border-opacity-30 focus:border-red-700 focus:border-opacity-30 bg-red-100'}
250
- placeholder={defaultValue ?? ''}
279
+ {:else if extra?.currency}
280
+ <CurrencyInput
281
+ inputClasses={{
282
+ formatted: twMerge('px-2 w-full py-1.5 text-black'),
283
+ wrapper: 'w-full windmillapp',
284
+ formattedZero: twMerge('text-black')
285
+ }}
286
+ style="color:black;"
251
287
  bind:value
252
- min={extra['min']}
253
- max={extra['max']}
288
+ currency={extra?.currency}
289
+ locale={extra?.currencyLocale ?? 'en-US'}
254
290
  />
291
+ {:else}
292
+ <div class="relative w-full">
293
+ <input
294
+ {autofocus}
295
+ on:focus
296
+ {disabled}
297
+ type="number"
298
+ class={valid
299
+ ? ''
300
+ : 'border border-red-700 border-opacity-30 focus:border-red-700 focus:border-opacity-30 bg-red-100'}
301
+ placeholder={defaultValue ?? ''}
302
+ bind:value
303
+ min={extra['min']}
304
+ max={extra['max']}
305
+ />
306
+ </div>
255
307
  {/if}
256
308
  {:else if inputCat == 'boolean'}
257
309
  <Toggle
@@ -278,6 +330,15 @@ $: validateInput(pattern, value, required);
278
330
  selectedOptionsDraggable={true}
279
331
  />
280
332
  </div>
333
+ {:else if extra.multiselect}
334
+ <div class="items-start">
335
+ <Multiselect
336
+ {disabled}
337
+ bind:selected={value}
338
+ options={itemsType?.enum ?? []}
339
+ selectedOptionsDraggable={true}
340
+ />
341
+ </div>
281
342
  {:else}
282
343
  <div class="w-full">
283
344
  {#key redraw}
@@ -297,17 +358,19 @@ $: validateInput(pattern, value, required);
297
358
  {:else if itemsType?.type == 'object'}
298
359
  <JsonEditor code={JSON.stringify(v, null, 2)} bind:value={v} />
299
360
  {:else if Array.isArray(itemsType?.enum)}
300
- <select
301
- on:focus={(e) => {
361
+ <ArgEnum
362
+ on:focus={() => {
302
363
  dispatch('focus')
303
364
  }}
304
- class="px-6"
365
+ {defaultValue}
366
+ {valid}
367
+ {customValue}
368
+ {disabled}
369
+ {autofocus}
305
370
  bind:value={v}
306
- >
307
- {#each itemsType?.enum ?? [] as e}
308
- <option>{e}</option>
309
- {/each}
310
- </select>
371
+ disableCustomValue={true}
372
+ enum_={itemsType?.enum ?? []}
373
+ />
311
374
  {:else}
312
375
  <input type="text" bind:value={v} id="arg-input-array" />
313
376
  {/if}
@@ -357,6 +420,30 @@ $: validateInput(pattern, value, required);
357
420
  <span class="text-2xs text-tertiary">Loading resource types...</span>
358
421
  {:else if inputCat == 'resource-object' && (resourceTypes == undefined || (format.split('-').length > 1 && resourceTypes.includes(format.substring('resource-'.length))))}
359
422
  <ObjectResourceInput {disablePortal} {format} bind:value {showSchemaExplorer} />
423
+ {:else if inputCat == 'resource-object' && format.split('-').length > 1 && format.replace('resource-', '') == 's3object'}
424
+ <div class="flex flex-col w-full gap-1">
425
+ <JsonEditor
426
+ bind:editor
427
+ on:focus={(e) => {
428
+ dispatch('focus')
429
+ }}
430
+ code={JSON.stringify({ s3: '' }, null, 2)}
431
+ bind:value
432
+ />
433
+ <Button
434
+ variant="border"
435
+ color="light"
436
+ size="xs"
437
+ btnClasses="mt-1"
438
+ on:click={() => {
439
+ s3FilePicker?.open?.()
440
+ }}
441
+ id="arg-input-file-picker"
442
+ startIcon={{ icon: Pipette }}
443
+ >
444
+ Choose an object from the catalog
445
+ </Button>
446
+ </div>
360
447
  {:else if inputCat == 'object' || inputCat == 'resource-object'}
361
448
  {#if properties && Object.keys(properties).length > 0}
362
449
  <div class="p-4 pl-8 border rounded w-full">
@@ -418,6 +505,18 @@ $: validateInput(pattern, value, required);
418
505
  : undefined}
419
506
  {showSchemaExplorer}
420
507
  />
508
+ {:else if inputCat == 'email'}
509
+ <input
510
+ {autofocus}
511
+ on:focus
512
+ {disabled}
513
+ type="email"
514
+ class={valid
515
+ ? ''
516
+ : 'border border-red-700 border-opacity-30 focus:border-red-700 focus:border-opacity-3'}
517
+ placeholder={defaultValue ?? ''}
518
+ bind:value
519
+ />
421
520
  {:else if inputCat == 'string'}
422
521
  <div class="flex flex-col w-full">
423
522
  <div class="flex flex-row w-full items-center justify-between relative">
@@ -439,7 +538,7 @@ $: validateInput(pattern, value, required);
439
538
  'w-full',
440
539
  valid
441
540
  ? ''
442
- : 'border border-red-700 border-opacity-30 focus:border-red-700 focus:border-opacity-30 bg-red-100'
541
+ : 'border border-red-700 border-opacity-30 focus:border-red-700 focus:border-opacity-3'
443
542
  )}
444
543
  placeholder={defaultValue ?? ''}
445
544
  bind:value
@@ -43,6 +43,7 @@ declare const __propDef: {
43
43
  disablePortal?: boolean | undefined;
44
44
  showSchemaExplorer?: boolean | undefined;
45
45
  simpleTooltip?: string | undefined;
46
+ customErrorMessage?: string | undefined;
46
47
  editor?: SimpleEditor | undefined;
47
48
  focus?: (() => void) | undefined;
48
49
  };
@@ -86,7 +86,7 @@ const scripts = {
86
86
  argName: 'api'
87
87
  },
88
88
  bigquery: {
89
- code: `import { BigQuery } from '@google-cloud/bigquery@7.2.0';
89
+ code: `import { BigQuery } from 'npm:@google-cloud/bigquery@7.2.0';
90
90
  export async function main(args: bigquery) {
91
91
  const bq = new BigQuery({
92
92
  credentials: args
@@ -113,7 +113,7 @@ GROUP BY table_name".replace('{dataset.id}', dataset.id)
113
113
  }
114
114
  return schema
115
115
  }`,
116
- lang: 'bun',
116
+ lang: 'deno',
117
117
  argName: 'args'
118
118
  },
119
119
  snowflake: {
@@ -9,7 +9,7 @@ import 'monaco-editor/esm/vs/basic-languages/sql/sql.contribution';
9
9
  import 'monaco-editor/esm/vs/language/typescript/monaco.contribution';
10
10
  import { initializeVscode } from './vscode';
11
11
  import EditorTheme from './EditorTheme.svelte';
12
- import { buildWorkerDefinition } from 'monaco-editor-workers';
12
+ import { buildWorkerDefinition } from './build_workers';
13
13
  buildWorkerDefinition('../../../workers', import.meta.url, false);
14
14
  const SIDE_BY_SIDE_MIN_WIDTH = 700;
15
15
  export let automaticLayout = true;
@@ -6,6 +6,7 @@ import { Button, Drawer, DrawerContent } from './common';
6
6
  import { ClipboardCopy, Download, Expand } from 'lucide-svelte';
7
7
  import Portal from 'svelte-portal';
8
8
  import ObjectViewer from './propertyPicker/ObjectViewer.svelte';
9
+ import S3FilePicker from './S3FilePicker.svelte';
9
10
  export let result;
10
11
  export let requireHtmlApproval = false;
11
12
  export let filename = undefined;
@@ -94,12 +95,16 @@ function inferResultKind(result) {
94
95
  keys.includes('approvalPage')) {
95
96
  return 'approval';
96
97
  }
98
+ else if (keys.length === 1 && keys.includes('s3')) {
99
+ return 's3object';
100
+ }
97
101
  }
98
102
  catch (err) { }
99
103
  }
100
104
  return 'json';
101
105
  }
102
106
  let jsonViewer;
107
+ let s3FileViewer;
103
108
  function toJsonStr(result) {
104
109
  return JSON.stringify(result, null, 4);
105
110
  }
@@ -115,7 +120,7 @@ function contentOrRootString(obj) {
115
120
 
116
121
  <div class="inline-highlight relative grow min-h-[200px]">
117
122
  {#if result != undefined && length != undefined && largeObject != undefined}
118
- {#if resultKind && resultKind != 'json'}
123
+ {#if resultKind && !['json', 's3object'].includes(resultKind)}
119
124
  <div class="top-0 flex flex-row w-full justify-between items-center"
120
125
  ><div class="mb-2 text-tertiary text-sm">
121
126
  as JSON&nbsp;<input class="windmillapp" type="checkbox" bind:checked={forceJson} /></div
@@ -133,7 +138,9 @@ function contentOrRootString(obj) {
133
138
  <button on:click={jsonViewer.openDrawer}><Expand size={16} /></button>
134
139
  </div>
135
140
  {/if}</div
136
- >{/if}{#if !forceJson && resultKind == 'table-col'}<div
141
+ >
142
+ {/if}
143
+ {#if !forceJson && resultKind == 'table-col'}<div
137
144
  class="grid grid-flow-col-dense border rounded-md"
138
145
  >
139
146
  {#each Object.keys(result) as col}
@@ -260,6 +267,17 @@ function contentOrRootString(obj) {
260
267
  ><a rel="noreferrer" target="_blank" href={result['approvalPage']}>Approval Page</a></div
261
268
  >
262
269
  </div>
270
+ {:else if !forceJson && resultKind == 's3object'}
271
+ <div class="absolute top-1 h-full w-full">
272
+ <Highlight class="" language={json} code={toJsonStr(result).replace(/\\n/g, '\n')} />
273
+ <button
274
+ class="text-secondary underline text-2xs whitespace-nowrap"
275
+ on:click={() => {
276
+ s3FileViewer?.open?.()
277
+ }}
278
+ >s3 explorer
279
+ </button>
280
+ </div>
263
281
  {:else if largeObject}<div class="text-sm text-tertiary"
264
282
  ><a
265
283
  download="{filename ?? 'result'}.json"
@@ -332,4 +350,13 @@ function contentOrRootString(obj) {
332
350
  </DrawerContent>
333
351
  </Drawer>
334
352
  </Portal>
353
+
354
+ <Portal>
355
+ <S3FilePicker
356
+ bind:this={s3FileViewer}
357
+ initialFileKey={result}
358
+ selectedFileKey={result}
359
+ readOnlyMode={true}
360
+ />
361
+ </Portal>
335
362
  {/if}