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.d.mts +52 -5
- package/dist/index.d.ts +52 -5
- package/dist/index.js +119 -37
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +118 -37
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
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/
|
|
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
|
|
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
|