Flowfile 0.3.4.1__py3-none-any.whl → 0.3.6__py3-none-any.whl

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.

Potentially problematic release.


This version of Flowfile might be problematic. Click here for more details.

Files changed (122) hide show
  1. flowfile/__init__.py +3 -3
  2. flowfile/api.py +36 -15
  3. flowfile/web/static/assets/CloudConnectionManager-2dfdce2f.css +86 -0
  4. flowfile/web/static/assets/CloudConnectionManager-d004942f.js +784 -0
  5. flowfile/web/static/assets/CloudStorageReader-29d14fcc.css +143 -0
  6. flowfile/web/static/assets/CloudStorageReader-eccf9fc2.js +437 -0
  7. flowfile/web/static/assets/CloudStorageWriter-49c9a4b2.css +138 -0
  8. flowfile/web/static/assets/CloudStorageWriter-b1ba6bba.js +430 -0
  9. flowfile/web/static/assets/{CrossJoin-dfcf7351.js → CrossJoin-68981877.js} +8 -8
  10. flowfile/web/static/assets/{DatabaseConnectionSettings-b2afb1d7.js → DatabaseConnectionSettings-0b06649c.js} +2 -2
  11. flowfile/web/static/assets/{DatabaseManager-824a49b2.js → DatabaseManager-8349a426.js} +2 -2
  12. flowfile/web/static/assets/{DatabaseReader-a48124d8.js → DatabaseReader-905344f8.js} +9 -9
  13. flowfile/web/static/assets/{DatabaseWriter-b47cbae2.js → DatabaseWriter-9f5b8638.js} +9 -9
  14. flowfile/web/static/assets/{ExploreData-fdfc45a4.js → ExploreData-131a6d53.js} +5 -5
  15. flowfile/web/static/assets/{ExternalSource-861b0e71.js → ExternalSource-e3549dcc.js} +6 -6
  16. flowfile/web/static/assets/{Filter-f87bb897.js → Filter-6e0730ae.js} +8 -8
  17. flowfile/web/static/assets/{Formula-1e2ed720.js → Formula-02f033e6.js} +75 -9
  18. flowfile/web/static/assets/{Formula-b8cefc31.css → Formula-29f19d21.css} +10 -0
  19. flowfile/web/static/assets/{FuzzyMatch-b6cc4fdd.js → FuzzyMatch-54c14036.js} +9 -9
  20. flowfile/web/static/assets/{GraphSolver-6a371f4c.js → GraphSolver-08a3f499.js} +5 -5
  21. flowfile/web/static/assets/{GroupBy-f7b7f472.js → GroupBy-2ae38139.js} +6 -6
  22. flowfile/web/static/assets/{Join-eec38203.js → Join-493b9772.js} +23 -15
  23. flowfile/web/static/assets/{Join-41c0f331.css → Join-f45eff22.css} +20 -20
  24. flowfile/web/static/assets/{ManualInput-9aaa46fb.js → ManualInput-4373d163.js} +106 -34
  25. flowfile/web/static/assets/{ManualInput-ac7b9972.css → ManualInput-a71b52c6.css} +29 -17
  26. flowfile/web/static/assets/{Output-3b2ca045.js → Output-b534f3c7.js} +4 -4
  27. flowfile/web/static/assets/{Pivot-a4f5d88f.js → Pivot-2968ff65.js} +6 -6
  28. flowfile/web/static/assets/{PolarsCode-49ce444f.js → PolarsCode-65136536.js} +6 -6
  29. flowfile/web/static/assets/{Read-07acdc9a.js → Read-c56339ed.js} +6 -6
  30. flowfile/web/static/assets/{RecordCount-6a21da56.js → RecordCount-1c641a5e.js} +5 -5
  31. flowfile/web/static/assets/{RecordId-949bdc17.js → RecordId-df308b8f.js} +6 -6
  32. flowfile/web/static/assets/{Sample-7afca6e1.js → Sample-293e8a64.js} +5 -5
  33. flowfile/web/static/assets/{SecretManager-b41c029d.js → SecretManager-03911655.js} +2 -2
  34. flowfile/web/static/assets/{Select-32b28406.js → Select-3058a13d.js} +8 -8
  35. flowfile/web/static/assets/{SettingsSection-a0f15a05.js → SettingsSection-fbf4fb39.js} +1 -1
  36. flowfile/web/static/assets/{Sort-fc6ba0e2.js → Sort-a29bbaf7.js} +6 -6
  37. flowfile/web/static/assets/{TextToRows-23127596.js → TextToRows-c7d7760e.js} +8 -8
  38. flowfile/web/static/assets/{UnavailableFields-c42880a3.js → UnavailableFields-118f1d20.js} +2 -2
  39. flowfile/web/static/assets/{Union-39eecc6c.js → Union-f0589571.js} +5 -5
  40. flowfile/web/static/assets/{Unique-a0e8fe61.js → Unique-7329a207.js} +8 -8
  41. flowfile/web/static/assets/{Unpivot-1e2d43f0.js → Unpivot-30b0be15.js} +5 -5
  42. flowfile/web/static/assets/{api-44ca9e9c.js → api-602fb95c.js} +1 -1
  43. flowfile/web/static/assets/api-fb67319c.js +80 -0
  44. flowfile/web/static/assets/cloud_storage_reader-aa1415d6.png +0 -0
  45. flowfile/web/static/assets/{designer-267d44f1.js → designer-94a6bf4d.js} +36 -34
  46. flowfile/web/static/assets/{documentation-6c0810a2.js → documentation-a224831e.js} +1 -1
  47. flowfile/web/static/assets/{dropDown-52790b15.js → dropDown-c2d2aa97.js} +1 -1
  48. flowfile/web/static/assets/{fullEditor-e272b506.js → fullEditor-921ac5fd.js} +2 -2
  49. flowfile/web/static/assets/{genericNodeSettings-4bdcf98e.js → genericNodeSettings-7013cc94.js} +3 -3
  50. flowfile/web/static/assets/{index-e235a8bc.js → index-3a75211d.js} +19 -6
  51. flowfile/web/static/assets/{nodeTitle-fc3fc4b7.js → nodeTitle-a63d4680.js} +3 -3
  52. flowfile/web/static/assets/{secretApi-cdc2a3fd.js → secretApi-763aec6e.js} +1 -1
  53. flowfile/web/static/assets/{selectDynamic-96aa82cd.js → selectDynamic-08464729.js} +3 -3
  54. flowfile/web/static/assets/{vue-codemirror.esm-25e75a08.js → vue-codemirror.esm-f15a5f87.js} +2 -1
  55. flowfile/web/static/assets/{vue-content-loader.es-6c4b1c24.js → vue-content-loader.es-93bd09d7.js} +1 -1
  56. flowfile/web/static/index.html +1 -1
  57. {flowfile-0.3.4.1.dist-info → flowfile-0.3.6.dist-info}/METADATA +8 -3
  58. {flowfile-0.3.4.1.dist-info → flowfile-0.3.6.dist-info}/RECORD +109 -104
  59. {flowfile-0.3.4.1.dist-info → flowfile-0.3.6.dist-info}/entry_points.txt +2 -0
  60. flowfile_core/__init__.py +2 -0
  61. flowfile_core/configs/node_store/nodes.py +8 -6
  62. flowfile_core/database/connection.py +63 -15
  63. flowfile_core/database/init_db.py +0 -1
  64. flowfile_core/database/models.py +49 -2
  65. flowfile_core/flowfile/code_generator/code_generator.py +402 -18
  66. flowfile_core/flowfile/connection_manager/models.py +1 -1
  67. flowfile_core/flowfile/database_connection_manager/db_connections.py +216 -2
  68. flowfile_core/flowfile/extensions.py +1 -1
  69. flowfile_core/flowfile/flow_data_engine/cloud_storage_reader.py +259 -0
  70. flowfile_core/flowfile/flow_data_engine/create/funcs.py +19 -8
  71. flowfile_core/flowfile/flow_data_engine/flow_data_engine.py +522 -59
  72. flowfile_core/flowfile/flow_data_engine/flow_file_column/main.py +12 -2
  73. flowfile_core/flowfile/flow_data_engine/fuzzy_matching/settings_validator.py +1 -1
  74. flowfile_core/flowfile/flow_data_engine/join/__init__.py +2 -1
  75. flowfile_core/flowfile/flow_data_engine/join/utils.py +25 -0
  76. flowfile_core/flowfile/flow_data_engine/subprocess_operations/subprocess_operations.py +29 -22
  77. flowfile_core/flowfile/flow_data_engine/utils.py +1 -40
  78. flowfile_core/flowfile/flow_graph.py +119 -82
  79. flowfile_core/flowfile/flow_node/flow_node.py +68 -33
  80. flowfile_core/flowfile/flow_node/models.py +32 -3
  81. flowfile_core/flowfile/flow_node/schema_callback.py +3 -2
  82. flowfile_core/flowfile/sources/external_sources/__init__.py +0 -2
  83. flowfile_core/flowfile/sources/external_sources/factory.py +4 -7
  84. flowfile_core/flowfile/utils.py +1 -23
  85. flowfile_core/main.py +3 -2
  86. flowfile_core/routes/cloud_connections.py +81 -0
  87. flowfile_core/routes/logs.py +0 -1
  88. flowfile_core/routes/routes.py +3 -39
  89. flowfile_core/schemas/cloud_storage_schemas.py +215 -0
  90. flowfile_core/schemas/input_schema.py +37 -15
  91. flowfile_core/schemas/schemas.py +7 -2
  92. flowfile_core/schemas/transform_schema.py +97 -22
  93. flowfile_core/utils/utils.py +40 -1
  94. flowfile_core/utils/validate_setup.py +41 -0
  95. flowfile_frame/flow_frame.py +253 -102
  96. flowfile_frame/flow_frame_methods.py +13 -13
  97. flowfile_worker/external_sources/s3_source/main.py +216 -0
  98. flowfile_worker/external_sources/s3_source/models.py +142 -0
  99. flowfile_worker/funcs.py +51 -6
  100. flowfile_worker/models.py +22 -2
  101. flowfile_worker/routes.py +40 -38
  102. flowfile_worker/utils.py +1 -1
  103. test_utils/s3/commands.py +46 -0
  104. test_utils/s3/data_generator.py +291 -0
  105. test_utils/s3/fixtures.py +209 -0
  106. flowfile/web/static/assets/AirbyteReader-1ac35765.css +0 -314
  107. flowfile/web/static/assets/AirbyteReader-e08044e5.js +0 -922
  108. flowfile/web/static/assets/dropDownGeneric-60f56a8a.js +0 -72
  109. flowfile/web/static/assets/dropDownGeneric-895680d6.css +0 -10
  110. flowfile_core/flowfile/sources/external_sources/airbyte_sources/airbyte.py +0 -159
  111. flowfile_core/flowfile/sources/external_sources/airbyte_sources/models.py +0 -172
  112. flowfile_core/flowfile/sources/external_sources/airbyte_sources/settings.py +0 -173
  113. flowfile_core/schemas/external_sources/airbyte_schemas.py +0 -20
  114. flowfile_worker/external_sources/airbyte_sources/__init__.py +0 -0
  115. flowfile_worker/external_sources/airbyte_sources/cache_manager.py +0 -161
  116. flowfile_worker/external_sources/airbyte_sources/main.py +0 -89
  117. flowfile_worker/external_sources/airbyte_sources/models.py +0 -133
  118. flowfile_worker/external_sources/airbyte_sources/settings.py +0 -0
  119. {flowfile-0.3.4.1.dist-info → flowfile-0.3.6.dist-info}/LICENSE +0 -0
  120. {flowfile-0.3.4.1.dist-info → flowfile-0.3.6.dist-info}/WHEEL +0 -0
  121. {flowfile_core/flowfile/sources/external_sources/airbyte_sources → flowfile_worker/external_sources/s3_source}/__init__.py +0 -0
  122. {flowfile_core/schemas/external_sources → test_utils/s3}/__init__.py +0 -0
@@ -0,0 +1,138 @@
1
+
2
+ /* Copied styles from the reader component for consistency */
3
+ .cloud-storage-container[data-v-55743049] {
4
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
5
+ max-width: 100%;
6
+ color: #333;
7
+ }
8
+ .section-subtitle[data-v-55743049] {
9
+ margin: 0 0 0.75rem 0;
10
+ font-size: 0.95rem;
11
+ font-weight: 600;
12
+ color: #4a5568;
13
+ }
14
+ .subsection-title[data-v-55743049] {
15
+ margin: 0.5rem 0 0.5rem 0;
16
+ font-size: 0.875rem;
17
+ font-weight: 600;
18
+ color: #718096;
19
+ }
20
+ .format-options[data-v-55743049] {
21
+ margin-top: 1rem;
22
+ padding: 1rem;
23
+ background-color: #f7fafc;
24
+ border-radius: 4px;
25
+ border: 1px solid #e2e8f0;
26
+ }
27
+ .form-row[data-v-55743049] {
28
+ display: flex;
29
+ gap: 0.75rem;
30
+ margin-bottom: 0.75rem;
31
+ width: 100%;
32
+ box-sizing: border-box;
33
+ }
34
+ .half[data-v-55743049] {
35
+ flex: 1;
36
+ min-width: 0;
37
+ max-width: calc(50% - 0.375rem);
38
+ }
39
+ .form-control[data-v-55743049] {
40
+ width: 100%;
41
+ padding: 0.5rem;
42
+ border: 1px solid #e2e8f0;
43
+ border-radius: 4px;
44
+ font-size: 0.875rem;
45
+ box-sizing: border-box;
46
+ }
47
+ .form-group[data-v-55743049] {
48
+ margin-bottom: 0.75rem;
49
+ width: 100%;
50
+ }
51
+ label[data-v-55743049] {
52
+ display: block;
53
+ margin-bottom: 0.25rem;
54
+ font-size: 0.875rem;
55
+ font-weight: 500;
56
+ color: #4a5568;
57
+ }
58
+ select.form-control[data-v-55743049] {
59
+ appearance: none;
60
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%234a5568' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
61
+ background-repeat: no-repeat;
62
+ background-position: right 0.5rem center;
63
+ background-size: 1em;
64
+ padding-right: 2rem;
65
+ }
66
+ .info-box[data-v-55743049] {
67
+ display: flex;
68
+ gap: 0.75rem;
69
+ padding: 0.75rem;
70
+ background-color: #e6f7ff;
71
+ border-left: 4px solid #1890ff;
72
+ border-radius: 4px;
73
+ margin-top: 1rem;
74
+ font-size: 0.875rem;
75
+ }
76
+ .info-box.info-warn[data-v-55743049] {
77
+ background-color: #fffbe6;
78
+ border-left-color: #faad14;
79
+ }
80
+ .info-box.info-warn i[data-v-55743049] {
81
+ color: #faad14;
82
+ }
83
+ .info-box i[data-v-55743049] {
84
+ color: #1890ff;
85
+ font-size: 1.25rem;
86
+ flex-shrink: 0;
87
+ padding-top: 2px;
88
+ }
89
+ .info-box p[data-v-55743049] {
90
+ margin: 0;
91
+ color: #4a5568;
92
+ }
93
+ .helper-text[data-v-55743049] {
94
+ display: flex;
95
+ align-items: center;
96
+ gap: 0.5rem;
97
+ margin-top: 0.5rem;
98
+ font-size: 0.8125rem;
99
+ color: #718096;
100
+ }
101
+ .helper-text i[data-v-55743049] {
102
+ color: #4299e1;
103
+ font-size: 0.875rem;
104
+ }
105
+ .loading-state[data-v-55743049] {
106
+ display: flex;
107
+ flex-direction: column;
108
+ align-items: center;
109
+ gap: 0.5rem;
110
+ padding: 1rem;
111
+ }
112
+ .loading-state p[data-v-55743049] {
113
+ margin: 0;
114
+ color: #718096;
115
+ font-size: 0.875rem;
116
+ }
117
+ .loading-spinner[data-v-55743049] {
118
+ width: 2rem;
119
+ height: 2rem;
120
+ border: 2px solid #e2e8f0;
121
+ border-top-color: #4299e1;
122
+ border-radius: 50%;
123
+ animation: spin-55743049 0.8s linear infinite;
124
+ }
125
+ @keyframes spin-55743049 {
126
+ to {
127
+ transform: rotate(360deg);
128
+ }
129
+ }
130
+ @media (max-width: 640px) {
131
+ .form-row[data-v-55743049] {
132
+ flex-direction: column;
133
+ gap: 0.5rem;
134
+ }
135
+ .half[data-v-55743049] {
136
+ max-width: 100%;
137
+ }
138
+ }
@@ -0,0 +1,430 @@
1
+ import { d as defineComponent, r as ref, c as openBlock, e as createElementBlock, f as createVNode, w as withCtx, p as createBaseVNode, a5 as withDirectives, F as Fragment, q as renderList, t as toDisplayString, ag as vModelSelect, g as createTextVNode, i as createCommentVNode, a6 as vModelText, h as createBlock, u as unref, z as ElMessage, _ as _export_sfc, n as onMounted, R as nextTick, a7 as Teleport } from "./index-3a75211d.js";
2
+ import { C as CodeLoader } from "./vue-content-loader.es-93bd09d7.js";
3
+ import { u as useNodeStore } from "./vue-codemirror.esm-f15a5f87.js";
4
+ import { f as fetchCloudStorageConnectionsInterfaces } from "./api-fb67319c.js";
5
+ import { G as GenericNodeSettings } from "./genericNodeSettings-7013cc94.js";
6
+ import { N as NodeButton, a as NodeTitle } from "./nodeTitle-a63d4680.js";
7
+ import "./designer-94a6bf4d.js";
8
+ const createNodeCloudStorageWriter = (flowId, nodeId) => {
9
+ const cloudStorageWriteSettings = {
10
+ auth_mode: "aws-cli",
11
+ // Default to local credentials
12
+ connection_name: void 0,
13
+ resource_path: "",
14
+ write_mode: "overwrite",
15
+ file_format: "parquet",
16
+ // Parquet is a common, efficient default
17
+ parquet_compression: "snappy",
18
+ csv_delimiter: ",",
19
+ csv_encoding: "utf8"
20
+ };
21
+ const nodeWriter = {
22
+ flow_id: flowId,
23
+ node_id: nodeId,
24
+ pos_x: 0,
25
+ pos_y: 0,
26
+ cloud_storage_settings: cloudStorageWriteSettings,
27
+ cache_results: false
28
+ };
29
+ return nodeWriter;
30
+ };
31
+ const _hoisted_1$1 = {
32
+ key: 0,
33
+ class: "cloud-storage-container"
34
+ };
35
+ const _hoisted_2 = { class: "listbox-wrapper" };
36
+ const _hoisted_3 = { class: "form-group" };
37
+ const _hoisted_4 = {
38
+ key: 0,
39
+ class: "loading-state"
40
+ };
41
+ const _hoisted_5 = { key: 1 };
42
+ const _hoisted_6 = ["value"];
43
+ const _hoisted_7 = {
44
+ key: 0,
45
+ class: "helper-text"
46
+ };
47
+ const _hoisted_8 = { class: "listbox-wrapper" };
48
+ const _hoisted_9 = { class: "form-group" };
49
+ const _hoisted_10 = { class: "form-group" };
50
+ const _hoisted_11 = { class: "form-group" };
51
+ const _hoisted_12 = {
52
+ key: 0,
53
+ value: "append"
54
+ };
55
+ const _hoisted_13 = {
56
+ key: 0,
57
+ class: "format-options"
58
+ };
59
+ const _hoisted_14 = { class: "form-row" };
60
+ const _hoisted_15 = { class: "form-group half" };
61
+ const _hoisted_16 = { class: "form-group half" };
62
+ const _hoisted_17 = {
63
+ key: 1,
64
+ class: "format-options"
65
+ };
66
+ const _hoisted_18 = { class: "form-group" };
67
+ const _hoisted_19 = {
68
+ key: 2,
69
+ class: "info-box info-warn"
70
+ };
71
+ const _hoisted_20 = {
72
+ key: 3,
73
+ class: "info-box"
74
+ };
75
+ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
76
+ __name: "CloudStorageWriter",
77
+ props: {
78
+ nodeId: {}
79
+ },
80
+ setup(__props, { expose: __expose }) {
81
+ const nodeStore = useNodeStore();
82
+ const dataLoaded = ref(false);
83
+ const nodeCloudStorageWriter = ref(null);
84
+ const connectionInterfaces = ref([]);
85
+ const connectionsAreLoading = ref(false);
86
+ const selectedConnection = ref(null);
87
+ const getStorageTypeLabel = (storageType) => {
88
+ switch (storageType) {
89
+ case "s3":
90
+ return "AWS S3";
91
+ case "adls":
92
+ return "Azure ADLS";
93
+ case "gcs":
94
+ return "Google Cloud Storage";
95
+ default:
96
+ return storageType.toUpperCase();
97
+ }
98
+ };
99
+ const getAuthMethodLabel = (authMethod) => {
100
+ switch (authMethod) {
101
+ case "access_key":
102
+ return "Access Key";
103
+ case "iam_role":
104
+ return "IAM Role";
105
+ case "service_principal":
106
+ return "Service Principal";
107
+ case "managed_identity":
108
+ return "Managed Identity";
109
+ case "sas_token":
110
+ return "SAS Token";
111
+ case "aws-cli":
112
+ return "AWS CLI";
113
+ case "auto":
114
+ return "Auto";
115
+ default:
116
+ return authMethod;
117
+ }
118
+ };
119
+ const handleFileFormatChange = () => {
120
+ if (nodeCloudStorageWriter.value) {
121
+ const settings = nodeCloudStorageWriter.value.cloud_storage_settings;
122
+ const format = settings.file_format;
123
+ if (format !== "delta") {
124
+ settings.write_mode = "overwrite";
125
+ }
126
+ if (format === "parquet" && !settings.parquet_compression) {
127
+ settings.parquet_compression = "snappy";
128
+ } else if (format === "csv" && !settings.csv_delimiter) {
129
+ settings.csv_delimiter = ",";
130
+ settings.csv_encoding = "utf8";
131
+ }
132
+ if (format !== "parquet") {
133
+ settings.parquet_compression = "snappy";
134
+ }
135
+ if (format !== "csv") {
136
+ settings.csv_delimiter = ";";
137
+ settings.csv_encoding = "utf8-lossy";
138
+ }
139
+ }
140
+ };
141
+ const updateConnection = () => {
142
+ if (nodeCloudStorageWriter.value) {
143
+ if (!selectedConnection.value) {
144
+ nodeCloudStorageWriter.value.cloud_storage_settings.auth_mode = "aws-cli";
145
+ nodeCloudStorageWriter.value.cloud_storage_settings.connection_name = void 0;
146
+ } else {
147
+ nodeCloudStorageWriter.value.cloud_storage_settings.auth_mode = selectedConnection.value.authMethod;
148
+ nodeCloudStorageWriter.value.cloud_storage_settings.connection_name = selectedConnection.value.connectionName;
149
+ }
150
+ }
151
+ };
152
+ const setConnectionOnConnectionName = async (connectionName) => {
153
+ selectedConnection.value = connectionInterfaces.value.find((ci) => ci.connectionName === connectionName) || null;
154
+ };
155
+ const loadNodeData = async (nodeId) => {
156
+ var _a, _b;
157
+ try {
158
+ const [nodeData] = await Promise.all([
159
+ nodeStore.getNodeData(nodeId, false),
160
+ fetchConnections()
161
+ ]);
162
+ if (nodeData) {
163
+ const hasValidSetup = Boolean((_a = nodeData.setting_input) == null ? void 0 : _a.is_setup);
164
+ nodeCloudStorageWriter.value = hasValidSetup ? nodeData.setting_input : createNodeCloudStorageWriter(nodeStore.flow_id, nodeId);
165
+ if ((_b = nodeCloudStorageWriter.value) == null ? void 0 : _b.cloud_storage_settings.connection_name) {
166
+ await setConnectionOnConnectionName(
167
+ nodeCloudStorageWriter.value.cloud_storage_settings.connection_name
168
+ );
169
+ } else {
170
+ selectedConnection.value = null;
171
+ }
172
+ }
173
+ dataLoaded.value = true;
174
+ } catch (error) {
175
+ console.error("Error loading node data:", error);
176
+ ElMessage.error("Failed to load node settings.");
177
+ dataLoaded.value = false;
178
+ }
179
+ };
180
+ const pushNodeData = async () => {
181
+ if (!nodeCloudStorageWriter.value || !nodeCloudStorageWriter.value.cloud_storage_settings) {
182
+ return;
183
+ }
184
+ console.log(nodeCloudStorageWriter);
185
+ nodeCloudStorageWriter.value.is_setup = true;
186
+ nodeStore.updateSettings(nodeCloudStorageWriter);
187
+ dataLoaded.value = false;
188
+ };
189
+ const fetchConnections = async () => {
190
+ connectionsAreLoading.value = true;
191
+ try {
192
+ connectionInterfaces.value = await fetchCloudStorageConnectionsInterfaces();
193
+ } catch (error) {
194
+ console.error("Error fetching connections:", error);
195
+ ElMessage.error("Failed to load cloud storage connections");
196
+ } finally {
197
+ connectionsAreLoading.value = false;
198
+ }
199
+ };
200
+ __expose({
201
+ loadNodeData,
202
+ pushNodeData
203
+ });
204
+ return (_ctx, _cache) => {
205
+ return dataLoaded.value && nodeCloudStorageWriter.value ? (openBlock(), createElementBlock("div", _hoisted_1$1, [
206
+ createVNode(GenericNodeSettings, {
207
+ modelValue: nodeCloudStorageWriter.value,
208
+ "onUpdate:modelValue": _cache[7] || (_cache[7] = ($event) => nodeCloudStorageWriter.value = $event)
209
+ }, {
210
+ default: withCtx(() => [
211
+ createBaseVNode("div", _hoisted_2, [
212
+ createBaseVNode("div", _hoisted_3, [
213
+ _cache[11] || (_cache[11] = createBaseVNode("label", { for: "connection-select" }, "Cloud Storage Connection", -1)),
214
+ connectionsAreLoading.value ? (openBlock(), createElementBlock("div", _hoisted_4, _cache[8] || (_cache[8] = [
215
+ createBaseVNode("div", { class: "loading-spinner" }, null, -1),
216
+ createBaseVNode("p", null, "Loading connections...", -1)
217
+ ]))) : (openBlock(), createElementBlock("div", _hoisted_5, [
218
+ withDirectives(createBaseVNode("select", {
219
+ id: "connection-select",
220
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => selectedConnection.value = $event),
221
+ class: "form-control",
222
+ onChange: updateConnection
223
+ }, [
224
+ _cache[9] || (_cache[9] = createBaseVNode("option", { value: null }, "No connection (use local credentials)", -1)),
225
+ (openBlock(true), createElementBlock(Fragment, null, renderList(connectionInterfaces.value, (conn) => {
226
+ return openBlock(), createElementBlock("option", {
227
+ key: conn.connectionName,
228
+ value: conn
229
+ }, toDisplayString(conn.connectionName) + " (" + toDisplayString(getStorageTypeLabel(conn.storageType)) + " - " + toDisplayString(getAuthMethodLabel(conn.authMethod)) + ") ", 9, _hoisted_6);
230
+ }), 128))
231
+ ], 544), [
232
+ [vModelSelect, selectedConnection.value]
233
+ ]),
234
+ !nodeCloudStorageWriter.value.cloud_storage_settings.connection_name ? (openBlock(), createElementBlock("div", _hoisted_7, _cache[10] || (_cache[10] = [
235
+ createBaseVNode("i", { class: "fa-solid fa-info-circle" }, null, -1),
236
+ createTextVNode(" Will use local AWS CLI credentials or environment variables ")
237
+ ]))) : createCommentVNode("", true)
238
+ ]))
239
+ ])
240
+ ]),
241
+ createBaseVNode("div", _hoisted_8, [
242
+ _cache[26] || (_cache[26] = createBaseVNode("h4", { class: "section-subtitle" }, "File Settings", -1)),
243
+ createBaseVNode("div", _hoisted_9, [
244
+ _cache[12] || (_cache[12] = createBaseVNode("label", { for: "file-path" }, "File Path", -1)),
245
+ withDirectives(createBaseVNode("input", {
246
+ id: "file-path",
247
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => nodeCloudStorageWriter.value.cloud_storage_settings.resource_path = $event),
248
+ type: "text",
249
+ class: "form-control",
250
+ placeholder: "e.g., bucket-name/folder/file.parquet"
251
+ }, null, 512), [
252
+ [vModelText, nodeCloudStorageWriter.value.cloud_storage_settings.resource_path]
253
+ ])
254
+ ]),
255
+ createBaseVNode("div", _hoisted_10, [
256
+ _cache[14] || (_cache[14] = createBaseVNode("label", { for: "file-format" }, "File Format", -1)),
257
+ withDirectives(createBaseVNode("select", {
258
+ id: "file-format",
259
+ "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => nodeCloudStorageWriter.value.cloud_storage_settings.file_format = $event),
260
+ class: "form-control",
261
+ onChange: handleFileFormatChange
262
+ }, _cache[13] || (_cache[13] = [
263
+ createBaseVNode("option", { value: "parquet" }, "Parquet", -1),
264
+ createBaseVNode("option", { value: "csv" }, "CSV", -1),
265
+ createBaseVNode("option", { value: "json" }, "JSON", -1),
266
+ createBaseVNode("option", { value: "delta" }, "Delta Lake", -1)
267
+ ]), 544), [
268
+ [vModelSelect, nodeCloudStorageWriter.value.cloud_storage_settings.file_format]
269
+ ])
270
+ ]),
271
+ createBaseVNode("div", _hoisted_11, [
272
+ _cache[16] || (_cache[16] = createBaseVNode("label", { for: "write-mode" }, "Write Mode", -1)),
273
+ withDirectives(createBaseVNode("select", {
274
+ id: "write-mode",
275
+ "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => nodeCloudStorageWriter.value.cloud_storage_settings.write_mode = $event),
276
+ class: "form-control"
277
+ }, [
278
+ _cache[15] || (_cache[15] = createBaseVNode("option", { value: "overwrite" }, "Overwrite", -1)),
279
+ nodeCloudStorageWriter.value.cloud_storage_settings.file_format === "delta" ? (openBlock(), createElementBlock("option", _hoisted_12, " Append ")) : createCommentVNode("", true)
280
+ ], 512), [
281
+ [vModelSelect, nodeCloudStorageWriter.value.cloud_storage_settings.write_mode]
282
+ ])
283
+ ]),
284
+ nodeCloudStorageWriter.value.cloud_storage_settings.file_format === "csv" ? (openBlock(), createElementBlock("div", _hoisted_13, [
285
+ _cache[20] || (_cache[20] = createBaseVNode("h5", { class: "subsection-title" }, "CSV Options", -1)),
286
+ createBaseVNode("div", _hoisted_14, [
287
+ createBaseVNode("div", _hoisted_15, [
288
+ _cache[17] || (_cache[17] = createBaseVNode("label", { for: "csv-delimiter" }, "Delimiter", -1)),
289
+ withDirectives(createBaseVNode("input", {
290
+ id: "csv-delimiter",
291
+ "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => nodeCloudStorageWriter.value.cloud_storage_settings.csv_delimiter = $event),
292
+ type: "text",
293
+ class: "form-control",
294
+ placeholder: ",",
295
+ maxlength: "1"
296
+ }, null, 512), [
297
+ [vModelText, nodeCloudStorageWriter.value.cloud_storage_settings.csv_delimiter]
298
+ ])
299
+ ]),
300
+ createBaseVNode("div", _hoisted_16, [
301
+ _cache[19] || (_cache[19] = createBaseVNode("label", { for: "csv-encoding" }, "Encoding", -1)),
302
+ withDirectives(createBaseVNode("select", {
303
+ id: "csv-encoding",
304
+ "onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => nodeCloudStorageWriter.value.cloud_storage_settings.csv_encoding = $event),
305
+ class: "form-control"
306
+ }, _cache[18] || (_cache[18] = [
307
+ createBaseVNode("option", { value: "utf8" }, "UTF-8", -1),
308
+ createBaseVNode("option", { value: "utf8-lossy" }, "UTF-8 Lossy", -1)
309
+ ]), 512), [
310
+ [vModelSelect, nodeCloudStorageWriter.value.cloud_storage_settings.csv_encoding]
311
+ ])
312
+ ])
313
+ ])
314
+ ])) : createCommentVNode("", true),
315
+ nodeCloudStorageWriter.value.cloud_storage_settings.file_format === "parquet" ? (openBlock(), createElementBlock("div", _hoisted_17, [
316
+ _cache[23] || (_cache[23] = createBaseVNode("h5", { class: "subsection-title" }, "Parquet Options", -1)),
317
+ createBaseVNode("div", _hoisted_18, [
318
+ _cache[22] || (_cache[22] = createBaseVNode("label", { for: "parquet-compression" }, "Compression", -1)),
319
+ withDirectives(createBaseVNode("select", {
320
+ id: "parquet-compression",
321
+ "onUpdate:modelValue": _cache[6] || (_cache[6] = ($event) => nodeCloudStorageWriter.value.cloud_storage_settings.parquet_compression = $event),
322
+ class: "form-control"
323
+ }, _cache[21] || (_cache[21] = [
324
+ createBaseVNode("option", { value: "snappy" }, "Snappy", -1),
325
+ createBaseVNode("option", { value: "gzip" }, "Gzip", -1),
326
+ createBaseVNode("option", { value: "brotli" }, "Brotli", -1),
327
+ createBaseVNode("option", { value: "lz4" }, "LZ4", -1),
328
+ createBaseVNode("option", { value: "zstd" }, "Zstd", -1)
329
+ ]), 512), [
330
+ [vModelSelect, nodeCloudStorageWriter.value.cloud_storage_settings.parquet_compression]
331
+ ])
332
+ ])
333
+ ])) : createCommentVNode("", true),
334
+ nodeCloudStorageWriter.value.cloud_storage_settings.write_mode === "overwrite" ? (openBlock(), createElementBlock("div", _hoisted_19, _cache[24] || (_cache[24] = [
335
+ createBaseVNode("i", { class: "fa-solid fa-triangle-exclamation" }, null, -1),
336
+ createBaseVNode("div", null, [
337
+ createBaseVNode("p", null, [
338
+ createBaseVNode("strong", null, "Overwrite mode:"),
339
+ createTextVNode(" If a file or data at the target path exists, it will be replaced. ")
340
+ ])
341
+ ], -1)
342
+ ]))) : createCommentVNode("", true),
343
+ nodeCloudStorageWriter.value.cloud_storage_settings.write_mode === "append" ? (openBlock(), createElementBlock("div", _hoisted_20, _cache[25] || (_cache[25] = [
344
+ createBaseVNode("i", { class: "fa-solid fa-info-circle" }, null, -1),
345
+ createBaseVNode("div", null, [
346
+ createBaseVNode("p", null, [
347
+ createBaseVNode("strong", null, "Append mode:"),
348
+ createTextVNode(" New data will be added. The schema of the new data must match the existing data. ")
349
+ ])
350
+ ], -1)
351
+ ]))) : createCommentVNode("", true)
352
+ ])
353
+ ]),
354
+ _: 1
355
+ }, 8, ["modelValue"])
356
+ ])) : (openBlock(), createBlock(unref(CodeLoader), { key: 1 }));
357
+ };
358
+ }
359
+ });
360
+ const CloudStorageWriter_vue_vue_type_style_index_0_scoped_55743049_lang = "";
361
+ const CloudStorageReader = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-55743049"]]);
362
+ const _hoisted_1 = { ref: "el" };
363
+ const _sfc_main = /* @__PURE__ */ defineComponent({
364
+ __name: "CloudStorageWriter",
365
+ props: {
366
+ nodeId: {
367
+ type: Number,
368
+ required: true
369
+ }
370
+ },
371
+ setup(__props) {
372
+ const nodeStore = useNodeStore();
373
+ const childComp = ref(null);
374
+ const props = __props;
375
+ const drawer = ref(false);
376
+ const closeOnDrawer = () => {
377
+ var _a;
378
+ drawer.value = false;
379
+ (_a = childComp.value) == null ? void 0 : _a.pushNodeData();
380
+ };
381
+ const openDrawer = async () => {
382
+ if (nodeStore.node_id === props.nodeId) {
383
+ return;
384
+ }
385
+ nodeStore.closeDrawer();
386
+ drawer.value = true;
387
+ const drawerOpen = nodeStore.isDrawerOpen;
388
+ nodeStore.isDrawerOpen = true;
389
+ await nextTick();
390
+ if (nodeStore.node_id === props.nodeId && drawerOpen) {
391
+ return;
392
+ }
393
+ if (childComp.value) {
394
+ childComp.value.loadNodeData(props.nodeId);
395
+ nodeStore.openDrawer(closeOnDrawer);
396
+ }
397
+ };
398
+ onMounted(async () => {
399
+ await nextTick();
400
+ });
401
+ return (_ctx, _cache) => {
402
+ return openBlock(), createElementBlock("div", _hoisted_1, [
403
+ createVNode(NodeButton, {
404
+ ref: "nodeButton",
405
+ "node-id": __props.nodeId,
406
+ "image-src": "cloud_storage_writer.png",
407
+ title: `${__props.nodeId}: Cloud storage writer`,
408
+ onClick: openDrawer
409
+ }, null, 8, ["node-id", "title"]),
410
+ drawer.value ? (openBlock(), createBlock(Teleport, {
411
+ key: 0,
412
+ to: "#nodesettings"
413
+ }, [
414
+ createVNode(NodeTitle, {
415
+ title: "Write data to cloud provider",
416
+ intro: "Write data to cloud provider"
417
+ }),
418
+ createVNode(CloudStorageReader, {
419
+ ref_key: "childComp",
420
+ ref: childComp,
421
+ "node-id": __props.nodeId
422
+ }, null, 8, ["node-id"])
423
+ ])) : createCommentVNode("", true)
424
+ ], 512);
425
+ };
426
+ }
427
+ });
428
+ export {
429
+ _sfc_main as default
430
+ };
@@ -1,11 +1,11 @@
1
- import { C as CodeLoader } from "./vue-content-loader.es-6c4b1c24.js";
2
- import { u as useNodeStore } from "./vue-codemirror.esm-25e75a08.js";
3
- import { s as selectDynamic } from "./selectDynamic-96aa82cd.js";
4
- import { G as GenericNodeSettings } from "./genericNodeSettings-4bdcf98e.js";
5
- import { d as defineComponent, r as ref, c as openBlock, e as createElementBlock, f as createVNode, w as withCtx, p as createBaseVNode, h as createBlock, u as unref, _ as _export_sfc, n as onMounted, R as nextTick, a7 as Teleport, i as createCommentVNode } from "./index-e235a8bc.js";
6
- import { N as NodeButton, a as NodeTitle } from "./nodeTitle-fc3fc4b7.js";
7
- import "./UnavailableFields-c42880a3.js";
8
- import "./designer-267d44f1.js";
1
+ import { C as CodeLoader } from "./vue-content-loader.es-93bd09d7.js";
2
+ import { u as useNodeStore } from "./vue-codemirror.esm-f15a5f87.js";
3
+ import { s as selectDynamic } from "./selectDynamic-08464729.js";
4
+ import { G as GenericNodeSettings } from "./genericNodeSettings-7013cc94.js";
5
+ import { d as defineComponent, r as ref, c as openBlock, e as createElementBlock, f as createVNode, w as withCtx, p as createBaseVNode, h as createBlock, u as unref, _ as _export_sfc, n as onMounted, R as nextTick, a7 as Teleport, i as createCommentVNode } from "./index-3a75211d.js";
6
+ import { N as NodeButton, a as NodeTitle } from "./nodeTitle-a63d4680.js";
7
+ import "./UnavailableFields-118f1d20.js";
8
+ import "./designer-94a6bf4d.js";
9
9
  const _hoisted_1$1 = { key: 0 };
10
10
  const _hoisted_2 = { class: "listbox-wrapper" };
11
11
  const _sfc_main$1 = /* @__PURE__ */ defineComponent({
@@ -1,5 +1,5 @@
1
- import { f as fetchSecretsApi } from "./secretApi-cdc2a3fd.js";
2
- import { d as defineComponent, r as ref, n as onMounted, c as openBlock, e as createElementBlock, p as createBaseVNode, t as toDisplayString, F as Fragment, q as renderList, i as createCommentVNode, _ as _export_sfc } from "./index-e235a8bc.js";
1
+ import { f as fetchSecretsApi } from "./secretApi-763aec6e.js";
2
+ import { d as defineComponent, r as ref, n as onMounted, c as openBlock, e as createElementBlock, p as createBaseVNode, t as toDisplayString, F as Fragment, q as renderList, i as createCommentVNode, _ as _export_sfc } from "./index-3a75211d.js";
3
3
  const _hoisted_1 = { class: "connection-settings-container" };
4
4
  const _hoisted_2 = { class: "toggle-button" };
5
5
  const _hoisted_3 = {
@@ -1,5 +1,5 @@
1
- import { f as fetchDatabaseConnectionsInterfaces, c as createDatabaseConnectionApi, d as deleteDatabaseConnectionApi } from "./api-44ca9e9c.js";
2
- import { d as defineComponent, r as ref, m as watch, l as computed, c as openBlock, e as createElementBlock, p as createBaseVNode, a5 as withDirectives, a6 as vModelText, ag as vModelSelect, ah as vModelDynamic, s as normalizeClass, ai as vModelCheckbox, t as toDisplayString, v as withModifiers, n as onMounted, g as createTextVNode, F as Fragment, q as renderList, f as createVNode, w as withCtx, u as unref, z as ElMessage, aj as ElDialog, ak as ElButton, _ as _export_sfc } from "./index-e235a8bc.js";
1
+ import { f as fetchDatabaseConnectionsInterfaces, c as createDatabaseConnectionApi, d as deleteDatabaseConnectionApi } from "./api-602fb95c.js";
2
+ import { d as defineComponent, r as ref, m as watch, l as computed, c as openBlock, e as createElementBlock, p as createBaseVNode, a5 as withDirectives, a6 as vModelText, ag as vModelSelect, ah as vModelDynamic, s as normalizeClass, ai as vModelCheckbox, t as toDisplayString, v as withModifiers, n as onMounted, g as createTextVNode, F as Fragment, q as renderList, f as createVNode, w as withCtx, u as unref, z as ElMessage, aj as ElDialog, ak as ElButton, _ as _export_sfc } from "./index-3a75211d.js";
3
3
  const _hoisted_1$1 = { class: "form-grid" };
4
4
  const _hoisted_2$1 = { class: "form-field" };
5
5
  const _hoisted_3$1 = { class: "form-field" };
@@ -1,12 +1,12 @@
1
- import { d as defineComponent, c as openBlock, e as createElementBlock, p as createBaseVNode, _ as _export_sfc, r as ref, n as onMounted, b as resolveComponent, f as createVNode, w as withCtx, F as Fragment, q as renderList, h as createBlock, u as unref, al as ElRadio, g as createTextVNode, t as toDisplayString, a5 as withDirectives, ag as vModelSelect, a6 as vModelText, i as createCommentVNode, a as axios, z as ElMessage, R as nextTick, a7 as Teleport } from "./index-e235a8bc.js";
2
- import { C as CodeLoader } from "./vue-content-loader.es-6c4b1c24.js";
3
- import { u as useNodeStore } from "./vue-codemirror.esm-25e75a08.js";
4
- import { f as fetchDatabaseConnectionsInterfaces } from "./api-44ca9e9c.js";
5
- import { D as DatabaseConnectionSettings } from "./DatabaseConnectionSettings-b2afb1d7.js";
6
- import { G as GenericNodeSettings } from "./genericNodeSettings-4bdcf98e.js";
7
- import { N as NodeButton, a as NodeTitle } from "./nodeTitle-fc3fc4b7.js";
8
- import "./secretApi-cdc2a3fd.js";
9
- import "./designer-267d44f1.js";
1
+ import { d as defineComponent, c as openBlock, e as createElementBlock, p as createBaseVNode, _ as _export_sfc, r as ref, n as onMounted, b as resolveComponent, f as createVNode, w as withCtx, F as Fragment, q as renderList, h as createBlock, u as unref, al as ElRadio, g as createTextVNode, t as toDisplayString, a5 as withDirectives, ag as vModelSelect, a6 as vModelText, i as createCommentVNode, a as axios, z as ElMessage, R as nextTick, a7 as Teleport } from "./index-3a75211d.js";
2
+ import { C as CodeLoader } from "./vue-content-loader.es-93bd09d7.js";
3
+ import { u as useNodeStore } from "./vue-codemirror.esm-f15a5f87.js";
4
+ import { f as fetchDatabaseConnectionsInterfaces } from "./api-602fb95c.js";
5
+ import { D as DatabaseConnectionSettings } from "./DatabaseConnectionSettings-0b06649c.js";
6
+ import { G as GenericNodeSettings } from "./genericNodeSettings-7013cc94.js";
7
+ import { N as NodeButton, a as NodeTitle } from "./nodeTitle-a63d4680.js";
8
+ import "./secretApi-763aec6e.js";
9
+ import "./designer-94a6bf4d.js";
10
10
  const createNodeDatabaseReader = (flowId, nodeId) => {
11
11
  const databaseSettings = {
12
12
  query_mode: "table",
@@ -1,12 +1,12 @@
1
- import { d as defineComponent, r as ref, n as onMounted, b as resolveComponent, c as openBlock, e as createElementBlock, f as createVNode, w as withCtx, p as createBaseVNode, F as Fragment, q as renderList, h as createBlock, u as unref, al as ElRadio, g as createTextVNode, t as toDisplayString, a5 as withDirectives, ag as vModelSelect, a6 as vModelText, z as ElMessage, _ as _export_sfc, R as nextTick, a7 as Teleport, i as createCommentVNode } from "./index-e235a8bc.js";
2
- import { C as CodeLoader } from "./vue-content-loader.es-6c4b1c24.js";
3
- import { u as useNodeStore } from "./vue-codemirror.esm-25e75a08.js";
4
- import { f as fetchDatabaseConnectionsInterfaces } from "./api-44ca9e9c.js";
5
- import { D as DatabaseConnectionSettings } from "./DatabaseConnectionSettings-b2afb1d7.js";
6
- import { G as GenericNodeSettings } from "./genericNodeSettings-4bdcf98e.js";
7
- import { N as NodeButton, a as NodeTitle } from "./nodeTitle-fc3fc4b7.js";
8
- import "./secretApi-cdc2a3fd.js";
9
- import "./designer-267d44f1.js";
1
+ import { d as defineComponent, r as ref, n as onMounted, b as resolveComponent, c as openBlock, e as createElementBlock, f as createVNode, w as withCtx, p as createBaseVNode, F as Fragment, q as renderList, h as createBlock, u as unref, al as ElRadio, g as createTextVNode, t as toDisplayString, a5 as withDirectives, ag as vModelSelect, a6 as vModelText, z as ElMessage, _ as _export_sfc, R as nextTick, a7 as Teleport, i as createCommentVNode } from "./index-3a75211d.js";
2
+ import { C as CodeLoader } from "./vue-content-loader.es-93bd09d7.js";
3
+ import { u as useNodeStore } from "./vue-codemirror.esm-f15a5f87.js";
4
+ import { f as fetchDatabaseConnectionsInterfaces } from "./api-602fb95c.js";
5
+ import { D as DatabaseConnectionSettings } from "./DatabaseConnectionSettings-0b06649c.js";
6
+ import { G as GenericNodeSettings } from "./genericNodeSettings-7013cc94.js";
7
+ import { N as NodeButton, a as NodeTitle } from "./nodeTitle-a63d4680.js";
8
+ import "./secretApi-763aec6e.js";
9
+ import "./designer-94a6bf4d.js";
10
10
  const createNodeDatabaseWriter = (flowId, nodeId) => {
11
11
  const databaseWriteSettings = {
12
12
  if_exists: "replace",