catalyst-relay 0.2.2 → 0.2.5

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.mjs CHANGED
@@ -142,6 +142,11 @@ function debugError(message, cause) {
142
142
  }
143
143
  }
144
144
 
145
+ // src/core/utils/content.ts
146
+ function normalizeContent(content) {
147
+ return content.replace(/\s+/g, " ").trim();
148
+ }
149
+
145
150
  // src/types/config.ts
146
151
  import { z } from "zod";
147
152
  var samlFormSelectorsSchema = z.object({
@@ -373,7 +378,7 @@ function requireConfig(extension) {
373
378
  return [config, null];
374
379
  }
375
380
 
376
- // src/core/adt/read.ts
381
+ // src/core/adt/craud/read.ts
377
382
  async function readObject(client, object) {
378
383
  const [config, configErr] = requireConfig(object.extension);
379
384
  if (configErr) return err(configErr);
@@ -397,7 +402,7 @@ async function readObject(client, object) {
397
402
  return ok(result);
398
403
  }
399
404
 
400
- // src/core/adt/lock.ts
405
+ // src/core/adt/craud/lock.ts
401
406
  async function lockObject(client, object) {
402
407
  const [config, configErr] = requireConfig(object.extension);
403
408
  if (configErr) return err(configErr);
@@ -445,7 +450,7 @@ async function unlockObject(client, object, lockHandle) {
445
450
  return ok(void 0);
446
451
  }
447
452
 
448
- // src/core/adt/create.ts
453
+ // src/core/adt/craud/create.ts
449
454
  async function createObject(client, object, packageName, transport, username) {
450
455
  const [config, configErr] = requireConfig(object.extension);
451
456
  if (configErr) return err(configErr);
@@ -482,7 +487,7 @@ async function createObject(client, object, packageName, transport, username) {
482
487
  return ok(void 0);
483
488
  }
484
489
 
485
- // src/core/adt/update.ts
490
+ // src/core/adt/craud/update.ts
486
491
  async function updateObject(client, object, lockHandle, transport) {
487
492
  const [config, configErr] = requireConfig(object.extension);
488
493
  if (configErr) return err(configErr);
@@ -510,7 +515,7 @@ async function updateObject(client, object, lockHandle, transport) {
510
515
  return ok(void 0);
511
516
  }
512
517
 
513
- // src/core/adt/delete.ts
518
+ // src/core/adt/craud/delete.ts
514
519
  async function deleteObject(client, object, lockHandle, transport) {
515
520
  const [config, configErr] = requireConfig(object.extension);
516
521
  if (configErr) return err(configErr);
@@ -535,7 +540,7 @@ async function deleteObject(client, object, lockHandle, transport) {
535
540
  return ok(void 0);
536
541
  }
537
542
 
538
- // src/core/adt/activation.ts
543
+ // src/core/adt/craud/activation.ts
539
544
  async function activateObjects(client, objects) {
540
545
  if (objects.length === 0) {
541
546
  return ok([]);
@@ -645,7 +650,7 @@ function extractActivationErrors(objects, xml, _extension) {
645
650
  return ok(results);
646
651
  }
647
652
 
648
- // src/core/adt/tree.ts
653
+ // src/core/adt/discovery/tree.ts
649
654
  async function getTree(client, query) {
650
655
  const internalQuery = {};
651
656
  if (query.package) {
@@ -762,16 +767,16 @@ function parseTreeResponse(xml) {
762
767
  return ok({ nodes, packages });
763
768
  }
764
769
 
765
- // src/core/adt/packages.ts
766
- async function getPackages(client) {
767
- const [treeResult, treeErr] = await getTreeInternal(client, {}, "*");
770
+ // src/core/adt/discovery/packages.ts
771
+ async function getPackages(client, filter = "*") {
772
+ const [treeResult, treeErr] = await getTreeInternal(client, {}, filter);
768
773
  if (treeErr) {
769
774
  return err(treeErr);
770
775
  }
771
776
  return ok(treeResult.packages);
772
777
  }
773
778
 
774
- // src/core/adt/transports.ts
779
+ // src/core/adt/transports/transports.ts
775
780
  async function getTransports(client, packageName) {
776
781
  const contentType = "application/vnd.sap.as+xml; charset=UTF-8; dataname=com.sap.adt.transport.service.checkData";
777
782
  const body = `<?xml version="1.0" encoding="UTF-8"?>
@@ -840,7 +845,7 @@ function extractTransports(xml) {
840
845
  return ok(transports);
841
846
  }
842
847
 
843
- // src/core/adt/previewParser.ts
848
+ // src/core/adt/data_extraction/previewParser.ts
844
849
  function parseDataPreview(xml, maxRows, isTable) {
845
850
  const [doc, parseErr] = safeParseXml(xml);
846
851
  if (parseErr) {
@@ -899,7 +904,7 @@ function parseDataPreview(xml, maxRows, isTable) {
899
904
  return ok(dataFrame);
900
905
  }
901
906
 
902
- // src/core/adt/dataPreview.ts
907
+ // src/core/adt/data_extraction/dataPreview.ts
903
908
  async function previewData(client, query) {
904
909
  const extension = query.objectType === "table" ? "astabldt" : "asddls";
905
910
  const config = getConfigByExtension(extension);
@@ -939,11 +944,83 @@ async function previewData(client, query) {
939
944
  return ok(dataFrame);
940
945
  }
941
946
 
942
- // src/core/adt/distinct.ts
947
+ // src/core/adt/data_extraction/queryBuilder.ts
948
+ function quoteString(value) {
949
+ return typeof value == "string" ? "'" + value + "'" : "" + value;
950
+ }
951
+ function basicFilterToWhere(filter) {
952
+ return `${filter.field} ${filter.operator} ${quoteString(filter.value)}`;
953
+ }
954
+ function betweenFilterToWhere(filter) {
955
+ return `${filter.field} between ${quoteString(filter.minimum)} and ${quoteString(filter.maximum)}`;
956
+ }
957
+ function listFilterToWhere(filter) {
958
+ return `${filter.field} ${filter.include ? "" : "not "}in ( ${filter.values.map(quoteString).join(", ")} )`;
959
+ }
960
+ function queryFilterToWhere(filter) {
961
+ if (filter.type === "list") return listFilterToWhere(filter);
962
+ if (filter.type === "between") return betweenFilterToWhere(filter);
963
+ return basicFilterToWhere(filter);
964
+ }
965
+ function queryFiltersToWhere(filters) {
966
+ if (filters.length === 0) return "";
967
+ return `
968
+ where ${filters.map(queryFilterToWhere).join(" and ")}`;
969
+ }
970
+ function sortingsToOrderBy(sortings) {
971
+ if (sortings.length === 0) return "";
972
+ return `
973
+ order by ${sortings.map((s) => `${s.field} ${s.direction}`).join(", ")}`;
974
+ }
975
+ function fieldsToGroupbyClause(fields) {
976
+ if (fields.length === 0) return "";
977
+ return `
978
+ group by ${fields.join(", ")}`;
979
+ }
980
+ function aggregationToFieldDefinition(aggregation) {
981
+ if (aggregation.function === "count") {
982
+ return `count( distinct main~${aggregation.field} ) as ${aggregation.field}`;
983
+ }
984
+ return `${aggregation.function}( main~${aggregation.field} ) as ${aggregation.field}`;
985
+ }
986
+ function parametersToSQLParams(params) {
987
+ if (params.length === 0) return "";
988
+ return `( ${params.map((p) => `${p.name} = ${quoteString(p.value)}`).join(", ")})`;
989
+ }
990
+ function buildSQLQuery(query) {
991
+ const [parameters, filters, sortings, aggregations] = [query.parameters ?? [], query.filters ?? [], query.sortings ?? [], query.aggregations ?? []];
992
+ const groupingFields = query.fields.filter((f) => !aggregations.find((a) => a.field === f));
993
+ if (sortings.filter((s) => !query.fields.includes(s.field)).length > 0) {
994
+ return err(new Error("Sorting fields must be included in the selected fields."));
995
+ }
996
+ let selectClause = "select\n";
997
+ const fieldSelections = [];
998
+ for (const field of query.fields) {
999
+ const aggregation = aggregations.find((a) => a.field === field);
1000
+ if (aggregation) {
1001
+ fieldSelections.push(` ${aggregationToFieldDefinition(aggregation)}`);
1002
+ continue;
1003
+ }
1004
+ fieldSelections.push(` main~${field}`);
1005
+ }
1006
+ selectClause += fieldSelections.join(",\n") + `
1007
+ from ${query.objectName}${parametersToSQLParams(parameters)} as main
1008
+ `;
1009
+ const [whereClause, groupbyClause, orderbyClause] = [queryFiltersToWhere(filters), aggregations.length ? fieldsToGroupbyClause(groupingFields) : "", sortingsToOrderBy(sortings)];
1010
+ const result = {
1011
+ objectName: query.objectName,
1012
+ objectType: query.objectType,
1013
+ sqlQuery: `${selectClause}${whereClause}${groupbyClause}${orderbyClause}`
1014
+ };
1015
+ if (query.limit !== void 0) result.limit = query.limit;
1016
+ return ok(result);
1017
+ }
1018
+
1019
+ // src/core/adt/data_extraction/distinct.ts
943
1020
  var MAX_ROW_COUNT = 5e4;
944
- async function getDistinctValues(client, objectName, column, objectType = "view") {
1021
+ async function getDistinctValues(client, objectName, parameters, column, objectType = "view") {
945
1022
  const columnName = column.toUpperCase();
946
- const sqlQuery = `SELECT ${columnName} AS value, COUNT(*) AS count FROM ${objectName} GROUP BY ${columnName}`;
1023
+ const sqlQuery = `SELECT ${columnName} AS value, COUNT(*) AS ValueCount FROM ${objectName}${parametersToSQLParams(parameters)} GROUP BY ${columnName} ORDER BY ValueCount DESCENDING`;
947
1024
  const [dataFrame, error] = await previewData(client, {
948
1025
  objectName,
949
1026
  objectType,
@@ -960,7 +1037,7 @@ async function getDistinctValues(client, objectName, column, objectType = "view"
960
1037
  return ok({ column, values });
961
1038
  }
962
1039
 
963
- // src/core/adt/count.ts
1040
+ // src/core/adt/data_extraction/count.ts
964
1041
  async function countRows(client, objectName, objectType) {
965
1042
  const sqlQuery = `SELECT COUNT(*) AS count FROM ${objectName}`;
966
1043
  const [dataFrame, error] = await previewData(client, {
@@ -983,7 +1060,7 @@ async function countRows(client, objectName, objectType) {
983
1060
  return ok(count);
984
1061
  }
985
1062
 
986
- // src/core/adt/searchObjects.ts
1063
+ // src/core/adt/discovery/searchObjects.ts
987
1064
  async function searchObjects(client, query, types) {
988
1065
  const searchPattern = query || "*";
989
1066
  const objectTypes = types && types.length > 0 ? types : getAllTypes();
@@ -1050,7 +1127,7 @@ function parseSearchResults(xml) {
1050
1127
  return ok(results);
1051
1128
  }
1052
1129
 
1053
- // src/core/adt/whereUsed.ts
1130
+ // src/core/adt/discovery/whereUsed.ts
1054
1131
  async function findWhereUsed(client, object) {
1055
1132
  const config = getConfigByExtension(object.extension);
1056
1133
  if (!config) {
@@ -1124,7 +1201,7 @@ function parseWhereUsed(xml) {
1124
1201
  return ok(dependencies);
1125
1202
  }
1126
1203
 
1127
- // src/core/adt/createTransport.ts
1204
+ // src/core/adt/transports/createTransport.ts
1128
1205
  async function createTransport(client, config) {
1129
1206
  const body = dictToAbapXml({
1130
1207
  DEVCLASS: config.package,
@@ -1155,7 +1232,7 @@ async function createTransport(client, config) {
1155
1232
  return ok(transportId);
1156
1233
  }
1157
1234
 
1158
- // src/core/adt/gitDiff.ts
1235
+ // src/core/adt/craud/gitDiff.ts
1159
1236
  import { diffArrays } from "diff";
1160
1237
  function computeDiff(serverLines, localLines) {
1161
1238
  const changes = diffArrays(serverLines, localLines);
@@ -1916,6 +1993,9 @@ var ADTClientImpl = class {
1916
1993
  if (this.agent) {
1917
1994
  fetchOptions.dispatcher = this.agent;
1918
1995
  }
1996
+ if (config.insecure) {
1997
+ fetchOptions.tls = { rejectUnauthorized: false };
1998
+ }
1919
1999
  if (body) {
1920
2000
  fetchOptions.body = body;
1921
2001
  }
@@ -2056,6 +2136,18 @@ var ADTClientImpl = class {
2056
2136
  results.push(result2);
2057
2137
  continue;
2058
2138
  }
2139
+ const serverContent = normalizeContent(existing.content);
2140
+ const localContent = normalizeContent(obj.content);
2141
+ if (serverContent === localContent) {
2142
+ const result2 = {
2143
+ name: obj.name,
2144
+ extension: obj.extension,
2145
+ status: "unchanged"
2146
+ };
2147
+ if (transport) result2.transport = transport;
2148
+ results.push(result2);
2149
+ continue;
2150
+ }
2059
2151
  const [, updateErr] = await this.update(obj, transport);
2060
2152
  if (updateErr) return err(updateErr);
2061
2153
  const result = {
@@ -2086,9 +2178,9 @@ var ADTClientImpl = class {
2086
2178
  return ok(void 0);
2087
2179
  }
2088
2180
  // --- Discovery ---
2089
- async getPackages() {
2181
+ async getPackages(filter) {
2090
2182
  if (!this.state.session) return err(new Error("Not logged in"));
2091
- return getPackages(this.requestor);
2183
+ return getPackages(this.requestor, filter);
2092
2184
  }
2093
2185
  async getTree(query) {
2094
2186
  if (!this.state.session) return err(new Error("Not logged in"));
@@ -2103,9 +2195,9 @@ var ADTClientImpl = class {
2103
2195
  if (!this.state.session) return err(new Error("Not logged in"));
2104
2196
  return previewData(this.requestor, query);
2105
2197
  }
2106
- async getDistinctValues(objectName, column, objectType = "view") {
2198
+ async getDistinctValues(objectName, parameters, column, objectType = "view") {
2107
2199
  if (!this.state.session) return err(new Error("Not logged in"));
2108
- return getDistinctValues(this.requestor, objectName, column, objectType);
2200
+ return getDistinctValues(this.requestor, objectName, parameters, column, objectType);
2109
2201
  }
2110
2202
  async countRows(objectName, objectType) {
2111
2203
  if (!this.state.session) return err(new Error("Not logged in"));
@@ -2150,19 +2242,8 @@ function createClient(config) {
2150
2242
  }
2151
2243
  return ok(new ADTClientImpl(config));
2152
2244
  }
2153
-
2154
- // src/core/config.ts
2155
- import { readFileSync } from "fs";
2156
- import { z as z2 } from "zod";
2157
- var systemConfigSchema = z2.record(
2158
- z2.string(),
2159
- z2.object({
2160
- adt: z2.string().url().optional(),
2161
- odata: z2.string().url().optional(),
2162
- instance_num: z2.string().optional()
2163
- })
2164
- );
2165
2245
  export {
2246
+ buildSQLQuery,
2166
2247
  createClient,
2167
2248
  err,
2168
2249
  ok