catalyst-relay 0.2.1 → 0.2.4

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.
package/dist/index.js CHANGED
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
+ buildSQLQuery: () => buildSQLQuery,
33
34
  createClient: () => createClient,
34
35
  err: () => err,
35
36
  ok: () => ok
@@ -125,93 +126,6 @@ function dictToAbapXml(data, root = "DATA") {
125
126
  </asx:abap>`;
126
127
  }
127
128
 
128
- // src/core/utils/sql.ts
129
- var SqlValidationError = class extends Error {
130
- constructor(message) {
131
- super(message);
132
- this.name = "SqlValidationError";
133
- }
134
- };
135
- function validateSqlInput(input, maxLength = 1e4) {
136
- if (typeof input !== "string") {
137
- return err(new SqlValidationError("Input must be a string"));
138
- }
139
- if (input.length > maxLength) {
140
- return err(new SqlValidationError(`Input exceeds maximum length of ${maxLength}`));
141
- }
142
- const dangerousPatterns = [
143
- {
144
- pattern: /\b(DROP|DELETE|INSERT|UPDATE|ALTER|CREATE|TRUNCATE)\s+/i,
145
- description: "DDL/DML keywords (DROP, DELETE, INSERT, etc.)"
146
- },
147
- {
148
- pattern: /;[\s]*\w/,
149
- description: "Statement termination followed by another statement"
150
- },
151
- {
152
- pattern: /--[\s]*\w/,
153
- description: "SQL comments with content"
154
- },
155
- {
156
- pattern: /\/\*.*?\*\//,
157
- description: "Block comments"
158
- },
159
- {
160
- pattern: /\bEXEC(UTE)?\s*\(/i,
161
- description: "Procedure execution"
162
- },
163
- {
164
- pattern: /\bSP_\w+/i,
165
- description: "Stored procedures"
166
- },
167
- {
168
- pattern: /\bXP_\w+/i,
169
- description: "Extended stored procedures"
170
- },
171
- {
172
- pattern: /\bUNION\s+(ALL\s+)?SELECT/i,
173
- description: "Union-based injection"
174
- },
175
- {
176
- pattern: /@@\w+/,
177
- description: "System variables"
178
- },
179
- {
180
- pattern: /\bDECLARE\s+@/i,
181
- description: "Variable declarations"
182
- },
183
- {
184
- pattern: /\bCAST\s*\(/i,
185
- description: "Type casting"
186
- },
187
- {
188
- pattern: /\bCONVERT\s*\(/i,
189
- description: "Type conversion"
190
- }
191
- ];
192
- for (const { pattern, description } of dangerousPatterns) {
193
- if (pattern.test(input)) {
194
- return err(new SqlValidationError(
195
- `Input contains potentially dangerous SQL pattern: ${description}`
196
- ));
197
- }
198
- }
199
- const specialCharMatches = input.match(/[;'"\\]/g);
200
- const specialCharCount = specialCharMatches ? specialCharMatches.length : 0;
201
- if (specialCharCount > 5) {
202
- return err(new SqlValidationError("Input contains excessive special characters"));
203
- }
204
- const singleQuoteCount = (input.match(/'/g) || []).length;
205
- if (singleQuoteCount % 2 !== 0) {
206
- return err(new SqlValidationError("Unbalanced single quotes detected"));
207
- }
208
- const doubleQuoteCount = (input.match(/"/g) || []).length;
209
- if (doubleQuoteCount % 2 !== 0) {
210
- return err(new SqlValidationError("Unbalanced double quotes detected"));
211
- }
212
- return ok(true);
213
- }
214
-
215
129
  // src/core/utils/csrf.ts
216
130
  var FETCH_CSRF_TOKEN = "fetch";
217
131
  var CSRF_TOKEN_HEADER = "x-csrf-token";
@@ -491,7 +405,7 @@ function requireConfig(extension) {
491
405
  return [config, null];
492
406
  }
493
407
 
494
- // src/core/adt/read.ts
408
+ // src/core/adt/craud/read.ts
495
409
  async function readObject(client, object) {
496
410
  const [config, configErr] = requireConfig(object.extension);
497
411
  if (configErr) return err(configErr);
@@ -515,7 +429,7 @@ async function readObject(client, object) {
515
429
  return ok(result);
516
430
  }
517
431
 
518
- // src/core/adt/lock.ts
432
+ // src/core/adt/craud/lock.ts
519
433
  async function lockObject(client, object) {
520
434
  const [config, configErr] = requireConfig(object.extension);
521
435
  if (configErr) return err(configErr);
@@ -563,7 +477,7 @@ async function unlockObject(client, object, lockHandle) {
563
477
  return ok(void 0);
564
478
  }
565
479
 
566
- // src/core/adt/create.ts
480
+ // src/core/adt/craud/create.ts
567
481
  async function createObject(client, object, packageName, transport, username) {
568
482
  const [config, configErr] = requireConfig(object.extension);
569
483
  if (configErr) return err(configErr);
@@ -600,7 +514,7 @@ async function createObject(client, object, packageName, transport, username) {
600
514
  return ok(void 0);
601
515
  }
602
516
 
603
- // src/core/adt/update.ts
517
+ // src/core/adt/craud/update.ts
604
518
  async function updateObject(client, object, lockHandle, transport) {
605
519
  const [config, configErr] = requireConfig(object.extension);
606
520
  if (configErr) return err(configErr);
@@ -628,7 +542,7 @@ async function updateObject(client, object, lockHandle, transport) {
628
542
  return ok(void 0);
629
543
  }
630
544
 
631
- // src/core/adt/delete.ts
545
+ // src/core/adt/craud/delete.ts
632
546
  async function deleteObject(client, object, lockHandle, transport) {
633
547
  const [config, configErr] = requireConfig(object.extension);
634
548
  if (configErr) return err(configErr);
@@ -653,7 +567,7 @@ async function deleteObject(client, object, lockHandle, transport) {
653
567
  return ok(void 0);
654
568
  }
655
569
 
656
- // src/core/adt/activation.ts
570
+ // src/core/adt/craud/activation.ts
657
571
  async function activateObjects(client, objects) {
658
572
  if (objects.length === 0) {
659
573
  return ok([]);
@@ -763,7 +677,7 @@ function extractActivationErrors(objects, xml, _extension) {
763
677
  return ok(results);
764
678
  }
765
679
 
766
- // src/core/adt/tree.ts
680
+ // src/core/adt/discovery/tree.ts
767
681
  async function getTree(client, query) {
768
682
  const internalQuery = {};
769
683
  if (query.package) {
@@ -880,7 +794,7 @@ function parseTreeResponse(xml) {
880
794
  return ok({ nodes, packages });
881
795
  }
882
796
 
883
- // src/core/adt/packages.ts
797
+ // src/core/adt/discovery/packages.ts
884
798
  async function getPackages(client) {
885
799
  const [treeResult, treeErr] = await getTreeInternal(client, {}, "*");
886
800
  if (treeErr) {
@@ -889,7 +803,7 @@ async function getPackages(client) {
889
803
  return ok(treeResult.packages);
890
804
  }
891
805
 
892
- // src/core/adt/transports.ts
806
+ // src/core/adt/transports/transports.ts
893
807
  async function getTransports(client, packageName) {
894
808
  const contentType = "application/vnd.sap.as+xml; charset=UTF-8; dataname=com.sap.adt.transport.service.checkData";
895
809
  const body = `<?xml version="1.0" encoding="UTF-8"?>
@@ -958,64 +872,7 @@ function extractTransports(xml) {
958
872
  return ok(transports);
959
873
  }
960
874
 
961
- // src/core/adt/queryBuilder.ts
962
- function buildWhereClauses(filters) {
963
- if (!filters || filters.length === 0) {
964
- return "";
965
- }
966
- const clauses = filters.map((filter) => {
967
- const { column, operator, value } = filter;
968
- switch (operator) {
969
- case "eq":
970
- return `${column} = ${formatValue(value)}`;
971
- case "ne":
972
- return `${column} != ${formatValue(value)}`;
973
- case "gt":
974
- return `${column} > ${formatValue(value)}`;
975
- case "ge":
976
- return `${column} >= ${formatValue(value)}`;
977
- case "lt":
978
- return `${column} < ${formatValue(value)}`;
979
- case "le":
980
- return `${column} <= ${formatValue(value)}`;
981
- case "like":
982
- return `${column} LIKE ${formatValue(value)}`;
983
- case "in":
984
- if (Array.isArray(value)) {
985
- const values = value.map((v) => formatValue(v)).join(", ");
986
- return `${column} IN (${values})`;
987
- }
988
- return `${column} IN (${formatValue(value)})`;
989
- default:
990
- return "";
991
- }
992
- }).filter((c) => c);
993
- if (clauses.length === 0) {
994
- return "";
995
- }
996
- return ` WHERE ${clauses.join(" AND ")}`;
997
- }
998
- function buildOrderByClauses(orderBy) {
999
- if (!orderBy || orderBy.length === 0) {
1000
- return "";
1001
- }
1002
- const clauses = orderBy.map((o) => `${o.column} ${o.direction.toUpperCase()}`);
1003
- return ` ORDER BY ${clauses.join(", ")}`;
1004
- }
1005
- function formatValue(value) {
1006
- if (value === null) {
1007
- return "NULL";
1008
- }
1009
- if (typeof value === "string") {
1010
- return `'${value.replace(/'/g, "''")}'`;
1011
- }
1012
- if (typeof value === "boolean") {
1013
- return value ? "1" : "0";
1014
- }
1015
- return String(value);
1016
- }
1017
-
1018
- // src/core/adt/previewParser.ts
875
+ // src/core/adt/data_extraction/previewParser.ts
1019
876
  function parseDataPreview(xml, maxRows, isTable) {
1020
877
  const [doc, parseErr] = safeParseXml(xml);
1021
878
  if (parseErr) {
@@ -1033,10 +890,18 @@ function parseDataPreview(xml, maxRows, isTable) {
1033
890
  if (!name || !dataType) continue;
1034
891
  columns.push({ name, dataType });
1035
892
  }
893
+ const dataSetElements = doc.getElementsByTagNameNS(namespace, "dataSet");
894
+ if (columns.length === 0 && dataSetElements.length > 0) {
895
+ for (let i = 0; i < dataSetElements.length; i++) {
896
+ const dataSet = dataSetElements[i];
897
+ if (!dataSet) continue;
898
+ const name = dataSet.getAttributeNS(namespace, "columnName") || dataSet.getAttribute("columnName") || `column${i}`;
899
+ columns.push({ name, dataType: "unknown" });
900
+ }
901
+ }
1036
902
  if (columns.length === 0) {
1037
- return err(new Error("No columns found in preview response"));
903
+ return ok({ columns: [], rows: [], totalRows: 0 });
1038
904
  }
1039
- const dataSetElements = doc.getElementsByTagNameNS(namespace, "dataSet");
1040
905
  const columnData = Array.from({ length: columns.length }, () => []);
1041
906
  for (let i = 0; i < dataSetElements.length; i++) {
1042
907
  const dataSet = dataSetElements[i];
@@ -1066,23 +931,16 @@ function parseDataPreview(xml, maxRows, isTable) {
1066
931
  return ok(dataFrame);
1067
932
  }
1068
933
 
1069
- // src/core/adt/data.ts
934
+ // src/core/adt/data_extraction/dataPreview.ts
1070
935
  async function previewData(client, query) {
1071
936
  const extension = query.objectType === "table" ? "astabldt" : "asddls";
1072
937
  const config = getConfigByExtension(extension);
1073
- if (!config || !config.dpEndpoint || !config.dpParam) {
938
+ if (!config?.dpEndpoint || !config?.dpParam) {
1074
939
  return err(new Error(`Data preview not supported for object type: ${query.objectType}`));
1075
940
  }
1076
941
  const limit = query.limit ?? 100;
1077
- const whereClauses = buildWhereClauses(query.filters);
1078
- const orderByClauses = buildOrderByClauses(query.orderBy);
1079
- const sqlQuery = `select * from ${query.objectName}${whereClauses}${orderByClauses}`;
1080
- const [, validationErr] = validateSqlInput(sqlQuery);
1081
- if (validationErr) {
1082
- return err(new Error(`SQL validation failed: ${validationErr.message}`));
1083
- }
1084
942
  debug(`Data preview: endpoint=${config.dpEndpoint}, param=${config.dpParam}=${query.objectName}`);
1085
- debug(`SQL: ${sqlQuery}`);
943
+ debug(`SQL: ${query.sqlQuery}`);
1086
944
  const [response, requestErr] = await client.request({
1087
945
  method: "POST",
1088
946
  path: `/sap/bc/adt/datapreview/${config.dpEndpoint}`,
@@ -1094,7 +952,7 @@ async function previewData(client, query) {
1094
952
  "Accept": "application/vnd.sap.adt.datapreview.table.v1+xml",
1095
953
  "Content-Type": "text/plain"
1096
954
  },
1097
- body: sqlQuery
955
+ body: query.sqlQuery
1098
956
  });
1099
957
  if (requestErr) {
1100
958
  return err(requestErr);
@@ -1113,119 +971,123 @@ async function previewData(client, query) {
1113
971
  return ok(dataFrame);
1114
972
  }
1115
973
 
1116
- // src/core/adt/distinct.ts
1117
- var MAX_ROW_COUNT = 5e4;
1118
- async function getDistinctValues(client, objectName, column, objectType = "view") {
1119
- const extension = objectType === "table" ? "astabldt" : "asddls";
1120
- const config = getConfigByExtension(extension);
1121
- if (!config || !config.dpEndpoint || !config.dpParam) {
1122
- return err(new Error(`Data preview not supported for object type: ${objectType}`));
1123
- }
1124
- const columnName = column.toUpperCase();
1125
- const sqlQuery = `SELECT ${columnName} AS value, COUNT(*) AS count FROM ${objectName} GROUP BY ${columnName}`;
1126
- const [, validationErr] = validateSqlInput(sqlQuery);
1127
- if (validationErr) {
1128
- return err(new Error(`SQL validation failed: ${validationErr.message}`));
1129
- }
1130
- const [response, requestErr] = await client.request({
1131
- method: "POST",
1132
- path: `/sap/bc/adt/datapreview/${config.dpEndpoint}`,
1133
- params: {
1134
- "rowNumber": MAX_ROW_COUNT,
1135
- [config.dpParam]: objectName
1136
- },
1137
- headers: {
1138
- "Accept": "application/vnd.sap.adt.datapreview.table.v1+xml"
1139
- },
1140
- body: sqlQuery
1141
- });
1142
- if (requestErr) {
1143
- return err(requestErr);
1144
- }
1145
- if (!response.ok) {
1146
- const text2 = await response.text();
1147
- const errorMsg = extractError(text2);
1148
- return err(new Error(`Distinct values query failed: ${errorMsg}`));
1149
- }
1150
- const text = await response.text();
1151
- const [doc, parseErr] = safeParseXml(text);
1152
- if (parseErr) {
1153
- return err(parseErr);
1154
- }
1155
- const dataSets = doc.getElementsByTagNameNS("http://www.sap.com/adt/dataPreview", "dataSet");
1156
- const values = [];
1157
- for (let i = 0; i < dataSets.length; i++) {
1158
- const dataSet = dataSets[i];
1159
- if (!dataSet) continue;
1160
- const dataElements = dataSet.getElementsByTagNameNS("http://www.sap.com/adt/dataPreview", "data");
1161
- if (dataElements.length < 2) continue;
1162
- const value = dataElements[0]?.textContent ?? "";
1163
- const countText = dataElements[1]?.textContent?.trim() ?? "0";
1164
- values.push({
1165
- value,
1166
- count: parseInt(countText, 10)
1167
- });
974
+ // src/core/adt/data_extraction/queryBuilder.ts
975
+ function quoteString(value) {
976
+ return typeof value == "string" ? "'" + value + "'" : "" + value;
977
+ }
978
+ function basicFilterToWhere(filter) {
979
+ return `${filter.field} ${filter.operator} ${quoteString(filter.value)}`;
980
+ }
981
+ function betweenFilterToWhere(filter) {
982
+ return `${filter.field} between ${quoteString(filter.minimum)} and ${quoteString(filter.maximum)}`;
983
+ }
984
+ function listFilterToWhere(filter) {
985
+ return `${filter.field} ${filter.include ? "" : "not "}in ( ${filter.values.map(quoteString).join(", ")} )`;
986
+ }
987
+ function queryFilterToWhere(filter) {
988
+ if (filter.type === "list") return listFilterToWhere(filter);
989
+ if (filter.type === "between") return betweenFilterToWhere(filter);
990
+ return basicFilterToWhere(filter);
991
+ }
992
+ function queryFiltersToWhere(filters) {
993
+ if (filters.length === 0) return "";
994
+ return `
995
+ where ${filters.map(queryFilterToWhere).join(" and ")}`;
996
+ }
997
+ function sortingsToOrderBy(sortings) {
998
+ if (sortings.length === 0) return "";
999
+ return `
1000
+ order by ${sortings.map((s) => `${s.field} ${s.direction}`).join(", ")}`;
1001
+ }
1002
+ function fieldsToGroupbyClause(fields) {
1003
+ if (fields.length === 0) return "";
1004
+ return `
1005
+ group by ${fields.join(", ")}`;
1006
+ }
1007
+ function aggregationToFieldDefinition(aggregation) {
1008
+ if (aggregation.function === "count") {
1009
+ return `count( distinct main~${aggregation.field} ) as ${aggregation.field}`;
1010
+ }
1011
+ return `${aggregation.function}( main~${aggregation.field} ) as ${aggregation.field}`;
1012
+ }
1013
+ function parametersToSQLParams(params) {
1014
+ if (params.length === 0) return "";
1015
+ return `( ${params.map((p) => `${p.name} = ${quoteString(p.value)}`).join(", ")})`;
1016
+ }
1017
+ function buildSQLQuery(query) {
1018
+ const [parameters, filters, sortings, aggregations] = [query.parameters ?? [], query.filters ?? [], query.sortings ?? [], query.aggregations ?? []];
1019
+ const groupingFields = query.fields.filter((f) => !aggregations.find((a) => a.field === f));
1020
+ if (sortings.filter((s) => !query.fields.includes(s.field)).length > 0) {
1021
+ return err(new Error("Sorting fields must be included in the selected fields."));
1022
+ }
1023
+ let selectClause = "select\n";
1024
+ const fieldSelections = [];
1025
+ for (const field of query.fields) {
1026
+ const aggregation = aggregations.find((a) => a.field === field);
1027
+ if (aggregation) {
1028
+ fieldSelections.push(` ${aggregationToFieldDefinition(aggregation)}`);
1029
+ continue;
1030
+ }
1031
+ fieldSelections.push(` main~${field}`);
1168
1032
  }
1033
+ selectClause += fieldSelections.join(",\n") + `
1034
+ from ${query.objectName}${parametersToSQLParams(parameters)} as main
1035
+ `;
1036
+ const [whereClause, groupbyClause, orderbyClause] = [queryFiltersToWhere(filters), aggregations.length ? fieldsToGroupbyClause(groupingFields) : "", sortingsToOrderBy(sortings)];
1169
1037
  const result = {
1170
- column,
1171
- values
1038
+ objectName: query.objectName,
1039
+ objectType: query.objectType,
1040
+ sqlQuery: `${selectClause}${whereClause}${groupbyClause}${orderbyClause}`
1172
1041
  };
1042
+ if (query.limit !== void 0) result.limit = query.limit;
1173
1043
  return ok(result);
1174
1044
  }
1175
1045
 
1176
- // src/core/adt/count.ts
1177
- async function countRows(client, objectName, objectType) {
1178
- const extension = objectType === "table" ? "astabldt" : "asddls";
1179
- const config = getConfigByExtension(extension);
1180
- if (!config || !config.dpEndpoint || !config.dpParam) {
1181
- return err(new Error(`Data preview not supported for object type: ${objectType}`));
1046
+ // src/core/adt/data_extraction/distinct.ts
1047
+ var MAX_ROW_COUNT = 5e4;
1048
+ async function getDistinctValues(client, objectName, parameters, column, objectType = "view") {
1049
+ const columnName = column.toUpperCase();
1050
+ const sqlQuery = `SELECT ${columnName} AS value, COUNT(*) AS ValueCount FROM ${objectName}${parametersToSQLParams(parameters)} GROUP BY ${columnName} ORDER BY ValueCount DESCENDING`;
1051
+ const [dataFrame, error] = await previewData(client, {
1052
+ objectName,
1053
+ objectType,
1054
+ sqlQuery,
1055
+ limit: MAX_ROW_COUNT
1056
+ });
1057
+ if (error) {
1058
+ return err(new Error(`Distinct values query failed: ${error.message}`));
1182
1059
  }
1060
+ const values = dataFrame.rows.map((row) => ({
1061
+ value: row[0],
1062
+ count: parseInt(String(row[1]), 10)
1063
+ }));
1064
+ return ok({ column, values });
1065
+ }
1066
+
1067
+ // src/core/adt/data_extraction/count.ts
1068
+ async function countRows(client, objectName, objectType) {
1183
1069
  const sqlQuery = `SELECT COUNT(*) AS count FROM ${objectName}`;
1184
- const [, validationErr] = validateSqlInput(sqlQuery);
1185
- if (validationErr) {
1186
- return err(new Error(`SQL validation failed: ${validationErr.message}`));
1187
- }
1188
- const [response, requestErr] = await client.request({
1189
- method: "POST",
1190
- path: `/sap/bc/adt/datapreview/${config.dpEndpoint}`,
1191
- params: {
1192
- "rowNumber": 1,
1193
- [config.dpParam]: objectName
1194
- },
1195
- headers: {
1196
- "Accept": "application/vnd.sap.adt.datapreview.table.v1+xml"
1197
- },
1198
- body: sqlQuery
1070
+ const [dataFrame, error] = await previewData(client, {
1071
+ objectName,
1072
+ objectType,
1073
+ sqlQuery,
1074
+ limit: 1
1199
1075
  });
1200
- if (requestErr) {
1201
- return err(requestErr);
1202
- }
1203
- if (!response.ok) {
1204
- const text2 = await response.text();
1205
- const errorMsg = extractError(text2);
1206
- return err(new Error(`Row count query failed: ${errorMsg}`));
1076
+ if (error) {
1077
+ return err(new Error(`Row count query failed: ${error.message}`));
1207
1078
  }
1208
- const text = await response.text();
1209
- const [doc, parseErr] = safeParseXml(text);
1210
- if (parseErr) {
1211
- return err(parseErr);
1212
- }
1213
- const dataElements = doc.getElementsByTagNameNS("http://www.sap.com/adt/dataPreview", "data");
1214
- if (dataElements.length === 0) {
1079
+ const countValue = dataFrame.rows[0]?.[0];
1080
+ if (countValue === void 0) {
1215
1081
  return err(new Error("No count value returned"));
1216
1082
  }
1217
- const countText = dataElements[0]?.textContent?.trim();
1218
- if (!countText) {
1219
- return err(new Error("Empty count value returned"));
1220
- }
1221
- const count = parseInt(countText, 10);
1083
+ const count = parseInt(String(countValue), 10);
1222
1084
  if (isNaN(count)) {
1223
1085
  return err(new Error("Invalid count value returned"));
1224
1086
  }
1225
1087
  return ok(count);
1226
1088
  }
1227
1089
 
1228
- // src/core/adt/searchObjects.ts
1090
+ // src/core/adt/discovery/searchObjects.ts
1229
1091
  async function searchObjects(client, query, types) {
1230
1092
  const searchPattern = query || "*";
1231
1093
  const objectTypes = types && types.length > 0 ? types : getAllTypes();
@@ -1292,7 +1154,7 @@ function parseSearchResults(xml) {
1292
1154
  return ok(results);
1293
1155
  }
1294
1156
 
1295
- // src/core/adt/whereUsed.ts
1157
+ // src/core/adt/discovery/whereUsed.ts
1296
1158
  async function findWhereUsed(client, object) {
1297
1159
  const config = getConfigByExtension(object.extension);
1298
1160
  if (!config) {
@@ -1366,7 +1228,7 @@ function parseWhereUsed(xml) {
1366
1228
  return ok(dependencies);
1367
1229
  }
1368
1230
 
1369
- // src/core/adt/createTransport.ts
1231
+ // src/core/adt/transports/createTransport.ts
1370
1232
  async function createTransport(client, config) {
1371
1233
  const body = dictToAbapXml({
1372
1234
  DEVCLASS: config.package,
@@ -1397,7 +1259,7 @@ async function createTransport(client, config) {
1397
1259
  return ok(transportId);
1398
1260
  }
1399
1261
 
1400
- // src/core/adt/gitDiff.ts
1262
+ // src/core/adt/craud/gitDiff.ts
1401
1263
  var import_diff = require("diff");
1402
1264
  function computeDiff(serverLines, localLines) {
1403
1265
  const changes = (0, import_diff.diffArrays)(serverLines, localLines);
@@ -2345,9 +2207,9 @@ var ADTClientImpl = class {
2345
2207
  if (!this.state.session) return err(new Error("Not logged in"));
2346
2208
  return previewData(this.requestor, query);
2347
2209
  }
2348
- async getDistinctValues(objectName, column, objectType = "view") {
2210
+ async getDistinctValues(objectName, parameters, column, objectType = "view") {
2349
2211
  if (!this.state.session) return err(new Error("Not logged in"));
2350
- return getDistinctValues(this.requestor, objectName, column, objectType);
2212
+ return getDistinctValues(this.requestor, objectName, parameters, column, objectType);
2351
2213
  }
2352
2214
  async countRows(objectName, objectType) {
2353
2215
  if (!this.state.session) return err(new Error("Not logged in"));
@@ -2392,20 +2254,9 @@ function createClient(config) {
2392
2254
  }
2393
2255
  return ok(new ADTClientImpl(config));
2394
2256
  }
2395
-
2396
- // src/core/config.ts
2397
- var import_node_fs = require("fs");
2398
- var import_zod2 = require("zod");
2399
- var systemConfigSchema = import_zod2.z.record(
2400
- import_zod2.z.string(),
2401
- import_zod2.z.object({
2402
- adt: import_zod2.z.string().url().optional(),
2403
- odata: import_zod2.z.string().url().optional(),
2404
- instance_num: import_zod2.z.string().optional()
2405
- })
2406
- );
2407
2257
  // Annotate the CommonJS export names for ESM import in node:
2408
2258
  0 && (module.exports = {
2259
+ buildSQLQuery,
2409
2260
  createClient,
2410
2261
  err,
2411
2262
  ok