windmill-components 1.687.0 → 1.695.1

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 (264) hide show
  1. package/package/components/ArgInput.svelte +2 -0
  2. package/package/components/AutoscalingConfigEditor.svelte +18 -4
  3. package/package/components/CompareWorkspaces.svelte +206 -157
  4. package/package/components/DatatableSchemaDiff.svelte +2 -2
  5. package/package/components/Dev.svelte +401 -85
  6. package/package/components/EditableSchemaForm.svelte +4 -0
  7. package/package/components/ErrorOrRecoveryHandler.svelte +2 -2
  8. package/package/components/FlowPreviewContent.svelte +32 -30
  9. package/package/components/FlowRestartButton.svelte +143 -61
  10. package/package/components/FlowRestartButton.svelte.d.ts +37 -0
  11. package/package/components/FlowStatusViewer.svelte +15 -1
  12. package/package/components/FlowStatusViewer.svelte.d.ts +10 -2
  13. package/package/components/FlowStatusViewerInner.svelte +1 -2
  14. package/package/components/FlowStatusViewerInner.svelte.d.ts +6 -2
  15. package/package/components/ForkConflictModal.svelte +57 -0
  16. package/package/components/ForkConflictModal.svelte.d.ts +3 -0
  17. package/package/components/GitRepoViewer.svelte +251 -97
  18. package/package/components/InputTransformSchemaForm.svelte +1 -1
  19. package/package/components/InstanceSettings.svelte +36 -16
  20. package/package/components/Login.svelte +113 -28
  21. package/package/components/Login.svelte.d.ts +1 -0
  22. package/package/components/Path.svelte +7 -1
  23. package/package/components/Path.svelte.d.ts +1 -1
  24. package/package/components/RunsPage.svelte +2 -1
  25. package/package/components/S3FilePickerInner.svelte +89 -89
  26. package/package/components/ScriptEditor.svelte +18 -5
  27. package/package/components/ShareModal.svelte.d.ts +1 -1
  28. package/package/components/apps/components/helpers/RunnableComponent.svelte.d.ts +3 -0
  29. package/package/components/apps/components/helpers/executeRunnable.js +2 -1
  30. package/package/components/apps/editor/AppReportsDrawerInner.svelte +1 -1
  31. package/package/components/apps/editor/appPolicy.js +2 -1
  32. package/package/components/apps/editor/commonAppUtils.d.ts +3 -0
  33. package/package/components/apps/editor/inlineScriptsPanel/CacheTtlPopup.svelte +1 -1
  34. package/package/components/apps/editor/inlineScriptsPanel/InlineScriptEditor.svelte +7 -0
  35. package/package/components/apps/editor/inlineScriptsPanel/TagPopup.svelte +49 -0
  36. package/package/components/apps/editor/inlineScriptsPanel/TagPopup.svelte.d.ts +9 -0
  37. package/package/components/apps/inputType.d.ts +1 -0
  38. package/package/components/apps/sharedTypes.d.ts +1 -0
  39. package/package/components/auditLogs/AuditLogsFilters.svelte +8 -3
  40. package/package/components/common/fileUpload/S3ArgInput.svelte +12 -10
  41. package/package/components/common/fileUpload/S3ArgInput.svelte.d.ts +2 -0
  42. package/package/components/copilot/chat/AIChatDisplay.svelte +5 -36
  43. package/package/components/copilot/chat/AIChatInput.svelte +56 -47
  44. package/package/components/copilot/chat/AIChatManager.svelte.js +48 -46
  45. package/package/components/copilot/chat/ContextElementBadge.svelte +6 -4
  46. package/package/components/copilot/chat/app/core.d.ts +12 -20
  47. package/package/components/copilot/chat/app/core.js +103 -160
  48. package/package/components/copilot/chat/app/core.test.js +234 -9
  49. package/package/components/copilot/chat/context.js +44 -0
  50. package/package/components/copilot/chat/flow/FlowAIChat.svelte +5 -3
  51. package/package/components/copilot/chat/flow/core.d.ts +2 -1
  52. package/package/components/copilot/chat/flow/core.js +48 -21
  53. package/package/components/copilot/chat/flow/helperUtils.d.ts +5 -2
  54. package/package/components/copilot/chat/flow/helperUtils.js +33 -1
  55. package/package/components/copilot/chat/flow/helperUtils.test.js +116 -1
  56. package/package/components/copilot/chat/flow/openFlow.json +1 -1
  57. package/package/components/copilot/chat/flow/openFlowZod.gen.js +24 -0
  58. package/package/components/copilot/chat/script/core.js +3 -0
  59. package/package/components/copilot/chat/shared.d.ts +6 -0
  60. package/package/components/copilot/chat/shared.js +22 -1
  61. package/package/components/copilot/chat/shared.test.d.ts +1 -0
  62. package/package/components/copilot/chat/shared.test.js +412 -0
  63. package/package/components/copilot/chat/workspaceTools.d.ts +7 -0
  64. package/package/components/copilot/chat/workspaceTools.js +239 -0
  65. package/package/components/copilot/chat/workspaceToolsZod.gen.d.ts +1295 -0
  66. package/package/components/copilot/chat/workspaceToolsZod.gen.js +424 -0
  67. package/package/components/copilot/lib.js +3 -1
  68. package/package/components/copilot/lib.test.d.ts +1 -0
  69. package/package/components/copilot/lib.test.js +19 -0
  70. package/package/components/copilot/modelConfig.d.ts +3 -0
  71. package/package/components/copilot/modelConfig.js +10 -0
  72. package/package/components/flows/FlowProgressBar.svelte +5 -2
  73. package/package/components/flows/content/FlowModuleComponent.svelte +636 -599
  74. package/package/components/flows/conversations/FlowChatManager.svelte.js +21 -10
  75. package/package/components/flows/flowStateUtils.svelte.js +5 -1
  76. package/package/components/flows/map/FlowModuleSchemaMap.svelte +3 -2
  77. package/package/components/flows/map/FlowModuleSchemaMap.svelte.d.ts +1 -0
  78. package/package/components/git_sync/GitSyncContext.svelte.js +0 -2
  79. package/package/components/graph/FlowGraphV2.svelte +7 -3
  80. package/package/components/graph/FlowGraphV2.svelte.d.ts +1 -0
  81. package/package/components/graph/renderers/triggers/TriggersBadge.svelte +3 -0
  82. package/package/components/home/deploy_ui.js +1 -1
  83. package/package/components/icons/AzureIcon.svelte +12 -25
  84. package/package/components/icons/AzureIcon.svelte.d.ts +3 -2
  85. package/package/components/instanceSettings.js +24 -0
  86. package/package/components/mcp/McpScopeSelector.svelte +119 -9
  87. package/package/components/mcp/McpScopeSelector.svelte.d.ts +1 -0
  88. package/package/components/offboarding-utils.js +2 -0
  89. package/package/components/progressBar/ProgressBar.svelte +9 -5
  90. package/package/components/progressBar/ProgressBar.svelte.d.ts +1 -0
  91. package/package/components/raw_apps/DeleteAfterUsePopup.svelte +52 -0
  92. package/package/components/raw_apps/DeleteAfterUsePopup.svelte.d.ts +9 -0
  93. package/package/components/raw_apps/RawAppBackgroundRunner.svelte +5 -1
  94. package/package/components/raw_apps/RawAppEditor.svelte +159 -102
  95. package/package/components/raw_apps/RawAppInlineScriptEditor.svelte +9 -3
  96. package/package/components/raw_apps/RawAppInlineScriptEditor.svelte.d.ts +2 -1
  97. package/package/components/raw_apps/RawAppInlineScriptRunnable.svelte +1 -0
  98. package/package/components/raw_apps/RawAppInlineScriptRunnable.svelte.d.ts +1 -0
  99. package/package/components/raw_apps/RawAppInputsSpecEditor.svelte +48 -5
  100. package/package/components/raw_apps/RawAppSharedUiDrawer.svelte +129 -0
  101. package/package/components/raw_apps/RawAppSharedUiDrawer.svelte.d.ts +5 -0
  102. package/package/components/raw_apps/RawAppSidebar.svelte +12 -0
  103. package/package/components/raw_apps/dataTableRefUtils.d.ts +7 -0
  104. package/package/components/raw_apps/dataTableRefUtils.js +34 -0
  105. package/package/components/raw_apps/dataTableRefUtils.test.d.ts +1 -0
  106. package/package/components/raw_apps/dataTableRefUtils.test.js +29 -0
  107. package/package/components/raw_apps/rawAppPolicy.d.ts +1 -0
  108. package/package/components/raw_apps/rawAppPolicy.js +17 -2
  109. package/package/components/resources/resourceTypesFilter.d.ts +19 -0
  110. package/package/components/resources/resourceTypesFilter.js +21 -0
  111. package/package/components/restartFromStepPath.d.ts +39 -0
  112. package/package/components/restartFromStepPath.js +89 -0
  113. package/package/components/runs/JobDetailFieldConfig.d.ts +1 -0
  114. package/package/components/runs/JobDetailFieldConfig.js +57 -10
  115. package/package/components/runs/JobDetailHeader.svelte +24 -3
  116. package/package/components/runs/runsFilter.d.ts +1 -1
  117. package/package/components/schema/FlowPropertyEditor.svelte +30 -1
  118. package/package/components/schema/FlowPropertyEditor.svelte.d.ts +5 -2
  119. package/package/components/search/GlobalSearchModal.svelte +8 -1
  120. package/package/components/select/Select.svelte +1 -1
  121. package/package/components/settings/CreateToken.svelte +48 -77
  122. package/package/components/settings/EditTokenScopesModal.svelte +57 -0
  123. package/package/components/settings/EditTokenScopesModal.svelte.d.ts +10 -0
  124. package/package/components/settings/ScopesPicker.svelte +43 -0
  125. package/package/components/settings/ScopesPicker.svelte.d.ts +11 -0
  126. package/package/components/settings/TokensTable.svelte +51 -15
  127. package/package/components/sidebar/OperatorMenu.svelte +6 -0
  128. package/package/components/sidebar/SidebarContent.svelte +11 -1
  129. package/package/components/triggers/AddTriggersButton.svelte +6 -0
  130. package/package/components/triggers/CaptureWrapper.svelte +19 -1
  131. package/package/components/triggers/TriggerEditorToolbar.svelte.d.ts +1 -1
  132. package/package/components/triggers/TriggerModeToggle.svelte +36 -7
  133. package/package/components/triggers/TriggerModeToggle.svelte.d.ts +1 -1
  134. package/package/components/triggers/TriggerSuspendedJobsModal.svelte.d.ts +1 -1
  135. package/package/components/triggers/TriggersEditor.svelte +5 -1
  136. package/package/components/triggers/TriggersWrapper.svelte +10 -0
  137. package/package/components/triggers/azure/AzureCapture.svelte +41 -0
  138. package/package/components/triggers/azure/AzureCapture.svelte.d.ts +44 -0
  139. package/package/components/triggers/azure/AzureTriggerEditor.svelte +20 -0
  140. package/package/components/triggers/azure/AzureTriggerEditor.svelte.d.ts +9 -0
  141. package/package/components/triggers/azure/AzureTriggerEditorConfigSection.svelte +301 -0
  142. package/package/components/triggers/azure/AzureTriggerEditorConfigSection.svelte.d.ts +16 -0
  143. package/package/components/triggers/azure/AzureTriggerEditorInner.svelte +422 -0
  144. package/package/components/triggers/azure/AzureTriggerEditorInner.svelte.d.ts +25 -0
  145. package/package/components/triggers/azure/AzureTriggerPanel.svelte +55 -0
  146. package/package/components/triggers/azure/AzureTriggerPanel.svelte.d.ts +10 -0
  147. package/{dist/sharedUtils/components/triggers/kafka → package/components/triggers/azure}/utils.d.ts +1 -1
  148. package/package/components/triggers/azure/utils.js +56 -0
  149. package/package/components/triggers/email/EmailTriggerEditorInner.svelte +2 -0
  150. package/package/components/triggers/gcp/GcpTriggerEditorInner.svelte +9 -3
  151. package/package/components/triggers/http/RouteEditorInner.svelte +2 -0
  152. package/package/components/triggers/kafka/KafkaTriggerEditorInner.svelte +9 -3
  153. package/package/components/triggers/mqtt/MqttTriggerEditorInner.svelte +9 -3
  154. package/package/components/triggers/nats/NatsTriggerEditorInner.svelte +9 -3
  155. package/package/components/triggers/postgres/PostgresTriggerEditorInner.svelte +9 -3
  156. package/package/components/triggers/schedules/ScheduleEditorInner.svelte +9 -3
  157. package/package/components/triggers/sqs/SqsTriggerEditorInner.svelte +9 -3
  158. package/package/components/triggers/triggers.svelte.d.ts +1 -0
  159. package/package/components/triggers/triggers.svelte.js +23 -1
  160. package/package/components/triggers/utils.js +20 -0
  161. package/package/components/triggers/websocket/WebsocketTriggerEditorInner.svelte +9 -3
  162. package/package/components/triggers.d.ts +1 -1
  163. package/package/components/useNestedRestartState.svelte.d.ts +56 -0
  164. package/package/components/useNestedRestartState.svelte.js +320 -0
  165. package/package/components/workspaceSettings/SharedUiSettings.svelte +175 -0
  166. package/package/components/workspaceSettings/SharedUiSettings.svelte.d.ts +3 -0
  167. package/package/gen/core/OpenAPI.js +1 -1
  168. package/package/gen/schemas.gen.d.ts +294 -24
  169. package/package/gen/schemas.gen.js +297 -25
  170. package/package/gen/services.gen.d.ts +247 -4
  171. package/package/gen/services.gen.js +498 -7
  172. package/package/gen/types.gen.d.ts +990 -37
  173. package/package/hubPaths.json +2 -5
  174. package/package/infer.d.ts +1 -1
  175. package/package/infer.js +37 -51
  176. package/package/mcpEndpointTools.js +60 -4
  177. package/package/script_helpers.js +17 -0
  178. package/package/stores.d.ts +7 -0
  179. package/package/stores.js +6 -1
  180. package/package/system_prompts/index.d.ts +1 -0
  181. package/package/system_prompts/index.js +8 -0
  182. package/package/system_prompts/prompts.d.ts +16 -13
  183. package/package/system_prompts/prompts.js +653 -43
  184. package/package/templates/ci_test_bun.ts.template +8 -0
  185. package/package/templates/ci_test_python.py.template +8 -0
  186. package/package/utils/forkConflict.d.ts +26 -0
  187. package/package/utils/forkConflict.js +56 -0
  188. package/package/utils_deployable.d.ts +164 -121
  189. package/package/utils_deployable.js +61 -11
  190. package/package/utils_workspace_deploy.js +3 -1
  191. package/package.json +29 -5
  192. package/dist/sharedUtils/assets/tokens/colorTokensConfig.d.ts +0 -2
  193. package/dist/sharedUtils/base.d.ts +0 -1
  194. package/dist/sharedUtils/cloud.d.ts +0 -1
  195. package/dist/sharedUtils/common.d.ts +0 -111
  196. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/count.d.ts +0 -5
  197. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/delete.d.ts +0 -5
  198. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/insert.d.ts +0 -5
  199. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/select.d.ts +0 -13
  200. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/update.d.ts +0 -11
  201. package/dist/sharedUtils/components/apps/components/display/dbtable/utils.d.ts +0 -95
  202. package/dist/sharedUtils/components/apps/editor/appPolicy.d.ts +0 -6
  203. package/dist/sharedUtils/components/apps/editor/appUtilsCore.d.ts +0 -7
  204. package/dist/sharedUtils/components/apps/editor/appUtilsS3.d.ts +0 -33
  205. package/dist/sharedUtils/components/apps/editor/commonAppUtils.d.ts +0 -10
  206. package/dist/sharedUtils/components/apps/editor/component/components.d.ts +0 -5371
  207. package/dist/sharedUtils/components/apps/editor/component/default-codes.d.ts +0 -3
  208. package/dist/sharedUtils/components/apps/editor/component/index.d.ts +0 -3
  209. package/dist/sharedUtils/components/apps/editor/component/sets.d.ts +0 -7
  210. package/dist/sharedUtils/components/apps/editor/componentsPanel/componentDefaultProps.d.ts +0 -3
  211. package/dist/sharedUtils/components/apps/gridUtils.d.ts +0 -14
  212. package/dist/sharedUtils/components/apps/inputType.d.ts +0 -178
  213. package/dist/sharedUtils/components/apps/rx.d.ts +0 -29
  214. package/dist/sharedUtils/components/apps/sharedTypes.d.ts +0 -21
  215. package/dist/sharedUtils/components/apps/types.d.ts +0 -274
  216. package/dist/sharedUtils/components/assets/lib.d.ts +0 -25
  217. package/dist/sharedUtils/components/common/alert/model.d.ts +0 -2
  218. package/dist/sharedUtils/components/common/badge/model.d.ts +0 -8
  219. package/dist/sharedUtils/components/common/button/model.d.ts +0 -45
  220. package/dist/sharedUtils/components/common/fileInput/model.d.ts +0 -1
  221. package/dist/sharedUtils/components/common/index.d.ts +0 -24
  222. package/dist/sharedUtils/components/common/skeleton/model.d.ts +0 -21
  223. package/dist/sharedUtils/components/dbTypes.d.ts +0 -14
  224. package/dist/sharedUtils/components/diff_drawer.d.ts +0 -26
  225. package/dist/sharedUtils/components/ducklake.d.ts +0 -1
  226. package/dist/sharedUtils/components/flows/scheduleUtils.d.ts +0 -7
  227. package/dist/sharedUtils/components/icons/index.d.ts +0 -101
  228. package/dist/sharedUtils/components/random_positive_adjetive.d.ts +0 -1
  229. package/dist/sharedUtils/components/raw_apps/rawAppPolicy.d.ts +0 -10
  230. package/dist/sharedUtils/components/raw_apps/utils.d.ts +0 -15
  231. package/dist/sharedUtils/components/triggers/email/utils.d.ts +0 -4
  232. package/dist/sharedUtils/components/triggers/gcp/utils.d.ts +0 -2
  233. package/dist/sharedUtils/components/triggers/http/utils.d.ts +0 -11
  234. package/dist/sharedUtils/components/triggers/mqtt/utils.d.ts +0 -2
  235. package/dist/sharedUtils/components/triggers/nats/utils.d.ts +0 -2
  236. package/dist/sharedUtils/components/triggers/postgres/utils.d.ts +0 -8
  237. package/dist/sharedUtils/components/triggers/sqs/utils.d.ts +0 -2
  238. package/dist/sharedUtils/components/triggers/triggers.svelte.d.ts +0 -32
  239. package/dist/sharedUtils/components/triggers/utils.d.ts +0 -80
  240. package/dist/sharedUtils/components/triggers/websocket/utils.d.ts +0 -2
  241. package/dist/sharedUtils/components/triggers.d.ts +0 -20
  242. package/dist/sharedUtils/gen/core/ApiError.d.ts +0 -10
  243. package/dist/sharedUtils/gen/core/ApiRequestOptions.d.ts +0 -13
  244. package/dist/sharedUtils/gen/core/ApiResult.d.ts +0 -7
  245. package/dist/sharedUtils/gen/core/CancelablePromise.d.ts +0 -26
  246. package/dist/sharedUtils/gen/core/OpenAPI.d.ts +0 -27
  247. package/dist/sharedUtils/gen/core/request.d.ts +0 -29
  248. package/dist/sharedUtils/gen/index.d.ts +0 -6
  249. package/dist/sharedUtils/gen/schemas.gen.d.ts +0 -7036
  250. package/dist/sharedUtils/gen/services.gen.d.ts +0 -6047
  251. package/dist/sharedUtils/gen/types.gen.d.ts +0 -21881
  252. package/dist/sharedUtils/history.svelte.d.ts +0 -9
  253. package/dist/sharedUtils/hub.d.ts +0 -49
  254. package/dist/sharedUtils/jsr.json +0 -6
  255. package/dist/sharedUtils/lib.d.ts +0 -5
  256. package/dist/sharedUtils/lib.es.js +0 -1588
  257. package/dist/sharedUtils/package.json +0 -12
  258. package/dist/sharedUtils/schema.d.ts +0 -3
  259. package/dist/sharedUtils/stores.d.ts +0 -97
  260. package/dist/sharedUtils/svelte5Utils.svelte.d.ts +0 -80
  261. package/dist/sharedUtils/toast.d.ts +0 -8
  262. package/dist/sharedUtils/utils.d.ts +0 -265
  263. package/package/components/copilot/chat/flow/openFlowZod.js +0 -24
  264. /package/package/components/copilot/chat/flow/{openFlowZod.d.ts → openFlowZod.gen.d.ts} +0 -0
@@ -64,7 +64,11 @@ let listener = async (event) => {
64
64
  ? Object.fromEntries(Object.entries(runnable?.fields ?? {})
65
65
  .filter(([k, v]) => v.type == 'static')
66
66
  .map(([k, v]) => [k, v?.['value']]))
67
- : undefined
67
+ : undefined,
68
+ force_viewer_sensitive_inputs: editor
69
+ ? undefinedIfEmpty(Object.keys(runnable?.fields ?? {}).filter((k) => runnable?.fields?.[k]?.type == 'user' && runnable?.fields?.[k]?.sensitive))
70
+ : undefined,
71
+ force_viewer_delete_after_secs: editor ? runnable?.delete_after_secs : undefined
68
72
  }, undefined);
69
73
  let job = { component: runnable_id, created_at: Date.now(), job: uuid };
70
74
  if (event.data.type == 'backendAsync') {
@@ -15,16 +15,72 @@ import RawAppSidebar from './RawAppSidebar.svelte';
15
15
  import { isRunnableByName, isRunnableByPath } from '../apps/inputType';
16
16
  import { aiChatManager, AIMode } from '../copilot/chat/AIChatManager.svelte';
17
17
  import { onMount, untrack } from 'svelte';
18
+ import { createAppSelectedContext } from '../copilot/chat/context';
18
19
  import { rawAppLintStore } from './lintStore';
19
20
  import { dbSchemas } from '../../stores';
20
21
  import { runScriptAndPollResult } from '../jobs/utils';
21
22
  import { RawAppHistoryManager } from './RawAppHistoryManager.svelte';
22
23
  import { sendUserToast } from '../../utils';
23
- import { parseDataTableRef, formatDataTableRef, DEFAULT_DATA } from './dataTableRefUtils';
24
+ import { buildDataTableWhitelist, parseDataTableRef, formatDataTableRef, isDatatableTableAllowed, DEFAULT_DATA } from './dataTableRefUtils';
24
25
  let { files = $bindable({}), runnables = $bindable({}), data = $bindable(DEFAULT_DATA), newApp, policy, summary = $bindable(''), path, newPath = undefined, savedApp = $bindable(undefined), diffDrawer = undefined } = $props();
25
26
  export const version = undefined;
26
27
  // Convert to object format for child components
27
28
  let dataTableRefsObjects = $derived(data.tables.map(parseDataTableRef));
29
+ let dataTableWhitelist = $derived(buildDataTableWhitelist(dataTableRefsObjects));
30
+ function countTables(schemas) {
31
+ return Object.values(schemas).reduce((acc, tables) => acc + tables.length, 0);
32
+ }
33
+ function withTableCount(datatable) {
34
+ return {
35
+ datatable_name: datatable.datatable_name,
36
+ schemas: datatable.schemas,
37
+ tableCount: countTables(datatable.schemas),
38
+ ...(datatable.error && { error: datatable.error })
39
+ };
40
+ }
41
+ function isDatatableTableWhitelisted(datatableName, schemaName, tableName) {
42
+ return isDatatableTableAllowed(dataTableWhitelist, datatableName, schemaName, tableName);
43
+ }
44
+ function filterDatatableTables(allTables) {
45
+ if (dataTableWhitelist.datatables.size === 0) {
46
+ return allTables.map(withTableCount);
47
+ }
48
+ const results = [];
49
+ for (const datatable of allTables) {
50
+ if (!dataTableWhitelist.datatables.has(datatable.datatable_name)) {
51
+ continue;
52
+ }
53
+ if (dataTableWhitelist.allTablesDatatables.has(datatable.datatable_name)) {
54
+ results.push(withTableCount(datatable));
55
+ continue;
56
+ }
57
+ const allowedTables = dataTableWhitelist.tables.get(datatable.datatable_name);
58
+ if (!allowedTables) {
59
+ results.push(withTableCount({
60
+ datatable_name: datatable.datatable_name,
61
+ schemas: {},
62
+ error: datatable.error
63
+ }));
64
+ continue;
65
+ }
66
+ const filteredSchemas = {};
67
+ for (const [schemaName, tableNames] of Object.entries(datatable.schemas)) {
68
+ const allowedTablesInSchema = allowedTables.get(schemaName);
69
+ if (!allowedTablesInSchema)
70
+ continue;
71
+ const filteredTables = tableNames.filter((tableName) => allowedTablesInSchema.has(tableName));
72
+ if (filteredTables.length > 0) {
73
+ filteredSchemas[schemaName] = filteredTables;
74
+ }
75
+ }
76
+ results.push(withTableCount({
77
+ datatable_name: datatable.datatable_name,
78
+ schemas: filteredSchemas,
79
+ error: datatable.error
80
+ }));
81
+ }
82
+ return results;
83
+ }
28
84
  // Initialize history manager
29
85
  const historyManager = new RawAppHistoryManager({
30
86
  maxEntries: 50,
@@ -118,13 +174,52 @@ function convertToBackendRunnable(key, runnable) {
118
174
  return backendRunnable;
119
175
  }
120
176
  let iframeLoaded = $state(false); // @hmr:keep
177
+ // Suppresses iframe-sourced events for a short window after we re-push files,
178
+ // to keep the iframe's boot-time messages from clobbering the user's state.
179
+ // suppressIframeSetFiles is held across an entire iframe reload (e.g. theme switch);
180
+ // the timer is reset on every reload so rapid toggles don't clear it prematurely.
121
181
  let suppressSetActiveDocument = false;
182
+ let suppressIframeSetFiles = false;
183
+ let suppressTimer;
184
+ let sharedUiFiles = $state({});
185
+ let sharedUiVersion = $state(0);
186
+ let sharedUiLoaded = $state(false);
187
+ async function loadSharedUi() {
188
+ if (!$workspaceStore)
189
+ return;
190
+ try {
191
+ const res = (await WorkspaceService.getSharedUi({
192
+ workspace: $workspaceStore
193
+ }));
194
+ sharedUiFiles = res.files ?? {};
195
+ sharedUiVersion = res.version ?? 0;
196
+ }
197
+ catch (e) {
198
+ console.warn('Failed to load shared UI for raw app editor:', e);
199
+ sharedUiFiles = {};
200
+ }
201
+ finally {
202
+ sharedUiLoaded = true;
203
+ }
204
+ }
205
+ function setSharedUiInIframe() {
206
+ const filesSnap = $state.snapshot(sharedUiFiles);
207
+ iframe?.contentWindow?.postMessage({
208
+ type: 'setSharedUi',
209
+ files: filesSnap,
210
+ version: sharedUiVersion
211
+ }, '*');
212
+ }
122
213
  function populateFiles() {
123
214
  if (files) {
124
- // Suppress iframe's automatic setActiveDocument for a short window
125
- // after sending files, to prevent it from resetting to App.tsx.
126
215
  suppressSetActiveDocument = true;
127
- setTimeout(() => { suppressSetActiveDocument = false; }, 500);
216
+ if (suppressTimer !== undefined)
217
+ clearTimeout(suppressTimer);
218
+ suppressTimer = setTimeout(() => {
219
+ suppressSetActiveDocument = false;
220
+ suppressIframeSetFiles = false;
221
+ suppressTimer = undefined;
222
+ }, 500);
128
223
  const doc = untrack(() => selectedDocument);
129
224
  if (doc) {
130
225
  setFilesAndSelectInIframe(files, doc);
@@ -159,6 +254,7 @@ onMount(() => {
159
254
  aiChatManager.saveAndClear();
160
255
  aiChatManager.changeMode(AIMode.APP);
161
256
  rawAppLintStore.enable();
257
+ loadSharedUi();
162
258
  // Initialize aiChatManager.datatableCreationPolicy from stored data
163
259
  aiChatManager.datatableCreationPolicy = {
164
260
  enabled: data.datatable !== undefined,
@@ -322,38 +418,14 @@ $effect(() => {
322
418
  };
323
419
  },
324
420
  getSelectedContext: () => {
325
- const baseContext = {
421
+ return createAppSelectedContext({
326
422
  inspectorElement: inspectorElement,
327
- selectionExcluded: selectionExcludedFromPrompt,
328
- toggleSelectionExcluded: toggleSelectionExcluded,
329
423
  clearInspector: clearInspectorSelection,
330
- clearRunnable: handleClearRunnable,
331
424
  codeSelection: codeSelection,
332
425
  clearCodeSelection: () => {
333
426
  codeSelection = undefined;
334
427
  }
335
- };
336
- if (selectedRunnable) {
337
- const runnable = convertToBackendRunnable(selectedRunnable, runnables[selectedRunnable]);
338
- return {
339
- type: 'backend',
340
- backendKey: selectedRunnable,
341
- backendRunnable: runnable,
342
- ...baseContext
343
- };
344
- }
345
- if (selectedDocument) {
346
- return {
347
- type: 'frontend',
348
- frontendPath: selectedDocument,
349
- frontendContent: files?.[selectedDocument],
350
- ...baseContext
351
- };
352
- }
353
- return {
354
- type: 'none',
355
- ...baseContext
356
- };
428
+ });
357
429
  },
358
430
  snapshot: () => {
359
431
  // Force create snapshot for AI - it needs a restore point
@@ -364,79 +436,38 @@ $effect(() => {
364
436
  console.log('reverting to snapshot', id);
365
437
  handleHistorySelect(id);
366
438
  },
367
- getDatatables: async () => {
439
+ listDatatableTables: async () => {
368
440
  if (!$workspaceStore) {
369
441
  return [];
370
442
  }
371
- // Get all datatable schemas from the backend
372
- const allSchemas = await WorkspaceService.listDataTableSchemas({
443
+ const tables = await WorkspaceService.listDataTableTables({
373
444
  workspace: $workspaceStore
374
445
  });
375
- // Get unique datatable names from dataTableRefs (the whitelisted tables)
376
- const whitelistedDatatables = new Set(dataTableRefsObjects.map((ref) => ref.datatable));
377
- // If no datatables are configured, return all available datatables
378
- // This allows users to see all datatables in the @ context menu
379
- if (whitelistedDatatables.size === 0) {
380
- return allSchemas;
381
- }
382
- // Build a map of whitelisted tables per datatable: datatable -> schema -> Set<table>
383
- const whitelistedTables = new Map();
384
- for (const ref of dataTableRefsObjects) {
385
- if (!ref.table)
386
- continue;
387
- if (!whitelistedTables.has(ref.datatable)) {
388
- whitelistedTables.set(ref.datatable, new Map());
389
- }
390
- const schemaKey = ref.schema || 'public';
391
- const schemaMap = whitelistedTables.get(ref.datatable);
392
- if (!schemaMap.has(schemaKey)) {
393
- schemaMap.set(schemaKey, new Set());
394
- }
395
- schemaMap.get(schemaKey).add(ref.table);
446
+ return filterDatatableTables(tables);
447
+ },
448
+ getDatatableTableSchema: async (datatableName, schemaName, tableName) => {
449
+ if (!$workspaceStore) {
450
+ return {};
396
451
  }
397
- // Filter schemas to only include whitelisted datatables and tables
398
- const results = [];
399
- for (const schema of allSchemas) {
400
- if (!whitelistedDatatables.has(schema.datatable_name)) {
401
- continue;
402
- }
403
- const allowedTables = whitelistedTables.get(schema.datatable_name);
404
- if (!allowedTables) {
405
- // Include the datatable but with empty schemas
406
- results.push({
407
- datatable_name: schema.datatable_name,
408
- schemas: {},
409
- error: schema.error
410
- });
411
- continue;
412
- }
413
- // Filter schemas to only include whitelisted tables
414
- const filteredSchemas = {};
415
- for (const [schemaName, tables] of Object.entries(schema.schemas)) {
416
- const allowedTablesInSchema = allowedTables.get(schemaName);
417
- if (!allowedTablesInSchema)
418
- continue;
419
- const filteredTables = {};
420
- for (const [tableName, columns] of Object.entries(tables)) {
421
- if (allowedTablesInSchema.has(tableName)) {
422
- filteredTables[tableName] = columns;
423
- }
424
- }
425
- if (Object.keys(filteredTables).length > 0) {
426
- filteredSchemas[schemaName] = filteredTables;
427
- }
428
- }
429
- results.push({
430
- datatable_name: schema.datatable_name,
431
- schemas: filteredSchemas,
432
- error: schema.error
452
+ if (!isDatatableTableWhitelisted(datatableName, schemaName, tableName)) {
453
+ const tableRef = formatDataTableRef({
454
+ datatable: datatableName,
455
+ schema: schemaName === 'public' ? undefined : schemaName,
456
+ table: tableName
433
457
  });
458
+ throw new Error(`Table '${tableRef}' is not configured in this app`);
434
459
  }
435
- return results;
460
+ const schema = await WorkspaceService.getDataTableTableSchema({
461
+ workspace: $workspaceStore,
462
+ datatableName,
463
+ schemaName,
464
+ tableName
465
+ });
466
+ return schema.columns;
436
467
  },
437
468
  getAvailableDatatableNames: () => {
438
469
  // Get unique datatable names from dataTableRefs
439
- return [...new Set(dataTableRefsObjects.map((ref) => ref.datatable))];
470
+ return [...dataTableWhitelist.datatables];
440
471
  },
441
472
  execDatatableSql: async (datatableName, sql, newTable) => {
442
473
  if (!$workspaceStore) {
@@ -467,6 +498,7 @@ $effect(() => {
467
498
  delete $dbSchemas[resourcePath];
468
499
  }
469
500
  }
501
+ void aiChatManager.refreshDatatables();
470
502
  // Check if result is an array (SELECT) or something else
471
503
  if (Array.isArray(result)) {
472
504
  return { success: true, result };
@@ -491,6 +523,7 @@ $effect(() => {
491
523
  if (!data.tables.includes(newRef)) {
492
524
  data.tables = [...data.tables, newRef];
493
525
  saveFrontendDraft();
526
+ void aiChatManager.refreshDatatables();
494
527
  }
495
528
  }
496
529
  });
@@ -498,11 +531,7 @@ $effect(() => {
498
531
  let selectedRunnable = $state(undefined);
499
532
  let selectedDocument = $state(undefined);
500
533
  let inspectorElement = $state(undefined);
501
- let selectionExcludedFromPrompt = $state(false);
502
534
  let codeSelection = $state(undefined);
503
- function toggleSelectionExcluded() {
504
- selectionExcludedFromPrompt = !selectionExcludedFromPrompt;
505
- }
506
535
  let modules = $state({});
507
536
  // Normalize Windows-style path separators to Linux-style
508
537
  function normalizeFilePaths(filesObj) {
@@ -512,6 +541,10 @@ function normalizeFilePaths(filesObj) {
512
541
  }
513
542
  function listener(e) {
514
543
  if (e.data.type === 'setFiles') {
544
+ // Ignore setFiles from the iframe while it's reloading (e.g. theme switch);
545
+ // the iframe boots with its default template and would otherwise clobber the user's files.
546
+ if (suppressIframeSetFiles)
547
+ return;
515
548
  // Normalize Windows-style path separators to Linux-style
516
549
  const normalizedFiles = normalizeFilePaths(e.data.files);
517
550
  // Only mark pending changes if files actually changed (ignore echo from setFilesInIframe)
@@ -582,12 +615,41 @@ $effect(() => {
582
615
  iframeLoaded = true;
583
616
  });
584
617
  });
618
+ $effect(() => {
619
+ // Toggling dark mode changes the iframe src, causing it to reload.
620
+ // Reset iframeLoaded so the populate effect refires after the new load,
621
+ // and suppress the iframe's initial setFiles (default template) until then.
622
+ void darkMode;
623
+ untrack(() => {
624
+ if (iframe && iframeLoaded) {
625
+ iframeLoaded = false;
626
+ suppressIframeSetFiles = true;
627
+ // Cancel any pending clear from a prior reload — otherwise on rapid
628
+ // toggles the previous timer can fire mid-reload and drop suppression
629
+ // before the iframe has finished booting.
630
+ if (suppressTimer !== undefined) {
631
+ clearTimeout(suppressTimer);
632
+ suppressTimer = undefined;
633
+ }
634
+ }
635
+ });
636
+ });
585
637
  $effect(() => {
586
638
  iframe && iframeLoaded && files && populateFiles();
587
639
  });
588
640
  $effect(() => {
589
641
  iframe && iframeLoaded && runnables && populateRunnables();
590
642
  });
643
+ $effect(() => {
644
+ // Re-push the shared UI whenever the iframe (re)loads or the
645
+ // fetched files change. We gate on `sharedUiLoaded` so the empty
646
+ // initial state isn't sent before the API call resolves.
647
+ if (iframe && iframeLoaded && sharedUiLoaded) {
648
+ // Touch the version so reassignments after a refresh re-fire this.
649
+ void sharedUiVersion;
650
+ untrack(() => setSharedUiInIframe());
651
+ }
652
+ });
591
653
  function clearInspectorSelection() {
592
654
  inspectorElement = undefined;
593
655
  iframe?.contentWindow?.postMessage({ type: 'inspectorClear' }, '*');
@@ -601,21 +663,16 @@ function handleSelectFile(path) {
601
663
  path: path
602
664
  }, '*');
603
665
  }
604
- function handleClearRunnable() {
605
- selectedRunnable = undefined;
606
- }
607
666
  // Track previous values for change detection
608
667
  let prevSelectedRunnable = undefined;
609
668
  let prevSelectedDocument = undefined;
610
- // Clear inspector and reset exclusion when selection changes
669
+ // Clear inspector when selection changes
611
670
  $effect(() => {
612
671
  if (selectedRunnable !== prevSelectedRunnable || selectedDocument !== prevSelectedDocument) {
613
672
  // Only clear if we're actually switching to something different
614
673
  if (prevSelectedRunnable !== undefined || prevSelectedDocument !== undefined) {
615
674
  clearInspectorSelection();
616
675
  }
617
- // Reset exclusion when switching files/runnables
618
- selectionExcludedFromPrompt = false;
619
676
  prevSelectedRunnable = selectedRunnable;
620
677
  prevSelectedDocument = selectedDocument;
621
678
  }
@@ -10,6 +10,8 @@ import { emptySchema, getLocalSetting, sendUserToast, storeLocalSetting } from '
10
10
  import { scriptLangToEditorLang } from '../../scripts';
11
11
  import DiffEditor from '../DiffEditor.svelte';
12
12
  import CacheTtlPopup from '../apps/editor/inlineScriptsPanel/CacheTtlPopup.svelte';
13
+ import TagPopup from '../apps/editor/inlineScriptsPanel/TagPopup.svelte';
14
+ import DeleteAfterUsePopup from './DeleteAfterUsePopup.svelte';
13
15
  import { computeFields } from '../apps/editor/inlineScriptsPanel/utils';
14
16
  import EditorBar from '../EditorBar.svelte';
15
17
  import { LanguageIcon } from '../common/languageIcons';
@@ -22,7 +24,7 @@ import { Pane, Splitpanes } from 'svelte-splitpanes';
22
24
  import { editor as meditor } from 'monaco-editor';
23
25
  import { DebugConsole, getDAPClient, debugState, resetDAPClient, getDebugServerUrl, isDebuggable, getDebugFileExtension, fetchContextualVariables, signDebugRequest, getDebugErrorMessage } from '../debug';
24
26
  import TextInput from '../text_input/TextInput.svelte';
25
- let { inlineScript = $bindable(), name = $bindable(undefined), id, fields = $bindable(undefined), path, onRun, editor = $bindable(undefined), lastDeployedCode, onSelectionChange } = $props();
27
+ let { inlineScript = $bindable(), name = $bindable(undefined), id, fields = $bindable(undefined), path, onRun, editor = $bindable(undefined), lastDeployedCode, onSelectionChange, delete_after_secs = $bindable() } = $props();
26
28
  let diffEditor = $state();
27
29
  let validCode = $state(true);
28
30
  async function inferInlineScriptSchema(language, content, schema) {
@@ -74,8 +76,10 @@ let width = $state(0);
74
76
  let inferAssetsRes = resource([() => inlineScript?.language, () => inlineScript?.content], async () => inlineScript && inferAssets(inlineScript.language, inlineScript.content));
75
77
  let preparedSqlQueries = usePreparedAssetSqlQueries(() => inferAssetsRes.current?.sql_queries, () => $workspaceStore);
76
78
  $effect(() => {
77
- if (inlineScript && inferAssetsRes.current)
78
- inlineScript.assets = inferAssetsRes.current?.assets;
79
+ if (!inlineScript || !inferAssetsRes.current || inferAssetsRes.current.status === 'error')
80
+ return;
81
+ const newAssets = inferAssetsRes.current.assets;
82
+ inlineScript.assets = newAssets.length > 0 ? newAssets : undefined;
79
83
  });
80
84
  // Debug mode state
81
85
  const DEBUG_BETA_WARNING_KEY = 'debug_beta_warning_confirmed';
@@ -500,8 +504,10 @@ $effect(() => {
500
504
  {/if}
501
505
  <div class="flex w-full flex-row gap-2 items-center justify-end">
502
506
  {#if inlineScript}
507
+ <TagPopup bind:tag={inlineScript.tag} />
503
508
  <CacheTtlPopup bind:cache_ttl={inlineScript.cache_ttl} />
504
509
  {/if}
510
+ <DeleteAfterUsePopup bind:delete_after_secs />
505
511
 
506
512
  <Button
507
513
  variant="default"
@@ -12,6 +12,7 @@ interface Props {
12
12
  onRun: () => Promise<void>;
13
13
  editor?: any | undefined;
14
14
  lastDeployedCode?: string | undefined;
15
+ delete_after_secs?: number | undefined;
15
16
  /** Called when code is selected in the editor */
16
17
  onSelectionChange?: (selection: {
17
18
  content: string;
@@ -57,6 +58,6 @@ declare const RawAppInlineScriptEditor: $$__sveltets_2_IsomorphicComponent<Props
57
58
  stepOut: () => Promise<void>;
58
59
  clearAllBreakpoints: () => void;
59
60
  toggleDebugMode: () => void;
60
- }, "name" | "fields" | "inlineScript" | "editor">;
61
+ }, "name" | "fields" | "inlineScript" | "delete_after_secs" | "editor">;
61
62
  type RawAppInlineScriptEditor = InstanceType<typeof RawAppInlineScriptEditor>;
62
63
  export default RawAppInlineScriptEditor;
@@ -156,6 +156,7 @@ $effect(() => {
156
156
  bind:inlineScript={runnable.inlineScript}
157
157
  bind:name={runnable.name}
158
158
  bind:fields={runnable.fields}
159
+ bind:delete_after_secs={runnable.delete_after_secs}
159
160
  onRun={testPreview}
160
161
  on:delete
161
162
  path={appPath}
@@ -4,6 +4,7 @@ type RunnableWithInlineScript = RunnableWithFields & {
4
4
  inlineScript?: InlineScript & {
5
5
  language: ScriptLang;
6
6
  };
7
+ delete_after_secs?: number;
7
8
  };
8
9
  export type Runnable = RunnableWithInlineScript | undefined;
9
10
  interface Props {
@@ -3,7 +3,7 @@ import { addWhitespaceBeforeCapitals, capitalize, classNames } from '../../utils
3
3
  import Tooltip from '../Tooltip.svelte';
4
4
  import ToggleButtonGroup from '../common/toggleButton-v2/ToggleButtonGroup.svelte';
5
5
  import ToggleButton from '../common/toggleButton-v2/ToggleButton.svelte';
6
- import { Loader2, Pen, User, Shield } from 'lucide-svelte';
6
+ import { Loader2, Pen, User, Shield, Lock } from 'lucide-svelte';
7
7
  import Toggle from '../Toggle.svelte';
8
8
  import StaticInputEditor from '../apps/editor/settingsPanel/inputEditor/StaticInputEditor.svelte';
9
9
  import { fieldTypeToTsType } from '../apps/utils';
@@ -11,10 +11,22 @@ import Select from '../select/Select.svelte';
11
11
  import { userStore, workspaceStore } from '../../stores';
12
12
  // Build ctx properties with current user's actual values
13
13
  let ctxProperties = $derived([
14
- { value: 'username', label: 'Username', subtitle: `string — "${$userStore?.username ?? 'unknown'}"` },
14
+ {
15
+ value: 'username',
16
+ label: 'Username',
17
+ subtitle: `string — "${$userStore?.username ?? 'unknown'}"`
18
+ },
15
19
  { value: 'email', label: 'Email', subtitle: `string — "${$userStore?.email ?? 'unknown'}"` },
16
- { value: 'groups', label: 'Groups', subtitle: `string[] — ${JSON.stringify($userStore?.groups ?? [])}` },
17
- { value: 'workspace', label: 'Workspace', subtitle: `string — "${$workspaceStore ?? 'unknown'}"` },
20
+ {
21
+ value: 'groups',
22
+ label: 'Groups',
23
+ subtitle: `string[] — ${JSON.stringify($userStore?.groups ?? [])}`
24
+ },
25
+ {
26
+ value: 'workspace',
27
+ label: 'Workspace',
28
+ subtitle: `string — "${$workspaceStore ?? 'unknown'}"`
29
+ },
18
30
  { value: 'author', label: 'Author', subtitle: `string — "${$userStore?.email ?? 'unknown'}"` }
19
31
  ]);
20
32
  let { id, componentInput = $bindable(), key, shouldCapitalize = true, resourceOnly = false, tooltip = undefined, fieldType, subFieldType, format, selectOptions, placeholder, customTitle = undefined, displayType = false, allowTypeChange = true, loading = false, documentationLink = undefined } = $props();
@@ -83,7 +95,13 @@ run(() => {
83
95
  {#snippet children({ item })}
84
96
  <ToggleButton {item} value="user" icon={User} iconOnly tooltip="User Input" />
85
97
  <ToggleButton {item} value="static" icon={Pen} iconOnly tooltip="Static" />
86
- <ToggleButton {item} value="ctx" icon={Shield} iconOnly tooltip="Context (secure backend value)" />
98
+ <ToggleButton
99
+ {item}
100
+ value="ctx"
101
+ icon={Shield}
102
+ iconOnly
103
+ tooltip="Context (secure backend value)"
104
+ />
87
105
  {/snippet}
88
106
  </ToggleButtonGroup>
89
107
  {/if}
@@ -135,5 +153,30 @@ run(() => {
135
153
  >
136
154
  </div>
137
155
  {/if}
156
+ {#if componentInput?.type === 'user'}
157
+ <div class="flex flex-row items-center gap-1">
158
+ <Toggle
159
+ size="xs"
160
+ checked={Boolean(componentInput.sensitive)}
161
+ on:change={(e) => {
162
+ if (e.detail) {
163
+ componentInput.sensitive = true
164
+ } else {
165
+ delete componentInput.sensitive
166
+ }
167
+ }}
168
+ textClass="!text-tertiary"
169
+ options={{
170
+ right: 'sensitive'
171
+ }}
172
+ />
173
+ <Lock size={12} class="text-tertiary" />
174
+ <Tooltip
175
+ >The value is encrypted before being stored in the job's args, so it is not exposed in
176
+ plaintext to anyone with read access to the job. The script still receives the decrypted
177
+ value at runtime.</Tooltip
178
+ >
179
+ </div>
180
+ {/if}
138
181
  </div>
139
182
  {/if}