@quillsql/admin 1.6.0 → 1.6.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 (151) hide show
  1. package/dist/cjs/Admin.d.ts.map +1 -1
  2. package/dist/cjs/Admin.js +24 -11
  3. package/dist/cjs/AdminProvider.d.ts +2 -1
  4. package/dist/cjs/AdminProvider.d.ts.map +1 -1
  5. package/dist/cjs/AdminProvider.js +13 -24
  6. package/dist/cjs/api/ConnectionClient.d.ts +8 -0
  7. package/dist/cjs/api/ConnectionClient.d.ts.map +1 -1
  8. package/dist/cjs/api/ConnectionClient.js +42 -8
  9. package/dist/cjs/components/DashboardSelectPopover.d.ts.map +1 -1
  10. package/dist/cjs/components/DashboardSelectPopover.js +20 -3
  11. package/dist/cjs/components/DropDownMenuWithLabel.d.ts.map +1 -1
  12. package/dist/cjs/components/DropDownMenuWithLabel.js +4 -35
  13. package/dist/cjs/components/EmptyDashboardComponent/index.d.ts.map +1 -1
  14. package/dist/cjs/components/EmptyDashboardComponent/index.js +11 -9
  15. package/dist/cjs/components/QuillSelect.d.ts.map +1 -1
  16. package/dist/cjs/components/QuillSelect.js +2 -2
  17. package/dist/cjs/components/SegmentedControl.d.ts +4 -2
  18. package/dist/cjs/components/SegmentedControl.d.ts.map +1 -1
  19. package/dist/cjs/components/SegmentedControl.js +22 -16
  20. package/dist/cjs/components/SqlTextEditor.d.ts +9 -1
  21. package/dist/cjs/components/SqlTextEditor.d.ts.map +1 -1
  22. package/dist/cjs/components/SqlTextEditor.js +60 -12
  23. package/dist/cjs/components/UiComponents.d.ts.map +1 -1
  24. package/dist/cjs/components/UiComponents.js +11 -2
  25. package/dist/cjs/constants/dataTypes.d.ts +2 -0
  26. package/dist/cjs/constants/dataTypes.d.ts.map +1 -0
  27. package/dist/cjs/constants/dataTypes.js +21 -0
  28. package/dist/cjs/forms/client_onboard/ConnectDatabase.d.ts.map +1 -1
  29. package/dist/cjs/forms/client_onboard/ConnectDatabase.js +9 -17
  30. package/dist/cjs/forms/client_onboard/CreateSqlViews.d.ts.map +1 -1
  31. package/dist/cjs/forms/client_onboard/CreateSqlViews.js +24 -11
  32. package/dist/cjs/forms/sql_views/CreateEditSqlView.d.ts +4 -1
  33. package/dist/cjs/forms/sql_views/CreateEditSqlView.d.ts.map +1 -1
  34. package/dist/cjs/forms/sql_views/CreateEditSqlView.js +87 -36
  35. package/dist/cjs/modals/EditFiltersModal.d.ts.map +1 -1
  36. package/dist/cjs/modals/EditFiltersModal.js +13 -3
  37. package/dist/cjs/modals/NewDashboardModal.js +2 -2
  38. package/dist/cjs/modals/PromoteDashModal.js +2 -2
  39. package/dist/cjs/modals/PromoteViewModal.d.ts +2 -1
  40. package/dist/cjs/modals/PromoteViewModal.d.ts.map +1 -1
  41. package/dist/cjs/modals/PromoteViewModal.js +46 -36
  42. package/dist/cjs/primitives/TextInputPrimitive.d.ts +1 -0
  43. package/dist/cjs/primitives/TextInputPrimitive.d.ts.map +1 -1
  44. package/dist/cjs/primitives/TextInputPrimitive.js +35 -20
  45. package/dist/cjs/public_components/CreateEnvironment.d.ts +2 -1
  46. package/dist/cjs/public_components/CreateEnvironment.d.ts.map +1 -1
  47. package/dist/cjs/public_components/CreateEnvironment.js +4 -1
  48. package/dist/cjs/public_components/DashboardBuilder.d.ts.map +1 -1
  49. package/dist/cjs/public_components/DashboardBuilder.js +67 -156
  50. package/dist/cjs/public_components/DashboardManager.d.ts.map +1 -1
  51. package/dist/cjs/public_components/DashboardManager.js +72 -73
  52. package/dist/cjs/public_components/SQLViewManager.d.ts +1 -0
  53. package/dist/cjs/public_components/SQLViewManager.d.ts.map +1 -1
  54. package/dist/cjs/public_components/SQLViewManager.js +216 -40
  55. package/dist/cjs/utils/astProcessing.d.ts +2 -0
  56. package/dist/cjs/utils/astProcessing.d.ts.map +1 -0
  57. package/dist/cjs/utils/astProcessing.js +41 -0
  58. package/dist/cjs/utils/astProcessing.uspec.d.ts +2 -0
  59. package/dist/cjs/utils/astProcessing.uspec.d.ts.map +1 -0
  60. package/dist/cjs/utils/astProcessing.uspec.js +26 -0
  61. package/dist/cjs/utils/columnProcessing.d.ts +3 -0
  62. package/dist/cjs/utils/columnProcessing.d.ts.map +1 -0
  63. package/dist/cjs/utils/columnProcessing.js +42 -0
  64. package/dist/cjs/utils/dataEditor.d.ts +2 -2
  65. package/dist/cjs/utils/dataEditor.d.ts.map +1 -1
  66. package/dist/cjs/utils/dataEditor.js +4 -2
  67. package/dist/cjs/utils/databases.d.ts +0 -1
  68. package/dist/cjs/utils/databases.d.ts.map +1 -1
  69. package/dist/cjs/utils/databases.js +5 -6
  70. package/dist/cjs/utils/monacoAutocomplete.d.ts +21 -0
  71. package/dist/cjs/utils/monacoAutocomplete.d.ts.map +1 -0
  72. package/dist/cjs/utils/monacoAutocomplete.js +250 -0
  73. package/dist/cjs/utils/schema.d.ts +5 -0
  74. package/dist/cjs/utils/schema.d.ts.map +1 -1
  75. package/dist/cjs/utils/schema.js +129 -0
  76. package/dist/esm/Admin.d.ts.map +1 -1
  77. package/dist/esm/Admin.js +24 -11
  78. package/dist/esm/AdminProvider.d.ts +2 -1
  79. package/dist/esm/AdminProvider.d.ts.map +1 -1
  80. package/dist/esm/AdminProvider.js +13 -24
  81. package/dist/esm/api/ConnectionClient.d.ts +8 -0
  82. package/dist/esm/api/ConnectionClient.d.ts.map +1 -1
  83. package/dist/esm/api/ConnectionClient.js +42 -8
  84. package/dist/esm/components/DashboardSelectPopover.d.ts.map +1 -1
  85. package/dist/esm/components/DashboardSelectPopover.js +20 -3
  86. package/dist/esm/components/DropDownMenuWithLabel.d.ts.map +1 -1
  87. package/dist/esm/components/DropDownMenuWithLabel.js +4 -35
  88. package/dist/esm/components/EmptyDashboardComponent/index.d.ts.map +1 -1
  89. package/dist/esm/components/EmptyDashboardComponent/index.js +11 -9
  90. package/dist/esm/components/QuillSelect.d.ts.map +1 -1
  91. package/dist/esm/components/QuillSelect.js +2 -2
  92. package/dist/esm/components/SegmentedControl.d.ts +4 -2
  93. package/dist/esm/components/SegmentedControl.d.ts.map +1 -1
  94. package/dist/esm/components/SegmentedControl.js +22 -16
  95. package/dist/esm/components/SqlTextEditor.d.ts +9 -1
  96. package/dist/esm/components/SqlTextEditor.d.ts.map +1 -1
  97. package/dist/esm/components/SqlTextEditor.js +59 -11
  98. package/dist/esm/components/UiComponents.d.ts.map +1 -1
  99. package/dist/esm/components/UiComponents.js +12 -3
  100. package/dist/esm/constants/dataTypes.d.ts +2 -0
  101. package/dist/esm/constants/dataTypes.d.ts.map +1 -0
  102. package/dist/esm/constants/dataTypes.js +18 -0
  103. package/dist/esm/forms/client_onboard/ConnectDatabase.d.ts.map +1 -1
  104. package/dist/esm/forms/client_onboard/ConnectDatabase.js +9 -17
  105. package/dist/esm/forms/client_onboard/CreateSqlViews.d.ts.map +1 -1
  106. package/dist/esm/forms/client_onboard/CreateSqlViews.js +25 -12
  107. package/dist/esm/forms/sql_views/CreateEditSqlView.d.ts +4 -1
  108. package/dist/esm/forms/sql_views/CreateEditSqlView.d.ts.map +1 -1
  109. package/dist/esm/forms/sql_views/CreateEditSqlView.js +87 -36
  110. package/dist/esm/modals/EditFiltersModal.d.ts.map +1 -1
  111. package/dist/esm/modals/EditFiltersModal.js +13 -3
  112. package/dist/esm/modals/NewDashboardModal.js +2 -2
  113. package/dist/esm/modals/PromoteDashModal.js +2 -2
  114. package/dist/esm/modals/PromoteViewModal.d.ts +2 -1
  115. package/dist/esm/modals/PromoteViewModal.d.ts.map +1 -1
  116. package/dist/esm/modals/PromoteViewModal.js +50 -40
  117. package/dist/esm/primitives/TextInputPrimitive.d.ts +1 -0
  118. package/dist/esm/primitives/TextInputPrimitive.d.ts.map +1 -1
  119. package/dist/esm/primitives/TextInputPrimitive.js +33 -21
  120. package/dist/esm/public_components/CreateEnvironment.d.ts +2 -1
  121. package/dist/esm/public_components/CreateEnvironment.d.ts.map +1 -1
  122. package/dist/esm/public_components/CreateEnvironment.js +4 -1
  123. package/dist/esm/public_components/DashboardBuilder.d.ts.map +1 -1
  124. package/dist/esm/public_components/DashboardBuilder.js +68 -157
  125. package/dist/esm/public_components/DashboardManager.d.ts.map +1 -1
  126. package/dist/esm/public_components/DashboardManager.js +73 -74
  127. package/dist/esm/public_components/SQLViewManager.d.ts +1 -0
  128. package/dist/esm/public_components/SQLViewManager.d.ts.map +1 -1
  129. package/dist/esm/public_components/SQLViewManager.js +216 -42
  130. package/dist/esm/utils/astProcessing.d.ts +2 -0
  131. package/dist/esm/utils/astProcessing.d.ts.map +1 -0
  132. package/dist/esm/utils/astProcessing.js +37 -0
  133. package/dist/esm/utils/astProcessing.uspec.d.ts +2 -0
  134. package/dist/esm/utils/astProcessing.uspec.d.ts.map +1 -0
  135. package/dist/esm/utils/astProcessing.uspec.js +24 -0
  136. package/dist/esm/utils/columnProcessing.d.ts +3 -0
  137. package/dist/esm/utils/columnProcessing.d.ts.map +1 -0
  138. package/dist/esm/utils/columnProcessing.js +37 -0
  139. package/dist/esm/utils/dataEditor.d.ts +2 -2
  140. package/dist/esm/utils/dataEditor.d.ts.map +1 -1
  141. package/dist/esm/utils/dataEditor.js +4 -2
  142. package/dist/esm/utils/databases.d.ts +0 -1
  143. package/dist/esm/utils/databases.d.ts.map +1 -1
  144. package/dist/esm/utils/databases.js +5 -6
  145. package/dist/esm/utils/monacoAutocomplete.d.ts +21 -0
  146. package/dist/esm/utils/monacoAutocomplete.d.ts.map +1 -0
  147. package/dist/esm/utils/monacoAutocomplete.js +245 -0
  148. package/dist/esm/utils/schema.d.ts +5 -0
  149. package/dist/esm/utils/schema.d.ts.map +1 -1
  150. package/dist/esm/utils/schema.js +126 -1
  151. package/package.json +3 -2
@@ -6,9 +6,30 @@ import { EnvSelectPopover } from '../components';
6
6
  import { TableCell } from '../Admin';
7
7
  import CreateEditSqlView from '../forms/sql_views/CreateEditSqlView';
8
8
  import { addSqlView, editSQLView, deleteSQLView } from '../utils/dataEditor';
9
- import { getTableColumnsBySchema } from '../api/ConnectionClient';
10
- import { MemoizedButton, MemoizedDeleteButton, MemoizedSecondaryButton, } from '../components/UiComponents';
9
+ import { getSqlViewData, getTableColumnsBySchema, } from '../api/ConnectionClient';
10
+ import { LoadingSpinner, MemoizedButton, MemoizedDeleteButton, MemoizedModal, MemoizedSecondaryButton, } from '../components/UiComponents';
11
11
  import DatabaseMismatchCard from '../components/DatabaseMismatchCard';
12
+ import TogglePrimitive from '../primitives/TogglePrimitive';
13
+ import { SegmentedControl } from '../components/SegmentedControl';
14
+ import SqlTextEditor from '../components/SqlTextEditor';
15
+ import { Table } from '@quillsql/react';
16
+ import { getSchemaInfo } from '../utils/schema';
17
+ import { PromoteViewModal } from '../modals';
18
+ export const getDuplicateColumns = (columns) => {
19
+ if (!columns) {
20
+ return [];
21
+ }
22
+ const columnCount = columns?.reduce((acc, curr) => {
23
+ if (acc[curr.field]) {
24
+ acc[curr.field] += 1;
25
+ }
26
+ else {
27
+ acc[curr.field] = 1;
28
+ }
29
+ return acc;
30
+ }, {});
31
+ return Object.keys(columnCount).filter((column) => columnCount[column] > 1);
32
+ };
12
33
  export default function SQLViewManager({ containerStyle, }) {
13
34
  const [tables, setTables] = useState(undefined);
14
35
  const [modalIsOpen, setIsOpen] = useState(false);
@@ -26,13 +47,17 @@ export default function SQLViewManager({ containerStyle, }) {
26
47
  const [allTableData, setAllTableData] = useState([]);
27
48
  const [referencedTablesMap, setReferencedTablesMap] = useState({});
28
49
  const [schemaIsLoading, setSchemaIsLoading] = useState(false);
50
+ const [customFieldInfo, setCustomFieldInfo] = useState(undefined);
51
+ const [provider, setProvider] = useState(null);
29
52
  const [initialSqlView, setInitialSqlView] = useState(undefined);
53
+ const [submittingView, setSubmittingView] = useState(false);
30
54
  const parentRef = useRef(null);
31
55
  const { state, dispatch } = useAdmin();
32
56
  const closeEditModal = () => {
33
57
  setEditModalIsOpen(false);
34
58
  setEditName('');
35
59
  setEditViewQuery('');
60
+ setCustomFieldInfo(undefined);
36
61
  };
37
62
  const clickTableCell = (table) => {
38
63
  setEditName(table.name);
@@ -43,29 +68,18 @@ export default function SQLViewManager({ containerStyle, }) {
43
68
  name: table.name,
44
69
  query: table.viewQuery,
45
70
  });
71
+ setCustomFieldInfo(table.customFieldInfo);
46
72
  setEditModalIsOpen(true);
47
73
  };
48
74
  const getTables = async () => {
49
- const response = await fetch(`${state.queryEndpoint}`, {
50
- method: 'POST',
51
- headers: {
52
- ...state.queryHeaders,
53
- 'Content-Type': 'application/json',
54
- },
55
- body: JSON.stringify({
56
- metadata: {
57
- clientId: state.client._id,
58
- publicKey: state.client._id,
59
- task: 'schema',
60
- databaseType: state.client.databaseType,
61
- },
62
- }),
63
- });
64
- if (!response.ok) {
65
- throw new Error('Failed to fetch tables data');
66
- }
67
- const data = await response.json();
68
- setTables(data.data.tables);
75
+ const schemaData = await getSchemaInfo({
76
+ queryEndpoint: state.queryEndpoint,
77
+ queryHeaders: state.queryHeaders,
78
+ publicKey: state.client._id,
79
+ customerId: state.client.customerId,
80
+ gatherSchemaData: false,
81
+ }, 'svm');
82
+ setTables(schemaData);
69
83
  };
70
84
  const getSchemaTableDetails = async () => {
71
85
  setSchemaIsLoading(true);
@@ -106,7 +120,7 @@ export default function SQLViewManager({ containerStyle, }) {
106
120
  isSubscribed = false;
107
121
  };
108
122
  }, [state.client]);
109
- const handleModalSubmit = async (submitRequest, query, name, id, columns) => {
123
+ const handleModalSubmit = async (submitRequest, query, name, id, columns, customFieldInfo) => {
110
124
  try {
111
125
  const prevTableName = tables?.find((table) => table._id === id)?.name;
112
126
  const isPlural = referencedTablesMap &&
@@ -114,21 +128,29 @@ export default function SQLViewManager({ containerStyle, }) {
114
128
  referencedTablesMap[prevTableName].length > 1
115
129
  ? 's'
116
130
  : '';
131
+ let trimmedName = name?.trim() || undefined;
132
+ let submitResponse;
117
133
  switch (submitRequest) {
118
134
  case 'add':
119
- if (!name) {
135
+ if (!trimmedName) {
120
136
  alert('No name found');
121
137
  return;
122
138
  }
123
- if (tables?.map((table) => table.name).includes(name)) {
139
+ if (tables?.map((table) => table.name).includes(trimmedName)) {
124
140
  alert('Name already exists');
125
141
  return;
126
142
  }
127
- if (!/^[a-z0-9_]+$/.test(name)) {
128
- alert('Name must be lowercase with no spaces');
143
+ // determine if there are duplicate names if there are then alert the user
144
+ let duplicateColumns = getDuplicateColumns(columns);
145
+ if (duplicateColumns.length > 0) {
146
+ alert(`Ambiguous column names found. Either use aliases or remove the column to make every column name unique: \n\n${duplicateColumns.join('\n')}`);
129
147
  return;
130
148
  }
131
- await addSqlView(name, query, state);
149
+ if (!/^[a-z0-9_]+$/.test(trimmedName)) {
150
+ alert('Names can only include lowercase letters, numbers, and underscores');
151
+ return;
152
+ }
153
+ submitResponse = await addSqlView(trimmedName, query, customFieldInfo, state);
132
154
  break;
133
155
  case 'edit':
134
156
  if (!id) {
@@ -160,23 +182,29 @@ export default function SQLViewManager({ containerStyle, }) {
160
182
  return;
161
183
  }
162
184
  }
163
- if (!name) {
185
+ if (!trimmedName) {
164
186
  alert('No name found');
165
187
  return;
166
188
  }
167
- if (!/^[a-z0-9_]+$/.test(name)) {
189
+ if (!/^[a-z0-9_]+$/.test(trimmedName)) {
168
190
  alert('Names can only include lowercase letters, numbers, and underscores');
169
191
  return;
170
192
  }
193
+ // determine if there are duplicate names if there are then alert the user
194
+ const duplicateColumns2 = getDuplicateColumns(columns);
195
+ if (duplicateColumns2.length > 0) {
196
+ alert(`Ambiguous column names found. Either use aliases or remove the column to make every column name unique: \n\n${duplicateColumns2.join('\n')}`);
197
+ return;
198
+ }
171
199
  // check if the tableName is present excluding the table with the same id
172
200
  if (tables
173
201
  ?.filter((table) => table._id !== id)
174
202
  .map((table) => table.name)
175
- .includes(name)) {
203
+ .includes(trimmedName)) {
176
204
  alert('Name already exists');
177
205
  return;
178
206
  }
179
- await editSQLView(name, query, id, state);
207
+ submitResponse = await editSQLView(trimmedName, query, id, customFieldInfo, state);
180
208
  break;
181
209
  case 'delete':
182
210
  if (!id) {
@@ -185,10 +213,13 @@ export default function SQLViewManager({ containerStyle, }) {
185
213
  }
186
214
  // Determine if the table is referenced in other charts
187
215
  if (referencedTablesMap && referencedTablesMap[prevTableName]) {
188
- alert(`This table is referenced in the following dashboard${isPlural}/chart${isPlural}.\n\n${referencedTablesMap[prevTableName]?.join('\n')} \n\nPlease delete those charts before deleting this table.`);
216
+ const referencedTableInfo = referencedTablesMap[prevTableName].map((info) => {
217
+ return `${info.dashboardName} - ${info.reportName}`;
218
+ });
219
+ alert(`This table is referenced in the following dashboard${isPlural}/chart${isPlural}.\n\n${referencedTableInfo.join('\n')} \n\nPlease delete those charts before deleting this table.`);
189
220
  return;
190
221
  }
191
- await deleteSQLView(id, state);
222
+ submitResponse = await deleteSQLView(id, state);
192
223
  break;
193
224
  default:
194
225
  setEditName('');
@@ -197,6 +228,10 @@ export default function SQLViewManager({ containerStyle, }) {
197
228
  setEditModalIsOpen(true);
198
229
  return;
199
230
  }
231
+ if (submitResponse.status !== 'success') {
232
+ alert(`There was an error processing your ${submitRequest} request.`);
233
+ return;
234
+ }
200
235
  await getTables();
201
236
  closeEditModal();
202
237
  setEditQueryView(false);
@@ -211,7 +246,7 @@ export default function SQLViewManager({ containerStyle, }) {
211
246
  await handleModalSubmit('edit', query, name, id, columns);
212
247
  break;
213
248
  default:
214
- await handleModalSubmit('final-edit', query);
249
+ await handleModalSubmit('final-edit', query, undefined, undefined, columns);
215
250
  break;
216
251
  }
217
252
  };
@@ -282,12 +317,29 @@ export default function SQLViewManager({ containerStyle, }) {
282
317
  ? tables.map((table) => (_jsx(TableCell, { table: table, clickTableCell: clickTableCell }, table._id)))
283
318
  : null }, 'edit-view-query')) : (_jsx(CreateEditSqlView, { containerStyle: {}, initialSqlView: initialSqlView, closeEditView: () => setEditQueryView(false), addEditView: (request, name, query, id, columns) => {
284
319
  handleEditAddView(request, name, query, id, columns);
285
- }, allTableData: allTableData, schemaIsLoading: schemaIsLoading })) }))] }), _jsx(EditAddViewModal, { viewName: editName, viewQuery: editViewQuery, viewId: editViewId, editModalIsOpen: editModalIsOpen, closeEditModal: closeEditModal, submit: handleModalSubmit, state: state, onEditViewClick: () => setEditQueryView(true) })] }));
320
+ }, setProvider: (provider) => { setProvider(provider); }, provider: provider, allTableData: allTableData, schemaIsLoading: schemaIsLoading })) }))] }), _jsx(PromoteViewModal, { clientId: state.client._id, client: state.client, clients: state.clients, isOpen: isPromoteViewModalOpen, setIsOpen: setIsPromoteViewModalOpen, ModalComponent: MemoizedModal, views: tables || [], parentRef: parentRef }), _jsx(EditAddViewModal, { viewName: editName, viewQuery: editViewQuery, viewId: editViewId, editModalIsOpen: editModalIsOpen, customFieldInfo: customFieldInfo, closeEditModal: closeEditModal, submit: async (submitRequest, query, name, id, columns, customFieldInfo) => {
321
+ if (submitRequest !== 'delete') {
322
+ setSubmittingView(true);
323
+ }
324
+ await handleModalSubmit(submitRequest, query, name, id, columns, customFieldInfo);
325
+ setSubmittingView(false);
326
+ }, state: state, onEditViewClick: () => setEditQueryView(true), isLoading: submittingView })] }));
286
327
  }
287
- function EditAddViewModal({ viewName, viewQuery, viewId, editModalIsOpen, closeEditModal, submit, state, onEditViewClick = () => { }, }) {
328
+ function EditAddViewModal({ viewName, viewQuery, viewId, editModalIsOpen, customFieldInfo, closeEditModal, submit, state, onEditViewClick = () => { }, isLoading, }) {
288
329
  const [name, setName] = useState(viewName);
289
330
  const [query, setQuery] = useState(viewQuery);
290
331
  const [id, setId] = useState(viewId);
332
+ const [useCustomField, setUseCustomField] = useState(customFieldInfo ? true : false);
333
+ const [customFieldType, setCustomFieldType] = useState(customFieldInfo ? customFieldInfo.type : 'eav');
334
+ const [customFieldQuery, setCustomFieldQuery] = useState(customFieldInfo ? customFieldInfo.query : '');
335
+ const [runQueryButtonLoading, setRunQueryButtonLoading] = useState(false);
336
+ const [tableData, setTableData] = useState(undefined);
337
+ const [errorInfo, setErrorInfo] = useState({ show: false, message: '' });
338
+ useEffect(() => {
339
+ setCustomFieldQuery(customFieldInfo?.query || '');
340
+ setCustomFieldType(customFieldInfo?.type || 'eav');
341
+ setUseCustomField(customFieldInfo ? true : false);
342
+ }, [customFieldInfo]);
291
343
  useEffect(() => {
292
344
  setName(viewName);
293
345
  }, [viewName]);
@@ -297,7 +349,15 @@ function EditAddViewModal({ viewName, viewQuery, viewId, editModalIsOpen, closeE
297
349
  useEffect(() => {
298
350
  setId(viewId);
299
351
  }, [viewId]);
300
- return (_jsx(ModalPrimitive, { isOpen: editModalIsOpen, close: closeEditModal, children: _jsxs("div", { className: "flex flex-col p-[6px]", children: [_jsxs("div", { style: {
352
+ return (_jsx(ModalPrimitive, { isOpen: editModalIsOpen, close: () => {
353
+ setUseCustomField(false);
354
+ setCustomFieldType('eav');
355
+ setCustomFieldQuery('');
356
+ setTableData(undefined);
357
+ setErrorInfo({ show: false, message: '' });
358
+ setName('');
359
+ closeEditModal();
360
+ }, children: _jsxs("div", { style: { height: '100%', overflow: 'scroll', width: '100%' }, children: [_jsxs("div", { style: {
301
361
  display: 'flex',
302
362
  flexDirection: 'row',
303
363
  alignItems: 'center',
@@ -330,7 +390,6 @@ function EditAddViewModal({ viewName, viewQuery, viewId, editModalIsOpen, closeE
330
390
  fontWeight: 'medium',
331
391
  height: '120px',
332
392
  boxShadow: '0 1px 2px 0 rgba(0,0,0,.05)',
333
- width: '500px',
334
393
  background: 'linear-gradient(white 50%, transparent)',
335
394
  color: state.theme?.primaryTextColor,
336
395
  borderWidth: '1px',
@@ -364,7 +423,81 @@ function EditAddViewModal({ viewName, viewQuery, viewId, editModalIsOpen, closeE
364
423
  } }), viewName && (_jsx("div", { style: { position: 'absolute', bottom: '10px', right: '10px' }, children: _jsx(MemoizedSecondaryButton, { label: 'Edit Query ↗', onClick: () => {
365
424
  closeEditModal();
366
425
  onEditViewClick();
367
- } }) }))] }), _jsxs("div", { style: {
426
+ } }) }))] }), _jsx("br", {}), ['65d65b57cdd8ae70a5648d9c', '665610862cf7a3000be66453'].includes(state.client._id) &&
427
+ state.client.databaseType === 'PostgreSQL' && (_jsxs(_Fragment, { children: [_jsx("h3", { style: {
428
+ fontWeight: '600',
429
+ fontSize: '14px',
430
+ marginBottom: '6px',
431
+ color: '#212121',
432
+ }, children: "Custom fields" }), _jsx(TogglePrimitive, { value: useCustomField, onClick: () => {
433
+ setUseCustomField((useCustomField) => !useCustomField);
434
+ } }), _jsx("br", {}), useCustomField && (_jsxs(_Fragment, { children: [_jsx("h3", { style: {
435
+ fontWeight: '600',
436
+ fontSize: '14px',
437
+ marginBottom: '6px',
438
+ marginTop: '20px',
439
+ color: '#212121',
440
+ }, children: "Custom field type" }), _jsx(SegmentedControl, { theme: state.theme, value: customFieldType, onChange: (e) => {
441
+ setCustomFieldType(e);
442
+ }, left: 'EAV', right: 'JSON' }), _jsx("br", {}), _jsx("h3", { style: {
443
+ fontWeight: '600',
444
+ fontSize: '14px',
445
+ marginBottom: '6px',
446
+ color: '#212121',
447
+ }, children: "Custom field query" }), _jsx("h3", { style: {
448
+ fontWeight: '400',
449
+ fontSize: '14px',
450
+ marginBottom: '20px',
451
+ color: '#212121',
452
+ }, children: customFieldType === 'eav'
453
+ ? `A table of custom fields. It must have these columns: ref_table, ref_id, field, value, type, ${state.client.customerFieldName.replaceAll('"', '')}.`
454
+ : `A table of custom fields. It must have these columns: ref_table, ref_column, field, ${state.client.customerFieldName.replaceAll('"', '')}.` }), _jsx(SqlTextEditor, { value: customFieldQuery, setValue: (e) => {
455
+ setCustomFieldQuery(e);
456
+ }, setEditorMounted: () => { }, containerStyle: {
457
+ width: 800,
458
+ }, previousProvider: null, height: '150px', schema: [] }), _jsx("br", {}), _jsx(MemoizedButton, { label: 'Run query', onClick: async () => {
459
+ if (/limit\s+\d+\s*;?\s*$/i.test(customFieldQuery)) {
460
+ setErrorInfo({
461
+ show: true,
462
+ message: 'Error: Please remove the limit at the end of your query.',
463
+ });
464
+ return;
465
+ }
466
+ setErrorInfo({ show: false, message: '' });
467
+ setRunQueryButtonLoading(true);
468
+ const getSqlResults = await getSqlViewData(state.client._id, customFieldQuery, state.client.databaseType, state.queryEndpoint);
469
+ if (!getSqlResults.success) {
470
+ setErrorInfo({
471
+ show: true,
472
+ message: getSqlResults.error,
473
+ });
474
+ }
475
+ else {
476
+ setErrorInfo({ show: false, message: '' });
477
+ setTableData(getSqlResults);
478
+ }
479
+ setRunQueryButtonLoading(false);
480
+ } }), _jsx("br", {}), runQueryButtonLoading && (_jsx("div", { style: {
481
+ height: '250px',
482
+ width: '100%',
483
+ display: 'flex',
484
+ justifyContent: 'center',
485
+ alignItems: 'center',
486
+ }, children: _jsx(LoadingSpinner, {}) })), !errorInfo.show && tableData && !runQueryButtonLoading && (_jsx(Table, { rows: tableData.rows, columns: tableData.fields, containerStyle: {
487
+ height: '250px',
488
+ maxWidth: '800px',
489
+ paddingTop: '20px',
490
+ }, hideCSVDownloadButton: true })), errorInfo.show && (_jsx("div", { style: {
491
+ fontSize: 15,
492
+ fontWeight: '400',
493
+ paddingTop: '20px',
494
+ }, children: _jsx("div", { style: {
495
+ padding: 30,
496
+ background: 'rgba(0,0,0,0.02)',
497
+ display: 'inline-block',
498
+ flex: 0,
499
+ borderRadius: 6,
500
+ }, children: errorInfo.message }) }))] }))] })), _jsxs("div", { style: {
368
501
  display: 'flex',
369
502
  flexDirection: 'row',
370
503
  alignItems: 'center',
@@ -376,6 +509,47 @@ function EditAddViewModal({ viewName, viewQuery, viewId, editModalIsOpen, closeE
376
509
  alert('Please enter a name');
377
510
  return;
378
511
  }
379
- submit(viewName ? 'edit' : 'add', query, name, id);
380
- }, label: viewName ? 'Save changes' : 'Create view' })] })] }) }));
512
+ if (useCustomField) {
513
+ const fields = tableData?.fields.map((field) => field.field);
514
+ const missingFields = [];
515
+ if (!fields) {
516
+ alert('Custom field query is missing required columns');
517
+ return;
518
+ }
519
+ if (customFieldType === 'eav') {
520
+ // make sure the tableData has the required columns
521
+ [
522
+ 'ref_table',
523
+ 'ref_id',
524
+ 'field',
525
+ 'value',
526
+ 'type',
527
+ state.client.customerFieldName.replaceAll('"', ''),
528
+ ].forEach((requiredField) => {
529
+ if (!fields.includes(requiredField)) {
530
+ missingFields.push(requiredField);
531
+ }
532
+ });
533
+ }
534
+ else {
535
+ [
536
+ 'ref_table',
537
+ 'field',
538
+ 'ref_column',
539
+ state.client.customerFieldName.replaceAll('"', ''),
540
+ ].forEach((requiredField) => {
541
+ if (!fields.includes(requiredField)) {
542
+ missingFields.push(requiredField);
543
+ }
544
+ });
545
+ }
546
+ if (missingFields.length > 0) {
547
+ alert(`Custom field query is missing required columns: ${missingFields.join(', ')}`);
548
+ return;
549
+ }
550
+ }
551
+ submit(viewName ? 'edit' : 'add', query, name, id, undefined, useCustomField
552
+ ? { type: customFieldType, query: customFieldQuery }
553
+ : undefined);
554
+ }, label: viewName ? 'Save changes' : 'Create view', isLoading: isLoading })] })] }) }));
381
555
  }
@@ -0,0 +1,2 @@
1
+ export declare function processJoinASTWithDuplicateColumns(duplicateColumnsNames: string[], tableNames: string[], schema: any, ast: any): any;
2
+ //# sourceMappingURL=astProcessing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"astProcessing.d.ts","sourceRoot":"","sources":["../../../src/utils/astProcessing.ts"],"names":[],"mappings":"AAAA,wBAAgB,kCAAkC,CAChD,qBAAqB,EAAE,MAAM,EAAE,EAC/B,UAAU,EAAE,MAAM,EAAE,EACpB,MAAM,EAAE,GAAG,EACX,GAAG,EAAE,GAAG,OAsCT"}
@@ -0,0 +1,37 @@
1
+ export function processJoinASTWithDuplicateColumns(duplicateColumnsNames, tableNames, schema, ast) {
2
+ const columns = [];
3
+ schema.forEach((table) => {
4
+ if (tableNames.includes(table.tableName)) {
5
+ table.columns.forEach((column) => {
6
+ let tableName = table.tableName;
7
+ if (table.tableName.includes('.')) {
8
+ tableName = table.tableName.split('.')[1] || table.tableName;
9
+ }
10
+ if (duplicateColumnsNames.includes(column.columnName)) {
11
+ columns.push({
12
+ type: 'expr',
13
+ as: `${tableName}_${column.columnName}`,
14
+ expr: {
15
+ type: 'column_ref',
16
+ table: tableName,
17
+ column: column.columnName,
18
+ },
19
+ });
20
+ }
21
+ else {
22
+ columns.push({
23
+ type: 'expr',
24
+ as: null,
25
+ expr: {
26
+ type: 'column_ref',
27
+ table: tableName,
28
+ column: column.columnName,
29
+ },
30
+ });
31
+ }
32
+ });
33
+ }
34
+ });
35
+ ast.columns = columns;
36
+ return ast;
37
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=astProcessing.uspec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"astProcessing.uspec.d.ts","sourceRoot":"","sources":["../../../src/utils/astProcessing.uspec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,24 @@
1
+ import { processJoinASTWithDuplicateColumns } from "./astProcessing";
2
+ describe('astProcessing', () => {
3
+ describe('processJoinASTWithDuplicateColumns', () => {
4
+ it('should return a new ast object with unambiguous columns', () => {
5
+ const dummyAst = { where: 'dummy where' };
6
+ const tableNames = ['table1', 'table2'];
7
+ const duplicateColumns = ['amount'];
8
+ const schema = [
9
+ {
10
+ tableName: 'table1',
11
+ columns: [{ columnName: 'amount' }, { columnName: 'name' }],
12
+ },
13
+ {
14
+ tableName: 'table2',
15
+ columns: [{ columnName: 'amount' }, { columnName: 'other_name' }],
16
+ },
17
+ ];
18
+ const resultAst = processJoinASTWithDuplicateColumns(duplicateColumns, tableNames, schema, dummyAst);
19
+ expect(resultAst.columns.length).toEqual(4);
20
+ expect(resultAst.columns[0].as).toEqual('table1_amount');
21
+ expect(resultAst.columns[1].as).toEqual(null);
22
+ });
23
+ });
24
+ });
@@ -0,0 +1,3 @@
1
+ export declare function convertFieldTypeToJSType(fieldType: string): string;
2
+ export declare function processColumnReference(column: string, databaseType: string): string;
3
+ //# sourceMappingURL=columnProcessing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"columnProcessing.d.ts","sourceRoot":"","sources":["../../../src/utils/columnProcessing.ts"],"names":[],"mappings":"AAAA,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAsBlE;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,UAa1E"}
@@ -0,0 +1,37 @@
1
+ export function convertFieldTypeToJSType(fieldType) {
2
+ switch (fieldType) {
3
+ case 'bool':
4
+ return 'bool';
5
+ case 'int8':
6
+ case 'int2':
7
+ case 'int4':
8
+ case 'float4':
9
+ case 'float8':
10
+ case 'numeric':
11
+ return 'number';
12
+ case 'date':
13
+ case 'time':
14
+ case 'timestamptz':
15
+ case 'timestamp':
16
+ return 'date';
17
+ case 'interval':
18
+ case 'varchar':
19
+ case 'text':
20
+ default:
21
+ return 'string';
22
+ }
23
+ }
24
+ export function processColumnReference(column, databaseType) {
25
+ if (['postgresql', 'snowflake'].includes(databaseType.toLowerCase())) {
26
+ const columnParts = column.split('.');
27
+ if (columnParts.length > 1) {
28
+ return `"${columnParts[0]}"."${columnParts[1]}"`;
29
+ }
30
+ return `"${column}"`;
31
+ }
32
+ const columnParts = column.split('.');
33
+ if (columnParts.length > 1) {
34
+ return `\`${columnParts[0]}\`.\`${columnParts[1]}\``;
35
+ }
36
+ return `\`${column}\``;
37
+ }
@@ -1,4 +1,4 @@
1
- export declare const editSQLView: (editName: string, editViewQuery: string, editViewId: string, state: any) => Promise<any>;
2
- export declare const addSqlView: (name: string, editViewQuery: string, state: any) => Promise<any>;
1
+ export declare const editSQLView: (editName: string, editViewQuery: string, editViewId: string, customFieldInfo: any, state: any) => Promise<any>;
2
+ export declare const addSqlView: (name: string, editViewQuery: string, customFieldInfo: any, state: any) => Promise<any>;
3
3
  export declare const deleteSQLView: (id: string, state: any) => Promise<any>;
4
4
  //# sourceMappingURL=dataEditor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dataEditor.d.ts","sourceRoot":"","sources":["../../../src/utils/dataEditor.tsx"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW,aACZ,MAAM,iBACD,MAAM,cACT,MAAM,SACX,GAAG,iBAsDX,CAAC;AAEF,eAAO,MAAM,UAAU,SACf,MAAM,iBACG,MAAM,SACd,GAAG,iBA+CX,CAAC;AAEF,eAAO,MAAM,aAAa,OAAc,MAAM,SAAS,GAAG,iBAmCzD,CAAC"}
1
+ {"version":3,"file":"dataEditor.d.ts","sourceRoot":"","sources":["../../../src/utils/dataEditor.tsx"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW,aACZ,MAAM,iBACD,MAAM,cACT,MAAM,mBACD,GAAG,SACb,GAAG,iBAuDX,CAAC;AAEF,eAAO,MAAM,UAAU,SACf,MAAM,iBACG,MAAM,mBACJ,GAAG,SACb,GAAG,iBAgDX,CAAC;AAEF,eAAO,MAAM,aAAa,OAAc,MAAM,SAAS,GAAG,iBAmCzD,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { QUILL_SERVER } from './constants';
2
- export const editSQLView = async (editName, editViewQuery, editViewId, state) => {
2
+ export const editSQLView = async (editName, editViewQuery, editViewId, customFieldInfo, state) => {
3
3
  if (!editName.length) {
4
4
  alert('Please enter a table name.');
5
5
  return;
@@ -24,6 +24,7 @@ export const editSQLView = async (editName, editViewQuery, editViewId, state) =>
24
24
  metadata: {
25
25
  preQueries: [editViewQuery.replace(/;/, '')],
26
26
  name: editName,
27
+ customFieldInfo: customFieldInfo,
27
28
  task: 'view',
28
29
  id: editViewId,
29
30
  clientId: state.client._id,
@@ -52,7 +53,7 @@ export const editSQLView = async (editName, editViewQuery, editViewId, state) =>
52
53
  }
53
54
  return await response.json();
54
55
  };
55
- export const addSqlView = async (name, editViewQuery, state) => {
56
+ export const addSqlView = async (name, editViewQuery, customFieldInfo, state) => {
56
57
  if (!name.length) {
57
58
  alert('Please enter a table name.');
58
59
  return;
@@ -72,6 +73,7 @@ export const addSqlView = async (name, editViewQuery, state) => {
72
73
  body: JSON.stringify({
73
74
  metadata: {
74
75
  preQueries: [editViewQuery.replace(/;/, '')],
76
+ customFieldInfo: customFieldInfo,
75
77
  name: name,
76
78
  task: 'view',
77
79
  clientId: state.client._id,
@@ -29,7 +29,6 @@ interface SnowflakeConnection extends DatabaseConnection {
29
29
  port: string;
30
30
  }
31
31
  interface BigQueryConnection extends DatabaseConnection {
32
- companyTag: string;
33
32
  jsonString: string;
34
33
  }
35
34
  export type ConnectionType = DatabaseConnection | PostgresConnection | MySQLConnection | SnowflakeConnection | BigQueryConnection;
@@ -1 +1 @@
1
- {"version":3,"file":"databases.d.ts","sourceRoot":"","sources":["../../../src/utils/databases.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,kBAAmB,SAAQ,kBAAkB;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,eAAgB,SAAQ,kBAAkB;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,mBAAoB,SAAQ,kBAAkB;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,kBAAmB,SAAQ,kBAAkB;IACrD,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,cAAc,GACtB,kBAAkB,GAClB,kBAAkB,GAClB,eAAe,GACf,mBAAmB,GACnB,kBAAkB,CAAC;AAEvB,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,qBAAqB,EAAE,mBAAmB,EAyBtD,CAAC;AAEF,wBAAgB,2BAA2B,CACzC,YAAY,EAAE,MAAM,GACnB,cAAc,GAAG,SAAS,CAwC5B;AAED,wBAAgB,oBAAoB,CAClC,UAAU,CAAC,EAAE,kBAAkB,EAC/B,QAAQ,CAAC,EAAE,IAAI,UAyBhB"}
1
+ {"version":3,"file":"databases.d.ts","sourceRoot":"","sources":["../../../src/utils/databases.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,kBAAmB,SAAQ,kBAAkB;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,eAAgB,SAAQ,kBAAkB;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,mBAAoB,SAAQ,kBAAkB;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,kBAAmB,SAAQ,kBAAkB;IACrD,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,cAAc,GACtB,kBAAkB,GAClB,kBAAkB,GAClB,eAAe,GACf,mBAAmB,GACnB,kBAAkB,CAAC;AAEvB,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,qBAAqB,EAAE,mBAAmB,EAyBtD,CAAC;AAEF,wBAAgB,2BAA2B,CACzC,YAAY,EAAE,MAAM,GACnB,cAAc,GAAG,SAAS,CAuC5B;AAED,wBAAgB,oBAAoB,CAClC,UAAU,CAAC,EAAE,kBAAkB,EAC/B,QAAQ,CAAC,EAAE,IAAI,UAkChB"}
@@ -58,7 +58,6 @@ export function getDatabaseConnectionFormat(databaseName) {
58
58
  return {
59
59
  type: 'BigQuery',
60
60
  connectionString: '',
61
- companyTag: '',
62
61
  jsonString: '',
63
62
  };
64
63
  }
@@ -69,26 +68,26 @@ export function formConnectionString(connection, jsonFile) {
69
68
  return 'There is no connection info';
70
69
  }
71
70
  if (connection.connectionString !== '') {
72
- return connection.connectionString;
71
+ return connection.connectionString.replaceAll(' ', '');
73
72
  }
74
73
  if (connection.type === 'PostgreSQL') {
75
74
  const typedConnection = connection;
76
- return `postgres://${typedConnection.user}:${typedConnection.password}@${typedConnection.host}:${typedConnection.port}/${typedConnection.databaseName}`;
75
+ return `postgres://${typedConnection.user}:${typedConnection.password}@${typedConnection.host}:${typedConnection.port}/${typedConnection.databaseName}`.replaceAll(' ', '');
77
76
  }
78
77
  else if (connection.type === 'mysql') {
79
78
  const typedConnection = connection;
80
- return `mysql://${typedConnection.user}:${typedConnection.password}@${typedConnection.host}:${typedConnection.port}`;
79
+ return `mysql://${typedConnection.user}:${typedConnection.password}@${typedConnection.host}:${typedConnection.port}`.replaceAll(' ', '');
81
80
  }
82
81
  else if (connection.type === 'snowflake') {
83
82
  const typedConnection = connection;
84
- return `mysql://${typedConnection.user}:${typedConnection.password}@${typedConnection.host}:${typedConnection.port}`;
83
+ return `mysql://${typedConnection.user}:${typedConnection.password}@${typedConnection.host}:${typedConnection.port}`.replaceAll(' ', '');
85
84
  }
86
85
  else if (connection.type === 'BigQuery') {
87
86
  const typedConnection = connection;
88
87
  const cleanedJsonString = typedConnection.jsonString
89
88
  .replace(/\\(?![n"])/g, '')
90
89
  .replace(/\n/g, '');
91
- return `${typedConnection.companyTag}${cleanedJsonString}`;
90
+ return cleanedJsonString;
92
91
  }
93
92
  return '';
94
93
  }