abap-local-client 1.0.1 → 1.2.0

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/cli-config.cjs ADDED
@@ -0,0 +1,2 @@
1
+ // abap-local-config — CommonJS wrapper for ESM entry point
2
+ import('../config-cli.mjs');
package/cli.cjs ADDED
@@ -0,0 +1,3 @@
1
+ // abap-local-client — CommonJS wrapper for ESM entry point
2
+ // This wrapper is what npm's "bin" generates: node ./cli.js
3
+ import('../sso-sap-client.mjs');
package/package.json CHANGED
@@ -1,15 +1,13 @@
1
1
  {
2
2
  "name": "abap-local-client",
3
- "version": "1.0.1",
3
+ "version": "1.2.0",
4
4
  "description": "SAP Local Client — WebSocket bridge with Basic, SPNEGO, X.509, SAML & SNC authentication",
5
5
  "main": "sso-sap-client.mjs",
6
6
  "type": "module",
7
7
  "scripts": {
8
8
  "start": "node sso-sap-client.mjs",
9
- "dev": "node sso-sap-client.mjs",
10
9
  "sso": "node sso-sap-client.mjs",
11
- "rfc": "node saprouter-client.mjs",
12
- "kill": "node kill-client.js",
10
+ "config": "node config-cli.mjs",
13
11
  "test": "node test-integration.mjs",
14
12
  "prepublishOnly": "node test-integration.mjs"
15
13
  },
@@ -670,9 +670,43 @@ async function connect() {
670
670
  }
671
671
 
672
672
  // ════════════════════════════════════════════════════════════════════════════
673
- // Start
673
+ // Start — with inline CLI for setup/config when run directly
674
674
  // ════════════════════════════════════════════════════════════════════════════
675
675
 
676
+ const args = process.argv.slice(2);
677
+ const command = args[0];
678
+
679
+ // If the user ran "node sso-sap-client.mjs setup" or "npx abap-local-client config xyz",
680
+ // delegate to the config CLI instead of starting the WebSocket client.
681
+ if (command === 'setup' || command === 'config' || command === 'add-system' || command === 'set-mcp-key' ||
682
+ command === 'list-systems' || command === 'remove-system' || command === 'enable-system' ||
683
+ command === 'disable-system' || command === 'show-config' || command === 'arcanum-fallback' ||
684
+ command === 'set-ws-url' || command === 'help') {
685
+ // Dynamically import the config CLI so it processes the same argv
686
+ await import('./config-cli.mjs');
687
+ process.exit(0);
688
+ }
689
+
690
+ // If no config exists, show a quick-start guide
691
+ if (!config.isConfigInitialized()) {
692
+ console.log('╔═══════════════════════════════════════════════════════════╗');
693
+ console.log('║ SAP Local Client — First Run Setup ║');
694
+ console.log('╚═══════════════════════════════════════════════════════════╝');
695
+ console.log('');
696
+ console.log('No configuration found. Set up quickly:');
697
+ console.log('');
698
+ console.log(' node sso-sap-client.mjs set-mcp-key arc_local_...');
699
+ console.log(' node sso-sap-client.mjs add-system <id> <mode> --host <host> --client <client> ...');
700
+ console.log('');
701
+ console.log('Modes: basic | spnego | x509 | saml | snc');
702
+ console.log('');
703
+ console.log('Example:');
704
+ console.log(' node sso-sap-client.mjs add-system S4D snc --host vhlbvs4dci.sap.piracanjuba.com.br --sysnr 00 --client 100 --snc-partner-name "p:CN=svc.ssoS4D" --language PT');
705
+ console.log('');
706
+ console.log('For full help: node sso-sap-client.mjs help');
707
+ console.log('');
708
+ }
709
+
676
710
  console.log('╔═══════════════════════════════════════════════════════════╗');
677
711
  console.log('║ SAP Local Client — Multi-System SSO Bridge ║');
678
712
  console.log('╚═══════════════════════════════════════════════════════════╝');
package/xml-utils.mjs ADDED
@@ -0,0 +1,60 @@
1
+ import { XMLParser } from 'fast-xml-parser';
2
+
3
+ // Create XML parser instance
4
+ const xmlParser = new XMLParser({
5
+ ignoreAttributes: false,
6
+ attributeNamePrefix: '@_'
7
+ });
8
+
9
+ /**
10
+ * Parse SAP XML response and check for errors
11
+ * Returns: { hasErrors: boolean, errorMessages: string[], parsedData: object }
12
+ */
13
+ export function parseSAPResponse(xmlString) {
14
+ if (typeof xmlString !== 'string' || !xmlString.includes('<?xml')) {
15
+ return { hasErrors: false, errorMessages: [], parsedData: null };
16
+ }
17
+
18
+ try {
19
+ const parsed = xmlParser.parse(xmlString);
20
+
21
+ // Check for syntax check errors (chkrun:checkMessage with type="E")
22
+ if (parsed['chkrun:checkRunReports']) {
23
+ const report = parsed['chkrun:checkRunReports']['chkrun:checkReport'];
24
+ const messageList = report?.['chkrun:checkMessageList'];
25
+
26
+ if (messageList && messageList['chkrun:checkMessage']) {
27
+ const messages = Array.isArray(messageList['chkrun:checkMessage'])
28
+ ? messageList['chkrun:checkMessage']
29
+ : [messageList['chkrun:checkMessage']];
30
+
31
+ const errorMessages = [];
32
+ for (const msg of messages) {
33
+ if (msg['@_chkrun:type'] === 'E') {
34
+ let line = null;
35
+ if (msg['@_chkrun:uri'] && msg['@_chkrun:uri'].includes('#start=')) {
36
+ const match = msg['@_chkrun:uri'].match(/#start=(\d+),(\d+)/);
37
+ if (match) {
38
+ line = parseInt(match[1]);
39
+ }
40
+ }
41
+ const text = msg['@_chkrun:shortText'] || 'Unknown error';
42
+ const lineInfo = line ? ` (line ${line})` : '';
43
+ errorMessages.push(`${text}${lineInfo}`);
44
+ }
45
+ }
46
+
47
+ if (errorMessages.length > 0) {
48
+ return { hasErrors: true, errorMessages, parsedData: parsed };
49
+ }
50
+ }
51
+ }
52
+
53
+ // Add other error patterns here if needed (e.g., activation errors, etc.)
54
+
55
+ return { hasErrors: false, errorMessages: [], parsedData: parsed };
56
+ } catch (error) {
57
+ console.error(' ⚠️ XML parsing failed:', error.message);
58
+ return { hasErrors: false, errorMessages: [], parsedData: null };
59
+ }
60
+ }