catalyst-relay 0.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/types/result.ts","../src/core/utils/xml.ts","../src/core/utils/sql.ts","../src/core/utils/csrf.ts","../src/core/utils/headers.ts","../src/core/utils/logging.ts","../src/types/config.ts","../src/core/session/login.ts","../src/core/adt/types.ts","../src/core/adt/helpers.ts","../src/core/adt/read.ts","../src/core/adt/lock.ts","../src/core/adt/create.ts","../src/core/adt/update.ts","../src/core/adt/delete.ts","../src/core/adt/activation.ts","../src/core/adt/tree.ts","../src/core/adt/packages.ts","../src/core/adt/transports.ts","../src/core/adt/queryBuilder.ts","../src/core/adt/previewParser.ts","../src/core/adt/data.ts","../src/core/adt/distinct.ts","../src/core/adt/count.ts","../src/core/adt/searchObjects.ts","../src/core/adt/whereUsed.ts","../src/core/adt/createTransport.ts","../src/core/adt/gitDiff.ts","../src/core/client.ts","../src/core/config.ts"],"sourcesContent":["/**\n * Catalyst-Relay\n *\n * TypeScript middleware for SAP ADT integration.\n * Can be used as a library (direct imports) or as an HTTP server.\n *\n * @example Library usage\n * ```typescript\n * import { createClient } from 'catalyst-relay';\n *\n * const [client, error] = createClient({\n * url: 'https://sap-server:443',\n * client: '100',\n * auth: { type: 'basic', username: 'user', password: 'pass' }\n * });\n * if (error) throw error;\n *\n * const [session, loginError] = await client.login();\n * if (loginError) throw loginError;\n *\n * const [data, readError] = await client.read([\n * { name: 'ZTEST_VIEW', extension: 'asddls' }\n * ]);\n * ```\n *\n * @example Server usage\n * ```bash\n * bun run src/server.ts\n * ```\n */\n\n// Core exports\nexport { createClient } from './core';\nexport type { ADTClient } from './core';\n\n// Config types\nexport type {\n AuthType,\n AuthConfig,\n BasicAuthConfig,\n SamlAuthConfig,\n SsoAuthConfig,\n ClientConfig,\n} from './types/config';\n\n// Request types\nexport type {\n ObjectRef,\n ObjectContent,\n TreeQuery,\n PreviewQuery,\n Filter,\n FilterOperator,\n OrderBy,\n} from './types/requests';\n\n// Response wrappers\nexport type {\n ApiResponse,\n SuccessResponse,\n ErrorResponse,\n ErrorCode,\n} from './types/responses';\n\n// Result types\nexport type { Result, AsyncResult } from './types/result';\n\n// Session types\nexport type { Session } from './core/session/types';\n\n// ADT domain types\nexport type {\n ObjectMetadata,\n ObjectWithContent,\n UpsertResult,\n ActivationResult,\n ActivationMessage,\n TreeNode,\n Transport,\n Package,\n DataFrame,\n ColumnInfo,\n DistinctResult,\n SearchResult,\n Dependency,\n DiffResult,\n TransportConfig,\n ObjectConfig,\n} from './core/adt';\n\n// Result utilities\nexport { ok, err } from './types/result';\n","/**\n * Result type for error handling (Go-style tuples)\n *\n * Usage:\n * const [data, error] = await someFunction();\n * if (error) {\n * console.error(error);\n * return;\n * }\n * // data is guaranteed non-null\n */\n\nexport type Result<T, E = Error> = [T, null] | [null, E];\n\n/**\n * Async result type alias for convenience\n */\nexport type AsyncResult<T, E = Error> = Promise<Result<T, E>>;\n\n/**\n * Create a success result\n */\nexport function ok<T>(value: T): Result<T, never> {\n return [value, null];\n}\n\n/**\n * Create an error result\n */\nexport function err<E = Error>(error: E): Result<never, E> {\n return [null, error];\n}\n","/**\n * XML Parsing Utilities\n *\n * Secure XML parsing and manipulation for ADT responses.\n * Uses @xmldom/xmldom for cross-platform XML parsing.\n */\n\nimport { DOMParser } from '@xmldom/xmldom';\nimport type { Result } from '../../types/result';\nimport { ok, err } from '../../types/result';\n\n/**\n * Securely parse XML string into a Document object (throws on error)\n *\n * @param xmlString - The XML string to parse\n * @returns Parsed XML Document\n * @throws Error if XML is malformed\n * @deprecated Use safeParseXml for Result-based error handling\n */\nexport function parseXml(xmlString: string): Document {\n if (!xmlString || xmlString.trim().length === 0) {\n throw new Error('Empty XML string provided');\n }\n\n const parser = new DOMParser();\n const doc = parser.parseFromString(xmlString, 'text/xml');\n\n // Check for parser errors\n const parseError = doc.getElementsByTagName('parsererror');\n if (parseError.length > 0) {\n const errorNode = parseError[0];\n const errorText = errorNode?.textContent || 'Unknown XML parsing error';\n throw new Error(`XML parsing failed: ${errorText}`);\n }\n\n return doc;\n}\n\n/**\n * Safely parse XML string into a Document object\n *\n * @param xmlString - The XML string to parse\n * @returns Result tuple with Document or Error\n */\nexport function safeParseXml(xmlString: string): Result<Document, Error> {\n // Validate input.\n if (!xmlString || xmlString.trim().length === 0) {\n return err(new Error('Empty XML string provided'));\n }\n\n try {\n // Parse XML string.\n const parser = new DOMParser();\n const doc = parser.parseFromString(xmlString, 'text/xml');\n\n // Check for parser errors.\n const parseError = doc.getElementsByTagName('parsererror');\n if (parseError.length > 0) {\n const errorNode = parseError[0];\n const errorText = errorNode?.textContent || 'Unknown XML parsing error';\n return err(new Error(`XML parsing failed: ${errorText}`));\n }\n\n return ok(doc);\n } catch (error) {\n if (error instanceof Error) {\n return err(error);\n }\n return err(new Error('Unknown XML parsing error'));\n }\n}\n\n/**\n * Extract LOCK_HANDLE from ADT XML response\n *\n * @param xml - XML string containing lock handle\n * @returns Result tuple with lock handle or error\n */\nexport function extractLockHandle(xml: string): Result<string, Error> {\n // Validate input.\n if (!xml) {\n return err(new Error('Empty XML provided'));\n }\n\n // Parse XML response.\n const [doc, parseErr] = safeParseXml(xml);\n if (parseErr) { return err(parseErr); }\n\n // Find LOCK_HANDLE element.\n const lockHandleElements = doc.getElementsByTagName('LOCK_HANDLE');\n if (lockHandleElements.length === 0) {\n return err(new Error('LOCK_HANDLE element not found in XML'));\n }\n\n // Extract and validate lock handle value.\n const lockHandleElement = lockHandleElements[0];\n const lockHandle = lockHandleElement?.textContent;\n if (!lockHandle || lockHandle.trim().length === 0) {\n return err(new Error('LOCK_HANDLE element is empty'));\n }\n\n return ok(lockHandle.trim());\n}\n\n/**\n * Extract error message from ADT XML error response\n *\n * @param xml - XML string containing error message\n * @returns Error message or default message\n */\nexport function extractError(xml: string): string {\n // Handle empty input.\n if (!xml) {\n return 'No error message found';\n }\n\n // Parse XML response.\n const [doc, parseErr] = safeParseXml(xml);\n if (parseErr) {\n return 'Failed to parse error XML';\n }\n\n // Find message element.\n const messageElements = doc.getElementsByTagName('message');\n if (messageElements.length === 0) {\n return 'No message found';\n }\n\n // Extract message text.\n const messageElement = messageElements[0];\n const message = messageElement?.textContent;\n return message || 'No message found';\n}\n\n/**\n * Escape special XML characters\n *\n * @param str - String to escape\n * @returns XML-safe string\n */\nexport function escapeXml(str: string): string {\n // Handle empty input.\n if (!str) {\n return '';\n }\n\n // Replace special XML characters with entities.\n return str\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;');\n}\n\n/**\n * Convert a dictionary to ABAP-style XML\n *\n * This creates XML in the format expected by SAP ADT endpoints:\n * <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n * <asx:abap xmlns:asx=\"http://www.sap.com/abapxml\" version=\"1.0\">\n * <asx:values>\n * <DATA>\n * <KEY>value</KEY>\n * </DATA>\n * </asx:values>\n * </asx:abap>\n *\n * @param data - Key-value pairs to convert to XML\n * @param root - Root element name (default: \"DATA\")\n * @returns ABAP-formatted XML string\n */\nexport function dictToAbapXml(data: Record<string, string>, root: string = 'DATA'): string {\n // Build inner XML elements from key-value pairs.\n const innerElements = Object.entries(data)\n .map(([key, value]) => {\n if (value) {\n return `<${key}>${escapeXml(value)}</${key}>`;\n }\n return `<${key}/>`;\n })\n .join('\\n ');\n\n // Return complete ABAP XML structure.\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<asx:abap xmlns:asx=\"http://www.sap.com/abapxml\" version=\"1.0\">\n <asx:values>\n <${root}>\n ${innerElements}\n </${root}>\n </asx:values>\n</asx:abap>`;\n}\n","/**\n * SQL Input Validation\n *\n * Protects against SQL injection attacks in data preview queries.\n */\n\nimport type { Result } from '../../types/result';\nimport { ok, err } from '../../types/result';\n\n/**\n * Custom error class for SQL validation failures\n */\nexport class SqlValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'SqlValidationError';\n }\n}\n\n/**\n * Validate SQL input to prevent injection attacks\n *\n * Checks for:\n * - Dangerous SQL keywords (DROP, DELETE, INSERT, etc.)\n * - Statement terminators followed by new statements\n * - SQL comments\n * - Procedure execution\n * - Union-based injection\n * - System variables\n * - Excessive special characters\n * - Unbalanced quotes\n *\n * @param input - SQL input string to validate\n * @param maxLength - Maximum allowed length (default: 10000)\n * @returns Result tuple with true on success or SqlValidationError on failure\n *\n * @example\n * const [valid, error] = validateSqlInput(\"SELECT * FROM users WHERE id = 1\");\n * if (error) {\n * console.error('Invalid SQL:', error.message);\n * return;\n * }\n */\nexport function validateSqlInput(\n input: string,\n maxLength: number = 10000\n): Result<true, SqlValidationError> {\n // Verify input is a string type.\n if (typeof input !== 'string') {\n return err(new SqlValidationError('Input must be a string'));\n }\n\n // Enforce maximum input length to prevent resource exhaustion.\n if (input.length > maxLength) {\n return err(new SqlValidationError(`Input exceeds maximum length of ${maxLength}`));\n }\n\n // Define patterns for SQL injection detection.\n const dangerousPatterns: Array<{ pattern: RegExp; description: string }> = [\n {\n pattern: /\\b(DROP|DELETE|INSERT|UPDATE|ALTER|CREATE|TRUNCATE)\\s+/i,\n description: 'DDL/DML keywords (DROP, DELETE, INSERT, etc.)'\n },\n {\n pattern: /;[\\s]*\\w/,\n description: 'Statement termination followed by another statement'\n },\n {\n pattern: /--[\\s]*\\w/,\n description: 'SQL comments with content'\n },\n {\n pattern: /\\/\\*.*?\\*\\//,\n description: 'Block comments'\n },\n {\n pattern: /\\bEXEC(UTE)?\\s*\\(/i,\n description: 'Procedure execution'\n },\n {\n pattern: /\\bSP_\\w+/i,\n description: 'Stored procedures'\n },\n {\n pattern: /\\bXP_\\w+/i,\n description: 'Extended stored procedures'\n },\n {\n pattern: /\\bUNION\\s+(ALL\\s+)?SELECT/i,\n description: 'Union-based injection'\n },\n {\n pattern: /@@\\w+/,\n description: 'System variables'\n },\n {\n pattern: /\\bDECLARE\\s+@/i,\n description: 'Variable declarations'\n },\n {\n pattern: /\\bCAST\\s*\\(/i,\n description: 'Type casting'\n },\n {\n pattern: /\\bCONVERT\\s*\\(/i,\n description: 'Type conversion'\n }\n ];\n\n // Test input against each dangerous pattern.\n for (const { pattern, description } of dangerousPatterns) {\n if (pattern.test(input)) {\n return err(new SqlValidationError(\n `Input contains potentially dangerous SQL pattern: ${description}`\n ));\n }\n }\n\n // Count special characters that could indicate injection attempts.\n const specialCharMatches = input.match(/[;'\"\\\\]/g);\n const specialCharCount = specialCharMatches ? specialCharMatches.length : 0;\n\n // Reject inputs with too many special characters.\n if (specialCharCount > 5) {\n return err(new SqlValidationError('Input contains excessive special characters'));\n }\n\n // Ensure single quotes are balanced.\n const singleQuoteCount = (input.match(/'/g) || []).length;\n if (singleQuoteCount % 2 !== 0) {\n return err(new SqlValidationError('Unbalanced single quotes detected'));\n }\n\n // Ensure double quotes are balanced.\n const doubleQuoteCount = (input.match(/\"/g) || []).length;\n if (doubleQuoteCount % 2 !== 0) {\n return err(new SqlValidationError('Unbalanced double quotes detected'));\n }\n\n return ok(true);\n}\n","/**\n * CSRF Token Constants\n *\n * Constants for CSRF token handling with SAP ADT endpoints.\n */\n\n/**\n * Special value to request a CSRF token from the server\n *\n * When sent in the x-csrf-token header, SAP returns a valid token\n * in the response headers.\n */\nexport const FETCH_CSRF_TOKEN = 'fetch';\n\n/**\n * HTTP header name for CSRF token\n *\n * Used both for requesting tokens (with FETCH_CSRF_TOKEN value)\n * and sending tokens with authenticated requests.\n */\nexport const CSRF_TOKEN_HEADER = 'x-csrf-token';\n","/**\n * HTTP Header Utilities for ADT Requests\n *\n * Provides header building utilities and constants for SAP ADT HTTP requests.\n * Centralizes header management to avoid duplication across client code.\n */\n\nimport { CSRF_TOKEN_HEADER, FETCH_CSRF_TOKEN } from './csrf';\nimport type { AuthConfig } from '../../types/config';\n\n// Mimic Eclipse ADT plugin for compatibility\nexport const BASE_HEADERS = {\n 'X-sap-adt-sessiontype': 'stateful',\n 'User-Agent': 'Eclipse/4.34.0 ADT/3.46.0',\n 'X-sap-adt-profiling': 'server-time',\n} as const;\n\n// Default request timeout in milliseconds\nexport const DEFAULT_TIMEOUT = 30000;\n\n/**\n * Build request headers with auth and CSRF token\n *\n * @param baseHeaders - Base headers to include in all requests\n * @param customHeaders - Request-specific headers\n * @param auth - Authentication config (for basic auth header)\n * @param csrfToken - Current CSRF token (if available)\n * @returns Combined headers object\n */\nexport function buildRequestHeaders(\n baseHeaders: Record<string, string>,\n customHeaders?: Record<string, string>,\n auth?: AuthConfig,\n csrfToken?: string | null\n): Record<string, string> {\n // Merge base and custom headers.\n const headers: Record<string, string> = {\n ...baseHeaders,\n ...(customHeaders ?? {}),\n };\n\n // Add basic auth header if using basic authentication.\n if (auth?.type === 'basic') {\n // Use btoa for base64 encoding (web standard, available in both Node 18+ and Bun)\n const credentials = btoa(`${auth.username}:${auth.password}`);\n headers['Authorization'] = `Basic ${credentials}`;\n }\n\n // Add CSRF token if we have one (but not the 'fetch' placeholder).\n // Don't overwrite if custom headers already set the CSRF token (e.g., for token refresh).\n if (csrfToken && csrfToken !== FETCH_CSRF_TOKEN && !customHeaders?.[CSRF_TOKEN_HEADER]) {\n headers[CSRF_TOKEN_HEADER] = csrfToken;\n }\n\n return headers;\n}\n\n/**\n * Extract CSRF token from response headers\n *\n * SAP returns token in both upper and lowercase variations,\n * so we need to check both.\n *\n * @param headers - Response headers from SAP ADT server\n * @returns Extracted CSRF token or null if not found\n */\nexport function extractCsrfToken(headers: Headers): string | null {\n // Try both upper and lowercase header names.\n const token = headers.get(CSRF_TOKEN_HEADER) ||\n headers.get(CSRF_TOKEN_HEADER.toLowerCase());\n\n // Ignore the fetch token itself.\n if (!token || token === FETCH_CSRF_TOKEN) {\n return null;\n }\n\n return token;\n}\n","/**\r\n * Logging Utility — Debug logging with activation control\r\n *\r\n * Logs are silent by default. Call activateLogging() to enable console output.\r\n */\r\n\r\nlet isActive = false;\r\n\r\n/**\r\n * Enable debug logging to console\r\n */\r\nexport function activateLogging(): void {\r\n isActive = true;\r\n}\r\n\r\n/**\r\n * Disable debug logging (default state)\r\n */\r\nexport function deactivateLogging(): void {\r\n isActive = false;\r\n}\r\n\r\n/**\r\n * Check if logging is currently active\r\n */\r\nexport function isLoggingActive(): boolean {\r\n return isActive;\r\n}\r\n\r\n/**\r\n * Log a debug message (only prints when logging is active)\r\n */\r\nexport function debug(message: string): void {\r\n if (isActive) {\r\n console.log(`[DEBUG] ${message}`);\r\n }\r\n}\r\n\r\n/**\r\n * Log a debug error message (only prints when logging is active)\r\n */\r\nexport function debugError(message: string, cause?: unknown): void {\r\n if (!isActive) return;\r\n\r\n console.error(`[DEBUG] ${message}`);\r\n if (cause !== undefined) {\r\n console.error(`[DEBUG] Cause:`, cause);\r\n }\r\n}\r\n","import { z } from 'zod';\n\n/**\n * Authentication types supported by SAP ADT\n */\nexport type AuthType = 'basic' | 'saml' | 'sso';\n\n/**\n * Basic authentication configuration\n */\nexport interface BasicAuthConfig {\n type: 'basic';\n username: string;\n password: string;\n}\n\n/**\n * SAML authentication configuration\n */\nexport interface SamlAuthConfig {\n type: 'saml';\n username: string;\n password: string;\n provider?: string;\n}\n\n/**\n * SSO (Kerberos) authentication configuration\n */\nexport interface SsoAuthConfig {\n type: 'sso';\n certificate?: string;\n}\n\n/**\n * Union of all auth configurations\n */\nexport type AuthConfig = BasicAuthConfig | SamlAuthConfig | SsoAuthConfig;\n\n/**\n * Client configuration for connecting to SAP ADT\n */\nexport interface ClientConfig {\n /** ADT server URL (e.g., https://server:port) */\n url: string;\n /** SAP client number (e.g., '100') */\n client: string;\n /** Authentication configuration */\n auth: AuthConfig;\n /** Request timeout in milliseconds (default: 30000) */\n timeout?: number;\n /** Skip SSL verification (dev only) */\n insecure?: boolean;\n}\n\n/**\n * Zod schema for runtime validation of ClientConfig\n */\nexport const clientConfigSchema = z.object({\n url: z.string().url(),\n client: z.string().min(1).max(3),\n auth: z.discriminatedUnion('type', [\n z.object({\n type: z.literal('basic'),\n username: z.string().min(1),\n password: z.string().min(1),\n }),\n z.object({\n type: z.literal('saml'),\n username: z.string().min(1),\n password: z.string().min(1),\n provider: z.string().optional(),\n }),\n z.object({\n type: z.literal('sso'),\n certificate: z.string().optional(),\n }),\n ]),\n timeout: z.number().positive().optional(),\n insecure: z.boolean().optional(),\n});\n","/**\r\n * Session Lifecycle Operations\r\n *\r\n * Internal helpers for login/logout/session reset operations.\r\n * Used by ADTClient to manage session state.\r\n *\r\n * Handles:\r\n * - CSRF token fetching\r\n * - Basic authentication login flow\r\n * - Session reset on 500 errors\r\n * - Logout/cleanup\r\n */\r\n\r\nimport type { AuthConfig } from '../../types/config';\r\nimport type { Session } from './types';\r\nimport type { AsyncResult } from '../../types/result';\r\nimport { ok, err } from '../../types/result';\r\nimport {\r\n FETCH_CSRF_TOKEN,\r\n CSRF_TOKEN_HEADER,\r\n extractCsrfToken,\r\n debug,\r\n} from '../utils';\r\n\r\n// Request function type signature (provided by client.ts)\r\ntype RequestFn = (options: {\r\n method: 'GET' | 'POST' | 'PUT' | 'DELETE';\r\n path: string;\r\n params?: Record<string, string | number>;\r\n headers?: Record<string, string>;\r\n body?: string;\r\n}) => AsyncResult<Response, Error>;\r\n\r\n// Session state management (provided by client.ts)\r\nexport interface SessionState {\r\n csrfToken: string | null;\r\n session: Session | null;\r\n config: { auth: AuthConfig };\r\n}\r\n\r\n/**\r\n * Fetch CSRF token from SAP ADT server\r\n *\r\n * Endpoint and content type vary by auth type:\r\n * - SAML: /sap/bc/adt/core/http/sessions\r\n * - Basic/SSO: /sap/bc/adt/compatibility/graph\r\n *\r\n * @param state - Session state to update with new token\r\n * @param request - HTTP request function from client\r\n * @returns CSRF token string or error\r\n */\r\nexport async function fetchCsrfToken(\r\n state: SessionState,\r\n request: RequestFn\r\n): AsyncResult<string, Error> {\r\n // Select endpoint based on authentication type.\r\n const endpoint = state.config.auth.type === 'saml'\r\n ? '/sap/bc/adt/core/http/sessions'\r\n : '/sap/bc/adt/compatibility/graph';\r\n\r\n // Select content type based on authentication type.\r\n const contentType = state.config.auth.type === 'saml'\r\n ? 'application/vnd.sap.adt.core.http.session.v3+xml'\r\n : 'application/xml';\r\n\r\n // Build request headers with CSRF token fetch flag.\r\n const headers = {\r\n [CSRF_TOKEN_HEADER]: FETCH_CSRF_TOKEN,\r\n 'Content-Type': contentType,\r\n 'Accept': contentType,\r\n };\r\n\r\n // Execute CSRF token request.\r\n const [response, requestErr] = await request({\r\n method: 'GET',\r\n path: endpoint,\r\n headers,\r\n });\r\n\r\n if (requestErr) {\r\n return err(new Error(`Failed to fetch CSRF token: ${requestErr.message}`));\r\n }\r\n\r\n if (!response.ok) {\r\n const text = await response.text();\r\n return err(new Error(`CSRF token fetch failed with status ${response.status}: ${text}`));\r\n }\r\n\r\n // Extract CSRF token from response headers.\r\n const token = extractCsrfToken(response.headers);\r\n debug(`CSRF token from headers: ${token ? token.substring(0, 20) + '...' : 'null'}`);\r\n if (!token) {\r\n // Debug: show all headers\r\n debug('Response headers:');\r\n response.headers.forEach((value, key) => debug(` ${key}: ${value.substring(0, 50)}`));\r\n return err(new Error('No CSRF token returned in response headers'));\r\n }\r\n\r\n // Update session state with new token.\r\n state.csrfToken = token;\r\n debug(`Stored CSRF token in state: ${state.csrfToken?.substring(0, 20)}...`);\r\n\r\n return ok(token);\r\n}\r\n\r\n/**\r\n * Login to SAP ADT server\r\n *\r\n * Currently supports basic authentication only.\r\n * SAML and SSO flows are not yet implemented.\r\n *\r\n * @param state - Session state to update\r\n * @param request - HTTP request function from client\r\n * @returns Session object or error\r\n */\r\nexport async function login(\r\n state: SessionState,\r\n request: RequestFn\r\n): AsyncResult<Session, Error> {\r\n // Validate authentication type is supported.\r\n if (state.config.auth.type === 'saml') {\r\n return err(new Error('SAML authentication not yet implemented'));\r\n }\r\n\r\n if (state.config.auth.type === 'sso') {\r\n return err(new Error('SSO authentication not yet implemented'));\r\n }\r\n\r\n // Fetch CSRF token from SAP server.\r\n const [token, tokenErr] = await fetchCsrfToken(state, request);\r\n if (tokenErr) {\r\n return err(new Error(`Login failed: ${tokenErr.message}`));\r\n }\r\n\r\n // Extract username from authentication config.\r\n const username = state.config.auth.type === 'basic' ? state.config.auth.username : '';\r\n\r\n // Create session object with 8-hour expiration.\r\n const session: Session = {\r\n sessionId: token,\r\n username,\r\n expiresAt: Date.now() + (8 * 60 * 60 * 1000),\r\n };\r\n\r\n // Update session state.\r\n state.session = session;\r\n\r\n return ok(session);\r\n}\r\n\r\n/**\r\n * Logout from SAP ADT server\r\n *\r\n * Calls the SAP logoff endpoint and clears local state.\r\n *\r\n * @param state - Session state to clear\r\n * @param request - HTTP request function from client\r\n * @returns void or error\r\n */\r\nexport async function logout(\r\n state: SessionState,\r\n request: RequestFn\r\n): AsyncResult<void, Error> {\r\n // Execute logout request to SAP server.\r\n const [response, requestErr] = await request({\r\n method: 'POST',\r\n path: '/sap/public/bc/icf/logoff',\r\n });\r\n\r\n if (requestErr) {\r\n return err(new Error(`Logout failed: ${requestErr.message}`));\r\n }\r\n\r\n if (!response.ok) {\r\n const text = await response.text();\r\n return err(new Error(`Logout failed with status ${response.status}: ${text}`));\r\n }\r\n\r\n // Clear local session state.\r\n state.csrfToken = null;\r\n state.session = null;\r\n\r\n return ok(undefined);\r\n}\r\n\r\n/**\r\n * Reset session by logging out and back in\r\n *\r\n * Called automatically on 500 errors to recover from session expiration.\r\n *\r\n * @param state - Session state to reset\r\n * @param request - HTTP request function from client\r\n * @returns void or error\r\n */\r\nexport async function sessionReset(\r\n state: SessionState,\r\n request: RequestFn\r\n): AsyncResult<void, Error> {\r\n // Attempt to logout from current session.\r\n await logout(state, request);\r\n\r\n // Clear session state regardless of logout result.\r\n state.csrfToken = null;\r\n state.session = null;\r\n\r\n // Re-login to establish new session.\r\n const [, loginErr] = await login(state, request);\r\n if (loginErr) {\r\n return err(loginErr);\r\n }\r\n\r\n return ok(undefined);\r\n}\r\n","// ADT Object Type Configuration — metadata for SAP development objects\n\nimport type { AsyncResult } from '../../types/result';\n\n// Client interface for ADT requests\nexport interface AdtRequestor {\n request(options: {\n method: 'GET' | 'POST' | 'PUT' | 'DELETE';\n path: string;\n params?: Record<string, string | number>;\n headers?: Record<string, string>;\n body?: string;\n }): AsyncResult<Response, Error>;\n}\n\n// Configuration for a specific SAP object type\nexport interface ObjectConfig {\n /** ADT endpoint path (e.g., 'ddic/ddl/sources') */\n endpoint: string;\n /** XML namespace for creation requests */\n nameSpace: string;\n /** Root element name for creation XML */\n rootName: string;\n /** SAP ADT object type identifier (e.g., 'DDLS/DF') */\n type: string;\n /** Human-readable label (e.g., 'View') */\n label: string;\n /** File extension (e.g., 'asddls') */\n extension: string;\n /** Data preview endpoint (if supported) */\n dpEndpoint?: string;\n /** Data preview parameter name (if supported) */\n dpParam?: string;\n}\n\n/**\n * Result of upsert operation\n */\nexport interface UpsertResult {\n name: string;\n extension: string;\n status: 'created' | 'updated' | 'unchanged';\n transport?: string;\n}\n\n/**\n * Supported object types\n */\nexport type ConfiguredExtension = 'asddls' | 'asdcls' | 'astabldt' | 'aclass' | 'asprog';\n\n/**\n * Object type labels\n */\nexport enum ObjectTypeLabel {\n VIEW = 'View',\n ACCESS_CONTROL = 'Access Control',\n TABLE = 'Table',\n CLASS = 'Class',\n PROGRAM = 'ABAP Program',\n}\n\n/**\n * Configuration map for all supported object types\n *\n * Maps file extensions to their ADT configuration.\n * This is the central registry for object type metadata.\n */\nexport const OBJECT_CONFIG_MAP: Record<ConfiguredExtension, ObjectConfig> = {\n 'asddls': {\n endpoint: 'ddic/ddl/sources',\n nameSpace: 'xmlns:ddl=\"http://www.sap.com/adt/ddic/ddlsources\"',\n rootName: 'ddl:ddlSource',\n type: 'DDLS/DF',\n label: ObjectTypeLabel.VIEW,\n extension: 'asddls',\n dpEndpoint: 'cds',\n dpParam: 'ddlSourceName',\n },\n 'asdcls': {\n endpoint: 'acm/dcl/sources',\n nameSpace: 'xmlns:dcl=\"http://www.sap.com/adt/acm/dclsources\"',\n rootName: 'dcl:dclSource',\n type: 'DCLS/DL',\n label: ObjectTypeLabel.ACCESS_CONTROL,\n extension: 'asdcls',\n },\n 'aclass': {\n endpoint: 'oo/classes',\n nameSpace: 'xmlns:class=\"http://www.sap.com/adt/oo/classes\"',\n rootName: 'class:abapClass',\n type: 'CLAS/OC',\n label: ObjectTypeLabel.CLASS,\n extension: 'aclass',\n },\n 'astabldt': {\n endpoint: 'ddic/tables',\n nameSpace: 'xmlns:blue=\"http://www.sap.com/wbobj/blue\"',\n rootName: 'blue:blueSource',\n type: 'TABL/DT',\n label: ObjectTypeLabel.TABLE,\n extension: 'astabldt',\n dpEndpoint: 'ddic',\n dpParam: 'ddicEntityName',\n },\n 'asprog': {\n endpoint: 'programs/programs',\n nameSpace: 'xmlns:program=\"http://www.sap.com/adt/programs/programs\"',\n rootName: 'program:abapProgram',\n type: 'PROG/P',\n label: ObjectTypeLabel.PROGRAM,\n extension: 'asprog',\n },\n};\n\n/**\n * Get object configuration by extension\n *\n * @param extension - File extension (e.g., 'asddls')\n * @returns Configuration or null if not found\n */\nexport function getConfigByExtension(extension: string): ObjectConfig | null {\n return OBJECT_CONFIG_MAP[extension as ConfiguredExtension] ?? null;\n}\n\n/**\n * Get object configuration by ADT type\n *\n * @param type - ADT type identifier (e.g., 'DDLS/DF')\n * @returns Configuration or null if not found\n */\nexport function getConfigByType(type: string): ObjectConfig | null {\n for (const config of Object.values(OBJECT_CONFIG_MAP)) {\n if (config.type === type) {\n return config;\n }\n }\n return null;\n}\n\n/**\n * Get all configured extensions\n *\n * @returns Array of supported extensions\n */\nexport function getAllExtensions(): ConfiguredExtension[] {\n return Object.keys(OBJECT_CONFIG_MAP) as ConfiguredExtension[];\n}\n\n/**\n * Get all configured ADT types\n *\n * @returns Array of supported ADT types\n */\nexport function getAllTypes(): string[] {\n return Object.values(OBJECT_CONFIG_MAP).map(config => config.type);\n}\n\n/**\n * Check if extension is supported\n *\n * @param extension - Extension to check\n * @returns True if supported\n */\nexport function isExtensionSupported(extension: string): extension is ConfiguredExtension {\n return extension in OBJECT_CONFIG_MAP;\n}\n","/**\n * ADT Helpers — shared utilities for ADT operations\n *\n * Internal helpers used across multiple ADT files.\n * Not exported from the adt/ barrel.\n */\n\nimport type { AsyncResult } from '../../types/result';\nimport { extractError } from '../utils/xml';\nimport { getConfigByExtension } from './types';\nimport type { ObjectConfig } from './types';\n\n/**\n * Check response for errors and return text content\n */\nexport async function checkResponse(\n response: Response | null,\n requestErr: Error | null,\n operation: string\n): AsyncResult<string, Error> {\n // Handle request errors.\n if (requestErr) return [null, requestErr];\n if (!response) return [null, new Error(`${operation}: No response`)];\n\n // Handle HTTP errors.\n if (!response.ok) {\n const text = await response.text();\n const errorMsg = extractError(text);\n // Include status and raw text if no message found for debugging\n if (errorMsg === 'No message found' || errorMsg === 'Failed to parse error XML') {\n return [null, new Error(`${operation}: HTTP ${response.status} - ${text.substring(0, 500)}`)];\n }\n return [null, new Error(`${operation}: ${errorMsg}`)];\n }\n\n // Return successful response text.\n return [await response.text(), null];\n}\n\n/**\n * Validate extension and return config\n */\nexport function requireConfig(extension: string): [ObjectConfig, null] | [null, Error] {\n // Lookup configuration for extension.\n const config = getConfigByExtension(extension);\n if (!config) return [null, new Error(`Unsupported extension: ${extension}`)];\n\n // Return valid configuration.\n return [config, null];\n}\n","/**\n * POST /objects/read — Read object source content\n */\n\nimport type { AsyncResult } from '../../types/result';\nimport { ok, err } from '../../types/result';\nimport type { ObjectRef } from '../../types/requests';\nimport type { AdtRequestor } from './types';\nimport { checkResponse, requireConfig } from './helpers';\n\n/**\n * Object metadata\n */\nexport interface ObjectMetadata {\n name: string;\n extension: string;\n package: string;\n description?: string;\n createdBy?: string;\n createdAt?: string;\n modifiedBy?: string;\n modifiedAt?: string;\n}\n\n/**\n * Object with content (read response)\n */\nexport interface ObjectWithContent extends ObjectMetadata {\n content: string;\n}\n\n/**\n * Read object source content\n *\n * @param client - ADT client\n * @param object - Object reference (name + extension)\n * @returns Object with content or error\n */\nexport async function readObject(\n client: AdtRequestor,\n object: ObjectRef\n): AsyncResult<ObjectWithContent, Error> {\n // Validate object extension is supported.\n const [config, configErr] = requireConfig(object.extension);\n if (configErr) return err(configErr);\n\n // Execute GET request for object source content.\n const [response, requestErr] = await client.request({\n method: 'GET',\n path: `/sap/bc/adt/${config.endpoint}/${object.name}/source/main`,\n headers: { 'Accept': 'text/plain' },\n });\n\n // Validate successful response and extract content.\n const [content, checkErr] = await checkResponse(\n response,\n requestErr,\n `Failed to read ${config.label} ${object.name}`\n );\n if (checkErr) return err(checkErr);\n\n // Build result object with content.\n const result: ObjectWithContent = {\n name: object.name,\n extension: object.extension,\n package: '',\n content,\n };\n\n return ok(result);\n}\n","/**\r\n * Lock/Unlock — Object lock management for editing\r\n */\r\n\r\nimport type { AsyncResult } from '../../types/result';\r\nimport { ok, err } from '../../types/result';\r\nimport type { ObjectRef } from '../../types/requests';\r\nimport type { AdtRequestor } from './types';\r\nimport { extractLockHandle } from '../utils/xml';\r\nimport { checkResponse, requireConfig } from './helpers';\r\nimport { debug } from '../utils/logging';\r\n\r\n/**\r\n * Lock an object for editing\r\n *\r\n * @param client - ADT client\r\n * @param object - Object reference (name + extension)\r\n * @returns Lock handle string or error\r\n */\r\nexport async function lockObject(\r\n client: AdtRequestor,\r\n object: ObjectRef\r\n): AsyncResult<string, Error> {\r\n // Validate object extension is supported.\r\n const [config, configErr] = requireConfig(object.extension);\r\n if (configErr) return err(configErr);\r\n\r\n // Execute lock request.\r\n const [response, requestErr] = await client.request({\r\n method: 'POST',\r\n path: `/sap/bc/adt/${config.endpoint}/${object.name}/source/main`,\r\n params: {\r\n '_action': 'LOCK',\r\n 'accessMode': 'MODIFY',\r\n },\r\n headers: {\r\n 'Accept': 'application/*,application/vnd.sap.as+xml;charset=UTF-8;dataname=com.sap.adt.lock.result',\r\n },\r\n });\r\n\r\n // Validate successful response.\r\n const [text, checkErr] = await checkResponse(\r\n response,\r\n requestErr,\r\n `Failed to lock ${config.label} ${object.name}`\r\n );\r\n if (checkErr) return err(checkErr);\r\n\r\n // Extract lock handle from XML response.\r\n const [lockHandle, extractErr] = extractLockHandle(text);\r\n if (extractErr) {\r\n return err(new Error(`Failed to extract lock handle: ${extractErr.message}`));\r\n }\r\n debug(`Lock acquired: handle=${lockHandle}`);\r\n\r\n return ok(lockHandle);\r\n}\r\n\r\n/**\r\n * Unlock an object after editing\r\n *\r\n * @param client - ADT client\r\n * @param object - Object reference (name + extension)\r\n * @param lockHandle - Lock handle from lockObject()\r\n * @returns void or error\r\n */\r\nexport async function unlockObject(\r\n client: AdtRequestor,\r\n object: ObjectRef,\r\n lockHandle: string\r\n): AsyncResult<void, Error> {\r\n // Validate object extension is supported.\r\n const [config, configErr] = requireConfig(object.extension);\r\n if (configErr) return err(configErr);\r\n\r\n // Execute unlock request.\r\n const [response, requestErr] = await client.request({\r\n method: 'POST',\r\n path: `/sap/bc/adt/${config.endpoint}/${object.name}/source/main`,\r\n params: {\r\n '_action': 'UNLOCK',\r\n 'lockHandle': lockHandle,\r\n },\r\n });\r\n\r\n // Validate successful response.\r\n const [_, checkErr] = await checkResponse(\r\n response,\r\n requestErr,\r\n `Failed to unlock ${config.label} ${object.name}`\r\n );\r\n if (checkErr) return err(checkErr);\r\n\r\n return ok(undefined);\r\n}\r\n","/**\n * Create — Create new SAP development object\n */\n\nimport type { AsyncResult } from '../../types/result';\nimport { ok, err } from '../../types/result';\nimport type { ObjectContent } from '../../types/requests';\nimport type { AdtRequestor } from './types';\nimport { escapeXml } from '../utils/xml';\nimport { checkResponse, requireConfig } from './helpers';\n\n/**\n * Create a new object in SAP\n *\n * @param client - ADT client\n * @param object - Object with content (name, extension, content, description)\n * @param packageName - Target package\n * @param transport - Transport request (required for non-$TMP packages)\n * @param username - Creating user\n * @returns void or error\n */\nexport async function createObject(\n client: AdtRequestor,\n object: ObjectContent,\n packageName: string,\n transport: string | undefined,\n username: string\n): AsyncResult<void, Error> {\n // Validate object extension is supported.\n const [config, configErr] = requireConfig(object.extension);\n if (configErr) return err(configErr);\n\n // Default empty description if not provided.\n const description = object.description ?? '';\n\n // Build XML request body with object metadata.\n const body = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<${config.rootName} ${config.nameSpace}\n xmlns:adtcore=\"http://www.sap.com/adt/core\"\n adtcore:description=\"${escapeXml(description)}\"\n adtcore:language=\"EN\"\n adtcore:name=\"${object.name.toUpperCase()}\"\n adtcore:type=\"${config.type}\"\n adtcore:responsible=\"${username.toUpperCase()}\">\n\n <adtcore:packageRef adtcore:name=\"${packageName}\"/>\n\n</${config.rootName}>`;\n\n // Add transport parameter if provided.\n const params: Record<string, string> = {};\n if (transport) {\n params['corrNr'] = transport;\n }\n\n // Execute create request.\n const [response, requestErr] = await client.request({\n method: 'POST',\n path: `/sap/bc/adt/${config.endpoint}`,\n params,\n headers: { 'Content-Type': 'application/*' },\n body: body.trim(),\n });\n\n // Validate successful response.\n const [_, checkErr] = await checkResponse(\n response,\n requestErr,\n `Failed to create ${config.label} ${object.name}`\n );\n if (checkErr) return err(checkErr);\n\n return ok(undefined);\n}\n","/**\r\n * Update — Update existing SAP development object\r\n */\r\n\r\nimport type { AsyncResult } from '../../types/result';\r\nimport { ok, err } from '../../types/result';\r\nimport type { ObjectContent } from '../../types/requests';\r\nimport type { AdtRequestor } from './types';\r\nimport { checkResponse, requireConfig } from './helpers';\r\nimport { debug } from '../utils/logging';\r\n\r\n/**\r\n * Update an existing object's source content\r\n *\r\n * @param client - ADT client\r\n * @param object - Object with new content\r\n * @param lockHandle - Lock handle from lockObject()\r\n * @param transport - Transport request (required for non-$TMP packages)\r\n * @returns void or error\r\n */\r\nexport async function updateObject(\r\n client: AdtRequestor,\r\n object: ObjectContent,\r\n lockHandle: string,\r\n transport: string | undefined\r\n): AsyncResult<void, Error> {\r\n // Validate object extension is supported.\r\n const [config, configErr] = requireConfig(object.extension);\r\n if (configErr) return err(configErr);\r\n\r\n // Build request parameters with lock handle.\r\n const params: Record<string, string> = {\r\n 'lockHandle': lockHandle,\r\n };\r\n if (transport) {\r\n params['corrNr'] = transport;\r\n }\r\n\r\n // Execute update request to ADT server.\r\n debug(`Update ${object.name}: content length=${object.content?.length ?? 0}`);\r\n const [response, requestErr] = await client.request({\r\n method: 'PUT',\r\n path: `/sap/bc/adt/${config.endpoint}/${object.name}/source/main`,\r\n params,\r\n headers: { 'Content-Type': '*/*' },\r\n body: object.content,\r\n });\r\n debug(`Update response: ${response?.status ?? 'no response'}, err=${requestErr?.message ?? 'none'}`);\r\n\r\n // Validate successful response.\r\n const [_, checkErr] = await checkResponse(\r\n response,\r\n requestErr,\r\n `Failed to update ${config.label} ${object.name}`\r\n );\r\n if (checkErr) return err(checkErr);\r\n\r\n return ok(undefined);\r\n}\r\n","/**\n * Delete — Delete SAP development object\n */\n\nimport type { AsyncResult } from '../../types/result';\nimport { ok, err } from '../../types/result';\nimport type { ObjectRef } from '../../types/requests';\nimport type { AdtRequestor } from './types';\nimport { checkResponse, requireConfig } from './helpers';\n\n/**\n * Delete an object from SAP\n *\n * @param client - ADT client\n * @param object - Object reference (name + extension)\n * @param lockHandle - Lock handle from lockObject()\n * @param transport - Transport request (required for non-$TMP packages)\n * @returns void or error\n */\nexport async function deleteObject(\n client: AdtRequestor,\n object: ObjectRef,\n lockHandle: string,\n transport: string | undefined\n): AsyncResult<void, Error> {\n // Validate object extension is supported.\n const [config, configErr] = requireConfig(object.extension);\n if (configErr) return err(configErr);\n\n // Build request parameters with lock handle.\n const params: Record<string, string> = {\n 'lockHandle': lockHandle,\n };\n if (transport) {\n params['corrNr'] = transport;\n }\n\n // Execute delete request.\n const [response, requestErr] = await client.request({\n method: 'DELETE',\n path: `/sap/bc/adt/${config.endpoint}/${object.name}/source/main`,\n params,\n headers: { 'Accept': 'text/plain' },\n });\n\n // Validate successful response.\n const [_, checkErr] = await checkResponse(\n response,\n requestErr,\n `Failed to delete ${config.label} ${object.name}`\n );\n if (checkErr) return err(checkErr);\n\n return ok(undefined);\n}\n","// ADT Activation — activate ADT objects\r\n\r\nimport type { Result, AsyncResult } from '../../types/result';\r\nimport { ok, err } from '../../types/result';\r\nimport type { ObjectRef } from '../../types/requests';\r\nimport type { AdtRequestor } from './types';\r\nimport { getConfigByExtension } from './types';\r\nimport { extractError, safeParseXml } from '../utils/xml';\r\nimport { debug } from '../utils/logging';\r\n\r\n/**\r\n * Result of activation operation\r\n */\r\nexport interface ActivationResult {\r\n name: string;\r\n extension: string;\r\n status: 'success' | 'warning' | 'error';\r\n messages: ActivationMessage[];\r\n}\r\n\r\nexport interface ActivationMessage {\r\n severity: 'error' | 'warning' | 'info';\r\n text: string;\r\n line?: number;\r\n column?: number;\r\n}\r\n\r\nexport async function activateObjects(\r\n client: AdtRequestor,\r\n objects: ObjectRef[]\r\n): AsyncResult<ActivationResult[], Error> {\r\n // Handle empty input.\r\n if (objects.length === 0) {\r\n return ok([]);\r\n }\r\n\r\n // Validate object extension is supported.\r\n const extension = objects[0]!.extension;\r\n const config = getConfigByExtension(extension);\r\n if (!config) return err(new Error(`Unsupported extension: ${extension}`));\r\n\r\n // Verify all objects have same extension for batch activation.\r\n for (const obj of objects) {\r\n if (obj.extension !== extension) {\r\n return err(new Error('All objects must have the same extension for batch activation'));\r\n }\r\n }\r\n\r\n // Build XML request body with object references.\r\n const objectRefs = objects.map(obj => `<adtcore:objectReference\r\n adtcore:uri=\"/sap/bc/adt/${config.endpoint}/${obj.name.toLowerCase()}\"\r\n adtcore:type=\"${config.type}\"\r\n adtcore:name=\"${obj.name}\"\r\n adtcore:description=\"*\"/>`).join('\\n ');\r\n\r\n const body = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n <adtcore:objectReferences xmlns:adtcore=\"http://www.sap.com/adt/core\">\r\n ${objectRefs}\r\n </adtcore:objectReferences>`;\r\n\r\n // Execute activation request.\r\n const [response, requestErr] = await client.request({\r\n method: 'POST',\r\n path: '/sap/bc/adt/activation',\r\n params: {\r\n 'method': 'activate',\r\n 'preAuditRequested': 'true',\r\n },\r\n headers: {\r\n 'Content-Type': 'application/xml',\r\n 'Accept': 'application/xml',\r\n },\r\n body,\r\n });\r\n\r\n // Validate successful response.\r\n if (requestErr) { return err(requestErr); }\r\n const text = await response.text();\r\n debug(`Activation response status: ${response.status}`);\r\n debug(`Activation response: ${text.substring(0, 500)}`);\r\n if (!response.ok) {\r\n const errorMsg = extractError(text);\r\n return err(new Error(`Activation failed: ${errorMsg}`));\r\n }\r\n\r\n // Parse activation results from response.\r\n const [results, parseErr] = extractActivationErrors(objects, text, extension);\r\n if (parseErr) { return err(parseErr); }\r\n return ok(results);\r\n}\r\n\r\n// Parse activation response XML for errors\r\nfunction extractActivationErrors(\r\n objects: ObjectRef[],\r\n xml: string,\r\n _extension: string\r\n): Result<ActivationResult[], Error> {\r\n // Parse XML response.\r\n const [doc, parseErr] = safeParseXml(xml);\r\n if (parseErr) { return err(parseErr); }\r\n\r\n // Initialize error map with empty arrays for each object.\r\n const errorMap: Map<string, ActivationMessage[]> = new Map();\r\n objects.forEach(obj => errorMap.set(obj.name.toLowerCase(), []));\r\n\r\n // Extract message elements and prepare regex for position parsing.\r\n const msgElements = doc.getElementsByTagName('msg');\r\n const startRegex = /#start=(\\d+),(\\d+)/;\r\n\r\n // Process each message element.\r\n for (let i = 0; i < msgElements.length; i++) {\r\n const msg = msgElements[i];\r\n if (!msg) continue;\r\n\r\n // Skip warning messages (type 'W').\r\n const type = msg.getAttribute('type');\r\n if (type === 'W') continue;\r\n\r\n // Extract object description and href for position info.\r\n const objDescr = msg.getAttribute('objDescr');\r\n const href = msg.getAttribute('href');\r\n if (!objDescr || !href) continue;\r\n\r\n // Parse line and column from href.\r\n let line: number | undefined;\r\n let column: number | undefined;\r\n const match = startRegex.exec(href);\r\n if (match && match[1] && match[2]) {\r\n line = parseInt(match[1], 10);\r\n column = parseInt(match[2], 10);\r\n }\r\n if (!line || !column) continue;\r\n\r\n // Find matching object by name.\r\n const matchingObj = objects.find(obj =>\r\n objDescr.toLowerCase().includes(obj.name.toLowerCase())\r\n );\r\n if (!matchingObj) continue;\r\n\r\n // Extract message text elements.\r\n const shortTextElements = msg.getElementsByTagName('txt');\r\n for (let j = 0; j < shortTextElements.length; j++) {\r\n const txt = shortTextElements[j];\r\n if (!txt) continue;\r\n\r\n const text = txt.textContent;\r\n if (!text) continue;\r\n\r\n // Build activation message with severity and position.\r\n const message: ActivationMessage = {\r\n severity: type === 'E' ? 'error' : 'warning',\r\n text,\r\n line,\r\n column,\r\n };\r\n\r\n // Add message to object's error list.\r\n const messages = errorMap.get(matchingObj.name.toLowerCase()) || [];\r\n messages.push(message);\r\n errorMap.set(matchingObj.name.toLowerCase(), messages);\r\n }\r\n }\r\n\r\n // Build final results with status based on message severity.\r\n const results: ActivationResult[] = objects.map(obj => {\r\n const messages = errorMap.get(obj.name.toLowerCase()) || [];\r\n const hasErrors = messages.some(m => m.severity === 'error');\r\n\r\n return {\r\n name: obj.name,\r\n extension: obj.extension,\r\n status: hasErrors ? 'error' : messages.length > 0 ? 'warning' : 'success',\r\n messages,\r\n };\r\n });\r\n\r\n return ok(results);\r\n}\r\n","/**\n * Tree — Hierarchical tree browsing for packages\n */\n\nimport type { Result, AsyncResult } from '../../types/result';\nimport { ok, err } from '../../types/result';\nimport type { TreeQuery } from '../../types/requests';\nimport type { AdtRequestor } from './types';\nimport { getConfigByType } from './types';\nimport { extractError, safeParseXml } from '../utils/xml';\n\n/**\n * Tree node for hierarchical browsing\n */\nexport interface TreeNode {\n name: string;\n type: 'folder' | 'object';\n objectType?: string;\n extension?: string;\n hasChildren?: boolean;\n children?: TreeNode[];\n}\n\n/**\n * Package info\n */\nexport interface Package {\n name: string;\n description?: string;\n parentPackage?: string;\n}\n\n/**\n * Virtual folder for tree discovery (internal)\n */\ninterface VirtualFolder {\n name: string;\n hasChildrenOfSameFacet: boolean;\n count?: string;\n}\n\n/**\n * Tree discovery internal query (internal)\n */\ninterface TreeDiscoveryQuery {\n PACKAGE?: VirtualFolder;\n TYPE?: VirtualFolder;\n GROUP?: VirtualFolder;\n API?: VirtualFolder;\n}\n\n/**\n * Get hierarchical tree of objects\n *\n * @param client - ADT client\n * @param query - Tree query parameters\n * @returns Tree nodes or error\n */\nexport async function getTree(\n client: AdtRequestor,\n query: TreeQuery\n): AsyncResult<TreeNode[], Error> {\n // Build internal query with package filter.\n const internalQuery: TreeDiscoveryQuery = {};\n if (query.package) {\n internalQuery.PACKAGE = {\n name: query.package.startsWith('..') ? query.package : `..${query.package}`,\n hasChildrenOfSameFacet: false,\n };\n }\n\n // Execute tree discovery and return nodes.\n const [result, resultErr] = await getTreeInternal(client, internalQuery, '*');\n if (resultErr) { return err(resultErr); }\n return ok(result.nodes);\n}\n\n/**\n * Internal tree discovery with full options\n *\n * Exported for use by packages.ts\n */\nexport async function getTreeInternal(\n client: AdtRequestor,\n query: TreeDiscoveryQuery,\n searchPattern: string\n): AsyncResult<{ nodes: TreeNode[]; packages: Package[] }, Error> {\n // Build XML request body.\n const body = constructTreeBody(query, searchPattern);\n\n // Execute virtual folders request.\n const [response, requestErr] = await client.request({\n method: 'POST',\n path: '/sap/bc/adt/repository/informationsystem/virtualfolders/contents',\n headers: {\n 'Content-Type': 'application/vnd.sap.adt.repository.virtualfolders.request.v1+xml',\n 'Accept': 'application/vnd.sap.adt.repository.virtualfolders.result.v1+xml',\n },\n body,\n });\n\n // Validate successful response.\n if (requestErr) { return err(requestErr); }\n if (!response.ok) {\n const text = await response.text();\n const errorMsg = extractError(text);\n return err(new Error(`Tree discovery failed: ${errorMsg}`));\n }\n\n // Parse tree response.\n const text = await response.text();\n const [result, parseErr] = parseTreeResponse(text);\n if (parseErr) { return err(parseErr); }\n return ok(result);\n}\n\n// Construct tree discovery request body.\nfunction constructTreeBody(query: TreeDiscoveryQuery, searchPattern: string): string {\n // Determine which facets are specified vs requested.\n const facets: string[] = [];\n const specified: Record<string, string> = {};\n const sortedFacets = ['PACKAGE', 'GROUP', 'TYPE', 'API'];\n\n for (const facet of sortedFacets) {\n const value = query[facet as keyof TreeDiscoveryQuery];\n if (value) {\n specified[facet] = value.name;\n if (!value.hasChildrenOfSameFacet) {\n facets.push(facet);\n }\n } else {\n facets.push(facet);\n }\n }\n\n // Build XML elements for specified facets using preselection structure.\n const specifiedXml = Object.entries(specified)\n .map(([facet, name]) => ` <vfs:preselection facet=\"${facet.toLowerCase()}\">\n <vfs:value>${name}</vfs:value>\n </vfs:preselection>`)\n .join('\\n');\n\n // Build XML elements for requested facets (lowercase).\n const facetsXml = facets\n .map(facet => ` <vfs:facet>${facet.toLowerCase()}</vfs:facet>`)\n .join('\\n');\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<vfs:virtualFoldersRequest xmlns:vfs=\"http://www.sap.com/adt/ris/virtualFolders\" objectSearchPattern=\"${searchPattern}\">\n${specifiedXml}\n <vfs:facetorder>\n${facetsXml}\n </vfs:facetorder>\n</vfs:virtualFoldersRequest>`;\n}\n\n// Parse tree discovery response.\nfunction parseTreeResponse(xml: string): Result<{ nodes: TreeNode[]; packages: Package[] }, Error> {\n // Parse XML response.\n const [doc, parseErr] = safeParseXml(xml);\n if (parseErr) { return err(parseErr); }\n\n const nodes: TreeNode[] = [];\n const packages: Package[] = [];\n\n // Process virtual folder elements (packages, groups, etc).\n const virtualFolders = doc.getElementsByTagName('vfs:virtualFolder');\n for (let i = 0; i < virtualFolders.length; i++) {\n const vf = virtualFolders[i];\n if (!vf) continue;\n\n const facet = vf.getAttribute('facet');\n const name = vf.getAttribute('name');\n\n // Extract package metadata if this is a package facet.\n if (facet === 'PACKAGE' && name) {\n const desc = vf.getAttribute('description');\n const pkg: Package = {\n name: name.startsWith('..') ? name.substring(2) : name,\n };\n if (desc) {\n pkg.description = desc;\n }\n packages.push(pkg);\n }\n\n if (!name || !facet) continue;\n\n // Add folder node (strip '..' prefix from name).\n nodes.push({\n name: name.startsWith('..') ? name.substring(2) : name,\n type: 'folder',\n hasChildren: vf.getAttribute('hasChildrenOfSameFacet') === 'true',\n });\n }\n\n // Process object elements (actual ADT objects).\n const objects = doc.getElementsByTagName('vfs:object');\n for (let i = 0; i < objects.length; i++) {\n const obj = objects[i];\n if (!obj) continue;\n\n const name = obj.getAttribute('name');\n const type = obj.getAttribute('type');\n if (!name || !type) continue;\n\n // Look up object type configuration.\n const config = getConfigByType(type);\n if (!config) continue;\n\n nodes.push({\n name,\n type: 'object',\n objectType: config.label,\n extension: config.extension,\n });\n }\n\n return ok({ nodes, packages });\n}\n","/**\n * Packages — List available packages\n */\n\nimport type { AsyncResult } from '../../types/result';\nimport { ok, err } from '../../types/result';\nimport type { AdtRequestor } from './types';\nimport type { Package } from './tree';\nimport { getTreeInternal } from './tree';\n\n/**\n * Get list of available packages\n *\n * @param client - ADT client\n * @returns Array of packages or error\n */\nexport async function getPackages(\n client: AdtRequestor\n): AsyncResult<Package[], Error> {\n // Fetch tree with all packages using wildcard filter.\n const [treeResult, treeErr] = await getTreeInternal(client, {}, '*');\n\n // Validate successful tree retrieval.\n if (treeErr) {\n return err(treeErr);\n }\n\n // Extract packages from tree result.\n return ok(treeResult.packages);\n}\n","/**\n * Transports — List transport requests for a package\n */\n\nimport type { Result, AsyncResult } from '../../types/result';\nimport { ok, err } from '../../types/result';\nimport type { AdtRequestor } from './types';\n\n/**\n * Transport request\n */\nexport interface Transport {\n id: string;\n description: string;\n owner: string;\n status: 'modifiable' | 'released';\n}\n\nimport { extractError, safeParseXml } from '../utils/xml';\n\n/**\n * Get transports for a package\n *\n * @param client - ADT client\n * @param packageName - Package name\n * @returns Array of transports or error\n */\nexport async function getTransports(\n client: AdtRequestor,\n packageName: string\n): AsyncResult<Transport[], Error> {\n // Build XML request body for transport check.\n const contentType = 'application/vnd.sap.as+xml; charset=UTF-8; dataname=com.sap.adt.transport.service.checkData';\n const body = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n <asx:abap version=\"1.0\" xmlns:asx=\"http://www.sap.com/abapxml\">\n <asx:values>\n <DATA>\n <PGMID></PGMID>\n <OBJECT></OBJECT>\n <OBJECTNAME></OBJECTNAME>\n <DEVCLASS>${packageName}</DEVCLASS>\n <SUPER_PACKAGE></SUPER_PACKAGE>\n <OPERATION>I</OPERATION>\n <URI>/sap/bc/adt/ddic/ddl/sources/transport_check</URI>\n </DATA>\n </asx:values>\n </asx:abap>`;\n\n // Execute transport check request.\n const [response, requestErr] = await client.request({\n method: 'POST',\n path: '/sap/bc/adt/cts/transportchecks',\n headers: {\n 'Accept': contentType,\n 'Content-Type': contentType,\n },\n body,\n });\n\n // Validate successful response.\n if (requestErr) { return err(requestErr); }\n if (!response.ok) {\n const text = await response.text();\n const errorMsg = extractError(text);\n return err(new Error(`Failed to fetch transports for ${packageName}: ${errorMsg}`));\n }\n\n // Parse transports from response.\n const text = await response.text();\n const [transports, parseErr] = extractTransports(text);\n if (parseErr) { return err(parseErr); }\n return ok(transports);\n}\n\n// Extract transports from XML response.\nfunction extractTransports(xml: string): Result<Transport[], Error> {\n // Parse XML response.\n const [doc, parseErr] = safeParseXml(xml);\n if (parseErr) { return err(parseErr); }\n\n // Extract transport headers from response.\n const transports: Transport[] = [];\n const reqHeaders = doc.getElementsByTagName('REQ_HEADER');\n\n // Process each transport header.\n for (let i = 0; i < reqHeaders.length; i++) {\n const header = reqHeaders[i];\n if (!header) continue;\n\n // Extract transport metadata elements.\n const trkorrElement = header.getElementsByTagName('TRKORR')[0];\n const userElement = header.getElementsByTagName('AS4USER')[0];\n const textElement = header.getElementsByTagName('AS4TEXT')[0];\n if (!trkorrElement || !userElement || !textElement) continue;\n\n // Extract text content from elements.\n const id = trkorrElement.textContent;\n const owner = userElement.textContent;\n const description = textElement.textContent;\n if (!id || !owner || !description) continue;\n\n // Build transport object.\n transports.push({\n id,\n owner,\n description,\n status: 'modifiable',\n });\n }\n\n return ok(transports);\n}\n","// SQL Query Builder — construct safe SQL queries for ADT data preview\n\nimport type { Filter, OrderBy } from '../../types/requests';\n\n// Quote SQL identifier to prevent injection\nexport function quoteIdentifier(name: string): string {\n return `\"${name.replace(/\"/g, '\"\"')}\"`;\n}\n\nexport function buildWhereClauses(filters: Filter[] | undefined): string {\n // Handle empty or undefined filters.\n if (!filters || filters.length === 0) {\n return '';\n }\n\n // Build individual filter conditions.\n const clauses = filters.map(filter => {\n const { column, operator, value } = filter;\n\n // Map operator to SQL syntax.\n switch (operator) {\n case 'eq':\n return `${column} = ${formatValue(value)}`;\n case 'ne':\n return `${column} != ${formatValue(value)}`;\n case 'gt':\n return `${column} > ${formatValue(value)}`;\n case 'ge':\n return `${column} >= ${formatValue(value)}`;\n case 'lt':\n return `${column} < ${formatValue(value)}`;\n case 'le':\n return `${column} <= ${formatValue(value)}`;\n case 'like':\n return `${column} LIKE ${formatValue(value)}`;\n case 'in':\n // Handle array values for IN operator.\n if (Array.isArray(value)) {\n const values = value.map(v => formatValue(v)).join(', ');\n return `${column} IN (${values})`;\n }\n return `${column} IN (${formatValue(value)})`;\n default:\n return '';\n }\n }).filter(c => c);\n\n // Return empty string if no valid clauses.\n if (clauses.length === 0) {\n return '';\n }\n\n // Join clauses with AND.\n return ` WHERE ${clauses.join(' AND ')}`;\n}\n\nexport function buildOrderByClauses(orderBy: OrderBy[] | undefined): string {\n // Handle empty or undefined order by.\n if (!orderBy || orderBy.length === 0) {\n return '';\n }\n\n // Build order by clauses with direction.\n const clauses = orderBy.map(o => `${o.column} ${o.direction.toUpperCase()}`);\n return ` ORDER BY ${clauses.join(', ')}`;\n}\n\nexport function formatValue(value: unknown): string {\n // Handle null values.\n if (value === null) {\n return 'NULL';\n }\n\n // Escape and quote strings.\n if (typeof value === 'string') {\n return `'${value.replace(/'/g, \"''\")}'`;\n }\n\n // Convert booleans to 1 or 0.\n if (typeof value === 'boolean') {\n return value ? '1' : '0';\n }\n\n // Convert other types to string.\n return String(value);\n}\n","/**\n * Preview Parser — Parse data preview XML responses\n *\n * Internal helper used by data.ts, distinct.ts, and count.ts\n */\n\nimport type { Result } from '../../types/result';\nimport { ok, err } from '../../types/result';\nimport { safeParseXml } from '../utils/xml';\n\n/**\n * Data preview result (columnar format)\n */\nexport interface DataFrame {\n columns: ColumnInfo[];\n rows: unknown[][];\n totalRows?: number;\n}\n\nexport interface ColumnInfo {\n name: string;\n dataType: string;\n label?: string;\n}\n\n/**\n * Parse data preview XML response\n *\n * @param xml - XML response from SAP\n * @param maxRows - Maximum rows to parse\n * @param isTable - Whether source is a table (affects column name attribute)\n * @returns DataFrame or error\n */\nexport function parseDataPreview(\n xml: string,\n maxRows: number,\n isTable: boolean\n): Result<DataFrame, Error> {\n // Parse XML response.\n const [doc, parseErr] = safeParseXml(xml);\n if (parseErr) { return err(parseErr); }\n\n const namespace = 'http://www.sap.com/adt/dataPreview';\n\n // Extract column metadata from response.\n const metadataElements = doc.getElementsByTagNameNS(namespace, 'metadata');\n const columns: ColumnInfo[] = [];\n\n for (let i = 0; i < metadataElements.length; i++) {\n const meta = metadataElements[i];\n if (!meta) continue;\n\n // Tables use 'name', views use 'camelCaseName'.\n const nameAttr = isTable ? 'name' : 'camelCaseName';\n const name = meta.getAttributeNS(namespace, nameAttr) || meta.getAttribute('name');\n const dataType = meta.getAttributeNS(namespace, 'colType') || meta.getAttribute('colType');\n if (!name || !dataType) continue;\n\n columns.push({ name, dataType });\n }\n\n // Validate columns were found.\n if (columns.length === 0) {\n return err(new Error('No columns found in preview response'));\n }\n\n // Extract data values organized by column.\n const dataSetElements = doc.getElementsByTagNameNS(namespace, 'dataSet');\n const columnData: string[][] = Array.from({ length: columns.length }, () => []);\n\n for (let i = 0; i < dataSetElements.length; i++) {\n const dataSet = dataSetElements[i];\n if (!dataSet) continue;\n\n const dataElements = dataSet.getElementsByTagNameNS(namespace, 'data');\n for (let j = 0; j < dataElements.length; j++) {\n const data = dataElements[j];\n if (!data) continue;\n\n const value = data.textContent?.trim() || '';\n columnData[i]!.push(value);\n }\n }\n\n // Transform column-oriented data into row-oriented format.\n const rows: unknown[][] = [];\n const rowCount = columnData[0]?.length || 0;\n for (let i = 0; i < Math.min(rowCount, maxRows); i++) {\n const row: unknown[] = [];\n for (let j = 0; j < columns.length; j++) {\n row.push(columnData[j]![i]);\n }\n rows.push(row);\n }\n\n // Build final DataFrame result.\n const dataFrame: DataFrame = {\n columns,\n rows,\n totalRows: rowCount,\n };\n\n return ok(dataFrame);\n}\n","/**\r\n * Data Preview — Query table/view data\r\n */\r\n\r\nimport type { AsyncResult } from '../../types/result';\r\nimport { ok, err } from '../../types/result';\r\nimport type { PreviewQuery } from '../../types/requests';\r\nimport type { AdtRequestor } from './types';\r\nimport type { DataFrame } from './previewParser';\r\nimport { getConfigByExtension } from './types';\r\nimport { extractError } from '../utils/xml';\r\nimport { validateSqlInput } from '../utils/sql';\r\nimport { debug } from '../utils/logging';\r\nimport { buildWhereClauses, buildOrderByClauses } from './queryBuilder';\r\nimport { parseDataPreview } from './previewParser';\r\n\r\n/**\r\n * Preview table/view data with filters and sorting\r\n *\r\n * @param client - ADT client\r\n * @param query - Preview query parameters\r\n * @returns DataFrame or error\r\n */\r\nexport async function previewData(\r\n client: AdtRequestor,\r\n query: PreviewQuery\r\n): AsyncResult<DataFrame, Error> {\r\n // Confirm object is valid for data previews.\r\n const extension = query.objectType === 'table' ? 'astabldt' : 'asddls';\r\n const config = getConfigByExtension(extension);\r\n if (!config || !config.dpEndpoint || !config.dpParam) {\r\n return err(new Error(`Data preview not supported for object type: ${query.objectType}`));\r\n }\r\n\r\n // Construct SQL query for data preview\r\n const limit = query.limit ?? 100;\r\n\r\n const whereClauses = buildWhereClauses(query.filters);\r\n const orderByClauses = buildOrderByClauses(query.orderBy);\r\n // SAP SQL doesn't use quoted identifiers for object names\r\n const sqlQuery = `select * from ${query.objectName}${whereClauses}${orderByClauses}`;\r\n\r\n const [, validationErr] = validateSqlInput(sqlQuery);\r\n if (validationErr) {\r\n return err(new Error(`SQL validation failed: ${validationErr.message}`));\r\n }\r\n\r\n // Execute data preview request.\r\n debug(`Data preview: endpoint=${config.dpEndpoint}, param=${config.dpParam}=${query.objectName}`);\r\n debug(`SQL: ${sqlQuery}`);\r\n const [response, requestErr] = await client.request({\r\n method: 'POST',\r\n path: `/sap/bc/adt/datapreview/${config.dpEndpoint}`,\r\n params: {\r\n 'rowNumber': limit,\r\n [config.dpParam]: query.objectName,\r\n },\r\n headers: {\r\n 'Accept': 'application/vnd.sap.adt.datapreview.table.v1+xml',\r\n 'Content-Type': 'text/plain',\r\n },\r\n body: sqlQuery,\r\n });\r\n\r\n // Validate successful response.\r\n if (requestErr) { return err(requestErr); }\r\n if (!response.ok) {\r\n const text = await response.text();\r\n debug(`Data preview error response: ${text.substring(0, 500)}`);\r\n const errorMsg = extractError(text);\r\n return err(new Error(`Data preview failed: ${errorMsg}`));\r\n }\r\n const text = await response.text();\r\n\r\n // Confirm successful dataframe format\r\n const [dataFrame, parseErr] = parseDataPreview(text, limit, query.objectType === 'table');\r\n if (parseErr) { return err(parseErr); }\r\n return ok(dataFrame);\r\n}\r\n","/**\n * Distinct Values — Get distinct column values with counts\n */\n\nimport type { AsyncResult } from '../../types/result';\nimport { ok, err } from '../../types/result';\nimport type { AdtRequestor } from './types';\n\n/**\n * Distinct values result\n */\nexport interface DistinctResult {\n column: string;\n values: Array<{\n value: unknown;\n count: number;\n }>;\n}\n\nimport { getConfigByExtension } from './types';\nimport { extractError, safeParseXml } from '../utils/xml';\nimport { validateSqlInput } from '../utils/sql';\n\nconst MAX_ROW_COUNT = 50000;\n\n/**\n * Get distinct values for a column with counts\n *\n * @param client - ADT client\n * @param objectName - Table or view name\n * @param column - Column name\n * @param objectType - 'table' or 'view'\n * @returns Distinct values with counts or error\n */\nexport async function getDistinctValues(\n client: AdtRequestor,\n objectName: string,\n column: string,\n objectType: 'table' | 'view' = 'view'\n): AsyncResult<DistinctResult, Error> {\n // Determine endpoint configuration based on object type.\n const extension = objectType === 'table' ? 'astabldt' : 'asddls';\n const config = getConfigByExtension(extension);\n\n // Validate object type supports data preview operations.\n if (!config || !config.dpEndpoint || !config.dpParam) {\n return err(new Error(`Data preview not supported for object type: ${objectType}`));\n }\n\n // Construct SQL query for distinct values with counts.\n // SAP ADT data preview uses ABAP Open SQL which does not support quoted identifiers.\n const columnName = column.toUpperCase();\n const sqlQuery = `SELECT ${columnName} AS value, COUNT(*) AS count FROM ${objectName} GROUP BY ${columnName}`;\n\n // Validate SQL query for injection risks.\n const [, validationErr] = validateSqlInput(sqlQuery);\n if (validationErr) {\n return err(new Error(`SQL validation failed: ${validationErr.message}`));\n }\n\n // Execute distinct values request.\n const [response, requestErr] = await client.request({\n method: 'POST',\n path: `/sap/bc/adt/datapreview/${config.dpEndpoint}`,\n params: {\n 'rowNumber': MAX_ROW_COUNT,\n [config.dpParam]: objectName,\n },\n headers: {\n 'Accept': 'application/vnd.sap.adt.datapreview.table.v1+xml',\n },\n body: sqlQuery,\n });\n\n // Validate successful response.\n if (requestErr) {\n return err(requestErr);\n }\n\n if (!response.ok) {\n const text = await response.text();\n const errorMsg = extractError(text);\n return err(new Error(`Distinct values query failed: ${errorMsg}`));\n }\n\n // Parse XML response to extract distinct values directly.\n // GROUP BY queries return simpler structure without full column metadata.\n const text = await response.text();\n const [doc, parseErr] = safeParseXml(text);\n if (parseErr) {\n return err(parseErr);\n }\n\n // Extract data from dataPreview:dataSet elements.\n // Each dataSet contains two data elements: value and count.\n const dataSets = doc.getElementsByTagNameNS('http://www.sap.com/adt/dataPreview', 'dataSet');\n const values: Array<{ value: unknown; count: number }> = [];\n\n for (let i = 0; i < dataSets.length; i++) {\n const dataSet = dataSets[i];\n if (!dataSet) continue;\n\n const dataElements = dataSet.getElementsByTagNameNS('http://www.sap.com/adt/dataPreview', 'data');\n if (dataElements.length < 2) continue;\n\n const value = dataElements[0]?.textContent ?? '';\n const countText = dataElements[1]?.textContent?.trim() ?? '0';\n values.push({\n value,\n count: parseInt(countText, 10),\n });\n }\n\n const result: DistinctResult = {\n column,\n values,\n };\n\n return ok(result);\n}\n","/**\n * Count Rows — Get total row count for table/view\n */\n\nimport type { AsyncResult } from '../../types/result';\nimport { ok, err } from '../../types/result';\nimport type { AdtRequestor } from './types';\nimport { getConfigByExtension } from './types';\nimport { extractError, safeParseXml } from '../utils/xml';\nimport { validateSqlInput } from '../utils/sql';\n\n/**\n * Count total rows in a table or view\n *\n * @param client - ADT client\n * @param objectName - Table or view name\n * @param objectType - 'table' or 'view'\n * @returns Row count or error\n */\nexport async function countRows(\n client: AdtRequestor,\n objectName: string,\n objectType: 'table' | 'view'\n): AsyncResult<number, Error> {\n // Determine endpoint configuration based on object type.\n const extension = objectType === 'table' ? 'astabldt' : 'asddls';\n const config = getConfigByExtension(extension);\n\n // Validate object type supports data preview.\n if (!config || !config.dpEndpoint || !config.dpParam) {\n return err(new Error(`Data preview not supported for object type: ${objectType}`));\n }\n\n // Build SQL query to count rows.\n // SAP ADT data preview uses ABAP Open SQL which does not support quoted identifiers.\n const sqlQuery = `SELECT COUNT(*) AS count FROM ${objectName}`;\n\n // Validate SQL query for safety.\n const [, validationErr] = validateSqlInput(sqlQuery);\n if (validationErr) {\n return err(new Error(`SQL validation failed: ${validationErr.message}`));\n }\n\n // Execute count query request.\n const [response, requestErr] = await client.request({\n method: 'POST',\n path: `/sap/bc/adt/datapreview/${config.dpEndpoint}`,\n params: {\n 'rowNumber': 1,\n [config.dpParam]: objectName,\n },\n headers: {\n 'Accept': 'application/vnd.sap.adt.datapreview.table.v1+xml',\n },\n body: sqlQuery,\n });\n\n // Validate successful request.\n if (requestErr) {\n return err(requestErr);\n }\n\n // Validate successful response.\n if (!response.ok) {\n const text = await response.text();\n const errorMsg = extractError(text);\n return err(new Error(`Row count query failed: ${errorMsg}`));\n }\n\n // Parse XML response to extract count value directly.\n // COUNT responses have simpler structure without column metadata.\n const text = await response.text();\n const [doc, parseErr] = safeParseXml(text);\n if (parseErr) {\n return err(parseErr);\n }\n\n // Extract count from dataPreview:data elements.\n const dataElements = doc.getElementsByTagNameNS('http://www.sap.com/adt/dataPreview', 'data');\n if (dataElements.length === 0) {\n return err(new Error('No count value returned'));\n }\n\n // Get the first data element's text content (the count value).\n const countText = dataElements[0]?.textContent?.trim();\n if (!countText) {\n return err(new Error('Empty count value returned'));\n }\n\n // Parse and validate count as integer.\n const count = parseInt(countText, 10);\n if (isNaN(count)) {\n return err(new Error('Invalid count value returned'));\n }\n\n return ok(count);\n}\n","/**\n * Search Objects — Quick search by name pattern\n */\n\nimport type { Result, AsyncResult } from '../../types/result';\nimport { ok, err } from '../../types/result';\nimport type { AdtRequestor } from './types';\n\n/**\n * Search result\n */\nexport interface SearchResult {\n name: string;\n extension: string;\n package: string;\n description?: string;\n objectType: string;\n}\n\nimport { getConfigByType, getAllTypes } from './types';\nimport { extractError, safeParseXml } from '../utils/xml';\n\n/**\n * Search for objects by name pattern\n *\n * @param client - ADT client\n * @param query - Search pattern (supports wildcards)\n * @param types - Optional array of object type filters\n * @returns Array of matching objects or error\n */\nexport async function searchObjects(\n client: AdtRequestor,\n query: string,\n types?: string[]\n): AsyncResult<SearchResult[], Error> {\n // Build search parameters.\n const searchPattern = query || '*';\n const objectTypes = types && types.length > 0 ? types : getAllTypes();\n\n // Construct query parameters (matching Python reference exactly).\n const params: Array<[string, string]> = [\n ['operation', 'quickSearch'],\n ['query', searchPattern],\n ['maxResults', '10001'],\n ];\n for (const type of objectTypes) {\n params.push(['objectType', type]);\n }\n\n // Build URL search params.\n const urlParams = new URLSearchParams();\n for (const [key, value] of params) {\n urlParams.append(key, value);\n }\n\n // Execute search request.\n const [response, requestErr] = await client.request({\n method: 'GET',\n path: `/sap/bc/adt/repository/informationsystem/search?${urlParams.toString()}`,\n });\n\n // Validate successful response.\n if (requestErr) { return err(requestErr); }\n if (!response.ok) {\n const text = await response.text();\n const errorMsg = extractError(text);\n return err(new Error(`Search failed: ${errorMsg}`));\n }\n\n // Parse search results from response.\n const text = await response.text();\n const [results, parseErr] = parseSearchResults(text);\n if (parseErr) { return err(parseErr); }\n return ok(results);\n}\n\n// Parse search results from XML.\nfunction parseSearchResults(xml: string): Result<SearchResult[], Error> {\n // Parse XML response.\n const [doc, parseErr] = safeParseXml(xml);\n if (parseErr) { return err(parseErr); }\n\n // Extract object reference elements.\n const results: SearchResult[] = [];\n const objectRefs = doc.getElementsByTagNameNS('http://www.sap.com/adt/core', 'objectReference');\n\n // Process each object reference.\n for (let i = 0; i < objectRefs.length; i++) {\n const obj = objectRefs[i];\n if (!obj) continue;\n\n // Extract object metadata.\n const name = obj.getAttributeNS('http://www.sap.com/adt/core', 'name') || obj.getAttribute('adtcore:name');\n const type = obj.getAttributeNS('http://www.sap.com/adt/core', 'type') || obj.getAttribute('adtcore:type');\n const description = obj.getAttributeNS('http://www.sap.com/adt/core', 'description') || obj.getAttribute('adtcore:description');\n if (!name || !type) continue;\n\n // Look up object type configuration.\n const config = getConfigByType(type);\n if (!config) continue;\n\n // Extract package reference if available.\n const packageRef = obj.getElementsByTagNameNS('http://www.sap.com/adt/core', 'packageRef')[0];\n const packageName = packageRef\n ? (packageRef.getAttributeNS('http://www.sap.com/adt/core', 'name') || packageRef.getAttribute('adtcore:name'))\n : '';\n\n // Build search result object.\n const result: SearchResult = {\n name,\n extension: config.extension,\n package: packageName || '',\n objectType: config.label,\n };\n if (description) {\n result.description = description;\n }\n results.push(result);\n }\n\n return ok(results);\n}\n","/**\n * Where-Used — Find object dependencies\n */\n\nimport type { Result, AsyncResult } from '../../types/result';\nimport { ok, err } from '../../types/result';\nimport type { ObjectRef } from '../../types/requests';\nimport type { AdtRequestor } from './types';\n\n/**\n * Where-used dependency\n */\nexport interface Dependency {\n name: string;\n extension: string;\n package: string;\n usageType: string;\n}\n\nimport { getConfigByType, getConfigByExtension } from './types';\nimport { extractError, safeParseXml } from '../utils/xml';\n\n/**\n * Find where an object is used (dependencies)\n *\n * @param client - ADT client\n * @param object - Object to analyze\n * @returns Array of dependent objects or error\n */\nexport async function findWhereUsed(\n client: AdtRequestor,\n object: ObjectRef\n): AsyncResult<Dependency[], Error> {\n // Validate object extension is supported.\n const config = getConfigByExtension(object.extension);\n if (!config) {\n return err(new Error(`Unsupported extension: ${object.extension}`));\n }\n\n // Build object URI and request body.\n const uri = `/sap/bc/adt/${config.endpoint}/${object.name}`;\n const body = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n <usagereferences:usageReferenceRequest xmlns:usagereferences=\"http://www.sap.com/adt/ris/usageReferences\">\n <usagereferences:affectedObjects/>\n </usagereferences:usageReferenceRequest>`;\n\n // Execute where-used query.\n const [response, requestErr] = await client.request({\n method: 'POST',\n path: '/sap/bc/adt/repository/informationsystem/usageReferences',\n params: {\n 'uri': uri,\n 'ris_request_type': 'usageReferences',\n },\n headers: {\n 'Content-Type': 'application/vnd.sap.adt.repository.usagereferences.request.v1+xml',\n 'Accept': 'application/vnd.sap.adt.repository.usagereferences.result.v1+xml',\n },\n body,\n });\n\n // Validate successful response.\n if (requestErr) { return err(requestErr); }\n if (!response.ok) {\n const text = await response.text();\n const errorMsg = extractError(text);\n return err(new Error(`Where-used query failed: ${errorMsg}`));\n }\n\n // Parse dependencies from response.\n const text = await response.text();\n const [dependencies, parseErr] = parseWhereUsed(text);\n if (parseErr) { return err(parseErr); }\n return ok(dependencies);\n}\n\n// Parse where-used results from XML.\nfunction parseWhereUsed(xml: string): Result<Dependency[], Error> {\n // Parse XML response.\n const [doc, parseErr] = safeParseXml(xml);\n if (parseErr) { return err(parseErr); }\n\n // Extract referenced object elements.\n const dependencies: Dependency[] = [];\n const referencedObjects = doc.getElementsByTagNameNS(\n 'http://www.sap.com/adt/ris/usageReferences',\n 'referencedObject'\n );\n\n // Process each referenced object.\n for (let i = 0; i < referencedObjects.length; i++) {\n const refObj = referencedObjects[i];\n if (!refObj) continue;\n\n // Extract ADT object element.\n const adtObject = refObj.getElementsByTagNameNS(\n 'http://www.sap.com/adt/ris/usageReferences',\n 'adtObject'\n )[0];\n if (!adtObject) continue;\n\n // Extract object name and type.\n const name = adtObject.getAttributeNS('http://www.sap.com/adt/core', 'name') || adtObject.getAttribute('adtcore:name');\n const type = adtObject.getAttributeNS('http://www.sap.com/adt/core', 'type') || adtObject.getAttribute('adtcore:type');\n if (!name || !type) continue;\n\n // Look up object type configuration.\n const config = getConfigByType(type);\n if (!config) continue;\n\n // Extract package reference if available.\n const packageRef = adtObject.getElementsByTagNameNS('http://www.sap.com/adt/core', 'packageRef')[0];\n const packageName = packageRef\n ? (packageRef.getAttributeNS('http://www.sap.com/adt/core', 'name') || packageRef.getAttribute('adtcore:name'))\n : '';\n\n // Build dependency object.\n dependencies.push({\n name,\n extension: config.extension,\n package: packageName || '',\n usageType: 'reference',\n });\n }\n\n return ok(dependencies);\n}\n","/**\n * Create Transport — Create a new transport request for a package\n */\n\nimport type { AsyncResult } from '../../types/result';\nimport { ok, err } from '../../types/result';\nimport type { AdtRequestor } from './types';\nimport { dictToAbapXml, extractError } from '../utils/xml';\n\n/**\n * Configuration for creating a transport\n */\nexport interface TransportConfig {\n /** Package name (DEVCLASS) */\n package: string;\n /** Transport description/text */\n description: string;\n}\n\n/**\n * Create a new transport request\n *\n * @param client - ADT client\n * @param config - Transport configuration\n * @returns Transport ID or error\n */\nexport async function createTransport(\n client: AdtRequestor,\n config: TransportConfig\n): AsyncResult<string, Error> {\n // Build XML request body.\n const body = dictToAbapXml({\n DEVCLASS: config.package,\n REQUEST_TEXT: config.description,\n REF: '',\n OPERATION: 'I',\n });\n\n // Execute transport creation request.\n const [response, requestErr] = await client.request({\n method: 'POST',\n path: '/sap/bc/adt/cts/transports',\n headers: {\n 'Content-Type': 'application/vnd.sap.as+xml; charset=UTF-8; dataname=com.sap.adt.CreateCorrectionRequest',\n 'Accept': 'text/plain',\n },\n body,\n });\n\n // Validate response.\n if (requestErr) return err(requestErr);\n if (!response.ok) {\n const text = await response.text();\n const errorMsg = extractError(text);\n return err(new Error(`Failed to create transport for ${config.package}: ${errorMsg}`));\n }\n\n // Extract transport ID from response.\n const text = await response.text();\n const transportId = text.trim().split('/').pop();\n\n if (!transportId) {\n return err(new Error('Failed to parse transport ID from response'));\n }\n\n return ok(transportId);\n}\n","/**\n * Git Diff — Compare local content with server content\n *\n * Uses Myers diff algorithm to compute line-by-line differences.\n */\n\nimport { diffArrays, type ChangeObject } from 'diff';\nimport type { AsyncResult } from '../../types/result';\nimport { ok, err } from '../../types/result';\nimport type { AdtRequestor } from './types';\nimport type { ObjectContent } from '../../types/requests';\nimport { readObject } from './read';\nimport { getConfigByExtension } from './types';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Types (colocated - only used by this function)\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Base fields for all diff hunks */\ninterface BaseDiffHunk {\n /** Total number of lines in the hunk */\n length: number;\n /** Starting line in the diff output (0-indexed) */\n diffStart: number;\n /** Starting line in the local file (0-indexed) */\n localStart: number;\n}\n\n/** Addition or deletion hunk */\nexport interface SimpleDiffHunk extends BaseDiffHunk {\n type: 'addition' | 'deletion';\n /** Lines added or removed */\n changes: string[];\n}\n\n/** Modification hunk (deletion immediately followed by addition) */\nexport interface ModifiedDiffHunk extends BaseDiffHunk {\n type: 'modification';\n /** Tuple of [server_lines, local_lines] */\n changes: [string[], string[]];\n}\n\n/** Any diff hunk */\nexport type DiffHunk = SimpleDiffHunk | ModifiedDiffHunk;\n\n/** Result of comparing a single object */\nexport interface DiffResult {\n name: string;\n extension: string;\n label: string;\n diffs: DiffHunk[];\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Implementation\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Compute diff between server and local content\n *\n * Converts jsdiff ChangeObject[] output to the hunk format matching Python behavior.\n */\nfunction computeDiff(serverLines: string[], localLines: string[]): DiffHunk[] {\n const changes = diffArrays(serverLines, localLines);\n const hunks: DiffHunk[] = [];\n\n let diffIndex = 0;\n let localIndex = 0;\n\n for (let i = 0; i < changes.length; i++) {\n const change = changes[i] as ChangeObject<string[]>;\n if (!change) continue;\n\n if (!change.added && !change.removed) {\n // Unchanged lines - advance both indices\n const count = change.count ?? change.value.length;\n diffIndex += count;\n localIndex += count;\n continue;\n }\n\n if (change.removed) {\n // Check if next change is an addition (making this a modification)\n const nextChange = changes[i + 1] as ChangeObject<string[]> | undefined;\n\n if (nextChange?.added) {\n // Modification: deletion followed by addition\n const serverChanges = change.value;\n const localChanges = nextChange.value;\n const modHunk: ModifiedDiffHunk = {\n type: 'modification',\n length: serverChanges.length + localChanges.length,\n diffStart: diffIndex,\n localStart: localIndex,\n changes: [serverChanges, localChanges],\n };\n hunks.push(modHunk);\n\n // Advance indices and skip the next addition\n diffIndex += serverChanges.length + localChanges.length;\n localIndex += localChanges.length;\n i++; // Skip the addition we just processed\n continue;\n }\n\n // Pure deletion\n const deletionHunk: SimpleDiffHunk = {\n type: 'deletion',\n length: change.value.length,\n diffStart: diffIndex,\n localStart: localIndex,\n changes: change.value,\n };\n hunks.push(deletionHunk);\n diffIndex += change.value.length;\n continue;\n }\n\n if (!change.added) continue;\n\n // Pure addition (not preceded by deletion - handled above)\n const additionHunk: SimpleDiffHunk = {\n type: 'addition',\n length: change.value.length,\n diffStart: diffIndex,\n localStart: localIndex,\n changes: change.value,\n };\n hunks.push(additionHunk);\n diffIndex += change.value.length;\n localIndex += change.value.length;\n }\n\n return hunks;\n}\n\n/**\n * Compare local object content with server content\n *\n * @param client - ADT client\n * @param object - Object with local content to compare\n * @returns Diff result or error\n */\nexport async function gitDiff(\n client: AdtRequestor,\n object: ObjectContent\n): AsyncResult<DiffResult, Error> {\n // Read current server content.\n const [serverObj, readErr] = await readObject(client, {\n name: object.name,\n extension: object.extension,\n });\n\n if (readErr) {\n return err(new Error(`${object.name} does not exist on server`));\n }\n\n // Get label from config.\n const config = getConfigByExtension(object.extension);\n const label = config?.label ?? object.extension;\n\n // Split content into lines for comparison.\n const serverLines = serverObj.content.split('\\n');\n const localLines = object.content.split('\\n');\n\n // Compute diff.\n const diffs = computeDiff(serverLines, localLines);\n\n return ok({\n name: serverObj.name,\n extension: serverObj.extension,\n label,\n diffs,\n });\n}\n","/**\r\n * ADT Client Core Implementation\r\n *\r\n * HTTP client for SAP ADT (ABAP Development Tools) with:\r\n * - Session management (login/logout)\r\n * - CSRF token fetching and automatic refresh\r\n * - Basic authentication (SAML and SSO to be implemented)\r\n * - Automatic retry on 403 CSRF errors\r\n * - Session reset on 500 errors\r\n *\r\n * Uses web standard APIs (fetch, Request, Response) - runtime-agnostic.\r\n * High-level ADT operations (CRAUD, preview, etc.) are stubs to be implemented.\r\n */\r\n\r\nimport type { ClientConfig } from '../types/config';\r\nimport type {\r\n ObjectRef,\r\n ObjectContent,\r\n TreeQuery,\r\n PreviewQuery,\r\n} from '../types/requests';\r\nimport type { Session } from './session/types';\r\nimport type {\r\n ObjectWithContent,\r\n UpsertResult,\r\n ActivationResult,\r\n TreeNode,\r\n Transport,\r\n Package,\r\n DataFrame,\r\n DistinctResult,\r\n SearchResult,\r\n Dependency,\r\n TransportConfig,\r\n DiffResult,\r\n ObjectConfig,\r\n} from './adt';\r\nimport type { Result, AsyncResult } from '../types/result';\r\nimport { ok, err } from '../types/result';\r\nimport {\r\n CSRF_TOKEN_HEADER,\r\n BASE_HEADERS,\r\n DEFAULT_TIMEOUT,\r\n buildRequestHeaders,\r\n debug,\r\n debugError,\r\n} from './utils';\r\nimport { clientConfigSchema } from '../types/config';\r\nimport * as sessionOps from './session/login';\r\nimport * as adt from './adt';\r\nimport { Agent, fetch as undiciFetch } from 'undici';\r\n\r\n// HTTP request options for internal operations\r\ninterface RequestOptions {\r\n method: 'GET' | 'POST' | 'PUT' | 'DELETE';\r\n path: string;\r\n params?: Record<string, string | number>;\r\n headers?: Record<string, string>;\r\n body?: string;\r\n}\r\n\r\n// ADT Client interface - provides all operations for interacting with SAP ADT servers\r\nexport interface ADTClient {\r\n /** Current session info (null if not logged in) */\r\n readonly session: Session | null;\r\n\r\n // Lifecycle\r\n login(): AsyncResult<Session>;\r\n logout(): AsyncResult<void>;\r\n\r\n // CRAUD Operations\r\n read(objects: ObjectRef[]): AsyncResult<ObjectWithContent[]>;\r\n create(object: ObjectContent, packageName: string, transport?: string): AsyncResult<void>;\r\n update(object: ObjectContent, transport?: string): AsyncResult<void>;\r\n upsert(objects: ObjectContent[], packageName: string, transport?: string): AsyncResult<UpsertResult[]>;\r\n activate(objects: ObjectRef[]): AsyncResult<ActivationResult[]>;\r\n delete(objects: ObjectRef[], transport?: string): AsyncResult<void>;\r\n\r\n // Discovery\r\n getPackages(): AsyncResult<Package[]>;\r\n getTree(query: TreeQuery): AsyncResult<TreeNode[]>;\r\n getTransports(packageName: string): AsyncResult<Transport[]>;\r\n\r\n // Data Preview\r\n previewData(query: PreviewQuery): AsyncResult<DataFrame>;\r\n getDistinctValues(objectName: string, column: string, objectType?: 'table' | 'view'): AsyncResult<DistinctResult>;\r\n countRows(objectName: string, objectType: 'table' | 'view'): AsyncResult<number>;\r\n\r\n // Search\r\n search(query: string, types?: string[]): AsyncResult<SearchResult[]>;\r\n whereUsed(object: ObjectRef): AsyncResult<Dependency[]>;\r\n\r\n // Transport Management\r\n createTransport(config: TransportConfig): AsyncResult<string>;\r\n\r\n // Diff Operations\r\n gitDiff(objects: ObjectContent[]): AsyncResult<DiffResult[]>;\r\n\r\n // Configuration\r\n getObjectConfig(): ObjectConfig[];\r\n}\r\n\r\n// Internal client state (implements SessionState interface from session/login)\r\ninterface ClientState extends sessionOps.SessionState {\r\n config: ClientConfig;\r\n cookies: Map<string, string>;\r\n}\r\n\r\n// Build URL search parameters with sap-client\r\nfunction buildParams(\r\n baseParams: Record<string, string | number> | undefined,\r\n clientNum: string\r\n): URLSearchParams {\r\n const params = new URLSearchParams();\r\n\r\n // Add any custom parameters from the request.\r\n if (baseParams) {\r\n for (const [key, value] of Object.entries(baseParams)) {\r\n params.append(key, String(value));\r\n }\r\n }\r\n\r\n // Always append sap-client parameter.\r\n params.append('sap-client', clientNum);\r\n\r\n return params;\r\n}\r\n\r\n// Build full URL from base URL and path\r\nfunction buildUrl(baseUrl: string, path: string, params?: URLSearchParams): string {\r\n // Construct URL from base and path.\r\n const url = new URL(path, baseUrl);\r\n\r\n // Merge query parameters: preserve existing ones from path, add new ones.\r\n if (params) {\r\n for (const [key, value] of params.entries()) {\r\n url.searchParams.append(key, value);\r\n }\r\n }\r\n\r\n return url.toString();\r\n}\r\n\r\n/**\r\n * ADT Client implementation class.\r\n * Methods are defined on the prototype (not recreated per instance).\r\n */\r\nclass ADTClientImpl implements ADTClient {\r\n private state: ClientState;\r\n private requestor: adt.AdtRequestor;\r\n private agent: Agent | undefined;\r\n\r\n constructor(config: ClientConfig) {\r\n this.state = {\r\n config,\r\n session: null,\r\n csrfToken: null,\r\n cookies: new Map(),\r\n };\r\n // Bind request method for use as requestor\r\n this.requestor = { request: this.request.bind(this) };\r\n // Create insecure agent if SSL verification should be skipped\r\n if (config.insecure) {\r\n this.agent = new Agent({\r\n connect: {\r\n rejectUnauthorized: false,\r\n checkServerIdentity: () => undefined, // Skip hostname verification\r\n },\r\n });\r\n }\r\n }\r\n\r\n get session(): Session | null {\r\n return this.state.session;\r\n }\r\n\r\n // --- Private helpers ---\r\n\r\n private storeCookies(response: Response): void {\r\n const setCookieHeader = response.headers.get('set-cookie');\r\n if (!setCookieHeader) return;\r\n\r\n // Parse Set-Cookie header(s) - may be multiple cookies\r\n // Format: \"name=value; Path=/; HttpOnly\" or multiple separated\r\n const cookieStrings = setCookieHeader.split(/,(?=\\s*\\w+=)/);\r\n for (const cookieStr of cookieStrings) {\r\n const match = cookieStr.match(/^([^=]+)=([^;]*)/);\r\n if (match && match[1] && match[2]) {\r\n this.state.cookies.set(match[1].trim(), match[2].trim());\r\n }\r\n }\r\n }\r\n\r\n private buildCookieHeader(): string | null {\r\n if (this.state.cookies.size === 0) return null;\r\n return Array.from(this.state.cookies.entries())\r\n .map(([name, value]) => `${name}=${value}`)\r\n .join('; ');\r\n }\r\n\r\n // Core HTTP request function with CSRF token injection and automatic retry on 403 errors\r\n private async request(options: RequestOptions): AsyncResult<Response, Error> {\r\n const { method, path, params, headers: customHeaders, body } = options;\r\n const { config } = this.state;\r\n\r\n // Build headers with auth and CSRF token.\r\n debug(`Request ${method} ${path} - CSRF token in state: ${this.state.csrfToken?.substring(0, 20) || 'null'}...`);\r\n const headers = buildRequestHeaders(\r\n BASE_HEADERS,\r\n customHeaders,\r\n config.auth,\r\n this.state.csrfToken\r\n );\r\n debug(`CSRF header being sent: ${headers['x-csrf-token']?.substring(0, 20) || 'none'}...`);\r\n\r\n // Add stored cookies to request\r\n const cookieHeader = this.buildCookieHeader();\r\n if (cookieHeader) {\r\n headers['Cookie'] = cookieHeader;\r\n debug(`Cookies being sent: ${cookieHeader.substring(0, 50)}...`);\r\n }\r\n\r\n // Build URL with parameters.\r\n const urlParams = buildParams(params, config.client);\r\n const url = buildUrl(config.url, path, urlParams);\r\n\r\n // Build fetch options with timeout and optional insecure agent.\r\n const fetchOptions: RequestInit & { dispatcher?: Agent } = {\r\n method,\r\n headers,\r\n signal: AbortSignal.timeout(config.timeout ?? DEFAULT_TIMEOUT),\r\n };\r\n\r\n // Add insecure agent if configured\r\n if (this.agent) {\r\n fetchOptions.dispatcher = this.agent;\r\n }\r\n\r\n // Add request body if provided.\r\n if (body) {\r\n fetchOptions.body = body;\r\n }\r\n\r\n try {\r\n // Execute HTTP request.\r\n debug(`Fetching URL: ${url}`);\r\n debug(`Insecure mode: ${!!this.agent}`);\r\n // Use undici fetch directly to support dispatcher option for SSL bypass\r\n const response = await undiciFetch(url, fetchOptions as Parameters<typeof undiciFetch>[1]) as unknown as Response;\r\n\r\n // Store any cookies from response\r\n this.storeCookies(response);\r\n\r\n // Handle CSRF token validation failure with automatic refresh.\r\n if (response.status === 403) {\r\n const text = await response.text();\r\n if (text.includes('CSRF token validation failed')) {\r\n // Fetch new CSRF token.\r\n const [newToken, tokenErr] = await sessionOps.fetchCsrfToken(this.state, this.request.bind(this));\r\n if (tokenErr) {\r\n return err(new Error(`CSRF token refresh failed: ${tokenErr.message}`));\r\n }\r\n\r\n // Retry request with new token and cookies.\r\n headers[CSRF_TOKEN_HEADER] = newToken;\r\n const retryCookieHeader = this.buildCookieHeader();\r\n if (retryCookieHeader) {\r\n headers['Cookie'] = retryCookieHeader;\r\n }\r\n debug(`Retrying with new CSRF token: ${newToken.substring(0, 20)}...`);\r\n const retryResponse = await undiciFetch(url, { ...fetchOptions, headers } as Parameters<typeof undiciFetch>[1]) as unknown as Response;\r\n this.storeCookies(retryResponse);\r\n return ok(retryResponse);\r\n }\r\n\r\n // Return 403 response if not CSRF-related.\r\n return ok(new Response(text, {\r\n status: response.status,\r\n statusText: response.statusText,\r\n headers: response.headers,\r\n }));\r\n }\r\n\r\n // Handle session expiration with automatic reset.\r\n if (response.status === 500) {\r\n const text = await response.text();\r\n\r\n // Attempt session reset.\r\n const [, resetErr] = await sessionOps.sessionReset(this.state, this.request.bind(this));\r\n if (resetErr) {\r\n return err(new Error(`Session reset failed: ${resetErr.message}`));\r\n }\r\n\r\n // Return original 500 response.\r\n return ok(new Response(text, {\r\n status: response.status,\r\n statusText: response.statusText,\r\n headers: response.headers,\r\n }));\r\n }\r\n\r\n return ok(response);\r\n } catch (error) {\r\n // Log detailed error info for debugging\r\n if (error instanceof Error) {\r\n debugError(`Fetch error: ${error.name}: ${error.message}`, error.cause);\r\n if ('code' in error) {\r\n debugError(`Error code: ${(error as NodeJS.ErrnoException).code}`);\r\n }\r\n return err(error);\r\n }\r\n return err(new Error(`Network error: ${String(error)}`));\r\n }\r\n }\r\n\r\n // --- Lifecycle ---\r\n\r\n async login(): AsyncResult<Session> {\r\n return sessionOps.login(this.state, this.request.bind(this));\r\n }\r\n\r\n async logout(): AsyncResult<void> {\r\n return sessionOps.logout(this.state, this.request.bind(this));\r\n }\r\n\r\n // --- CRAUD Operations ---\r\n\r\n async read(objects: ObjectRef[]): AsyncResult<ObjectWithContent[]> {\r\n if (!this.state.session) return err(new Error('Not logged in'));\r\n\r\n const results: ObjectWithContent[] = [];\r\n for (const obj of objects) {\r\n const [result, readErr] = await adt.readObject(this.requestor, obj);\r\n if (readErr) return err(readErr);\r\n results.push(result);\r\n }\r\n return ok(results);\r\n }\r\n\r\n async create(object: ObjectContent, packageName: string, transport?: string): AsyncResult<void> {\r\n if (!this.state.session) return err(new Error('Not logged in'));\r\n\r\n // Step 1: Create empty object shell\r\n const [, createErr] = await adt.createObject(this.requestor, object, packageName, transport, this.state.session.username);\r\n if (createErr) return err(createErr);\r\n\r\n // Step 2: Populate content via lock → update → unlock\r\n const objRef: ObjectRef = { name: object.name, extension: object.extension };\r\n\r\n const [lockHandle, lockErr] = await adt.lockObject(this.requestor, objRef);\r\n if (lockErr) return err(lockErr);\r\n\r\n const [, updateErr] = await adt.updateObject(this.requestor, object, lockHandle, transport);\r\n\r\n // Always unlock after update attempt\r\n const [, unlockErr] = await adt.unlockObject(this.requestor, objRef, lockHandle);\r\n\r\n if (updateErr) return err(updateErr);\r\n if (unlockErr) return err(unlockErr);\r\n\r\n return ok(undefined);\r\n }\r\n\r\n async update(object: ObjectContent, transport?: string): AsyncResult<void> {\r\n if (!this.state.session) return err(new Error('Not logged in'));\r\n\r\n const objRef: ObjectRef = { name: object.name, extension: object.extension };\r\n\r\n // Lock object before update\r\n const [lockHandle, lockErr] = await adt.lockObject(this.requestor, objRef);\r\n if (lockErr) return err(lockErr);\r\n\r\n // Update object content\r\n const [, updateErr] = await adt.updateObject(this.requestor, object, lockHandle, transport);\r\n\r\n // Always unlock after update attempt\r\n const [, unlockErr] = await adt.unlockObject(this.requestor, objRef, lockHandle);\r\n\r\n // Return first error encountered\r\n if (updateErr) return err(updateErr);\r\n if (unlockErr) return err(unlockErr);\r\n\r\n return ok(undefined);\r\n }\r\n\r\n async upsert(objects: ObjectContent[], packageName: string, transport?: string): AsyncResult<UpsertResult[]> {\r\n if (!this.state.session) return err(new Error('Not logged in'));\r\n if (objects.length === 0) return ok([]);\r\n\r\n const results: UpsertResult[] = [];\r\n for (const obj of objects) {\r\n if (!obj.name || !obj.extension) continue;\r\n\r\n const objRef: ObjectRef = { name: obj.name, extension: obj.extension };\r\n\r\n // Try to read existing object\r\n const [existing] = await adt.readObject(this.requestor, objRef);\r\n\r\n // Object doesn't exist - create it\r\n if (!existing) {\r\n const [, createErr] = await this.create(obj, packageName, transport);\r\n if (createErr) return err(createErr);\r\n\r\n const result: UpsertResult = {\r\n name: obj.name,\r\n extension: obj.extension,\r\n status: 'created',\r\n };\r\n if (transport) result.transport = transport;\r\n results.push(result);\r\n continue;\r\n }\r\n\r\n // Object exists - update it\r\n const [, updateErr] = await this.update(obj, transport);\r\n if (updateErr) return err(updateErr);\r\n\r\n const result: UpsertResult = {\r\n name: obj.name,\r\n extension: obj.extension,\r\n status: 'updated',\r\n };\r\n if (transport) result.transport = transport;\r\n results.push(result);\r\n }\r\n return ok(results);\r\n }\r\n\r\n async activate(objects: ObjectRef[]): AsyncResult<ActivationResult[]> {\r\n if (!this.state.session) return err(new Error('Not logged in'));\r\n return adt.activateObjects(this.requestor, objects);\r\n }\r\n\r\n async delete(objects: ObjectRef[], transport?: string): AsyncResult<void> {\r\n if (!this.state.session) return err(new Error('Not logged in'));\r\n\r\n for (const obj of objects) {\r\n // Lock object before deletion\r\n const [lockHandle, lockErr] = await adt.lockObject(this.requestor, obj);\r\n if (lockErr) return err(lockErr);\r\n\r\n // Delete object\r\n const [, deleteErr] = await adt.deleteObject(this.requestor, obj, lockHandle, transport);\r\n if (deleteErr) {\r\n // Attempt to unlock on failure\r\n await adt.unlockObject(this.requestor, obj, lockHandle);\r\n return err(deleteErr);\r\n }\r\n }\r\n return ok(undefined);\r\n }\r\n\r\n // --- Discovery ---\r\n\r\n async getPackages(): AsyncResult<Package[]> {\r\n if (!this.state.session) return err(new Error('Not logged in'));\r\n return adt.getPackages(this.requestor);\r\n }\r\n\r\n async getTree(query: TreeQuery): AsyncResult<TreeNode[]> {\r\n if (!this.state.session) return err(new Error('Not logged in'));\r\n return adt.getTree(this.requestor, query);\r\n }\r\n\r\n async getTransports(packageName: string): AsyncResult<Transport[]> {\r\n if (!this.state.session) return err(new Error('Not logged in'));\r\n return adt.getTransports(this.requestor, packageName);\r\n }\r\n\r\n // --- Data Preview ---\r\n\r\n async previewData(query: PreviewQuery): AsyncResult<DataFrame> {\r\n if (!this.state.session) return err(new Error('Not logged in'));\r\n return adt.previewData(this.requestor, query);\r\n }\r\n\r\n async getDistinctValues(objectName: string, column: string, objectType: 'table' | 'view' = 'view'): AsyncResult<DistinctResult> {\r\n if (!this.state.session) return err(new Error('Not logged in'));\r\n return adt.getDistinctValues(this.requestor, objectName, column, objectType);\r\n }\r\n\r\n async countRows(objectName: string, objectType: 'table' | 'view'): AsyncResult<number> {\r\n if (!this.state.session) return err(new Error('Not logged in'));\r\n return adt.countRows(this.requestor, objectName, objectType);\r\n }\r\n\r\n // --- Search ---\r\n\r\n async search(query: string, types?: string[]): AsyncResult<SearchResult[]> {\r\n if (!this.state.session) return err(new Error('Not logged in'));\r\n return adt.searchObjects(this.requestor, query, types);\r\n }\r\n\r\n async whereUsed(object: ObjectRef): AsyncResult<Dependency[]> {\r\n if (!this.state.session) return err(new Error('Not logged in'));\r\n return adt.findWhereUsed(this.requestor, object);\r\n }\r\n\r\n // --- Transport Management ---\r\n\r\n async createTransport(transportConfig: TransportConfig): AsyncResult<string> {\r\n if (!this.state.session) return err(new Error('Not logged in'));\r\n return adt.createTransport(this.requestor, transportConfig);\r\n }\r\n\r\n // --- Diff Operations ---\r\n\r\n async gitDiff(objects: ObjectContent[]): AsyncResult<DiffResult[]> {\r\n if (!this.state.session) return err(new Error('Not logged in'));\r\n if (objects.length === 0) return ok([]);\r\n\r\n const results: DiffResult[] = [];\r\n for (const obj of objects) {\r\n const [result, diffErr] = await adt.gitDiff(this.requestor, obj);\r\n if (diffErr) return err(diffErr);\r\n results.push(result);\r\n }\r\n return ok(results);\r\n }\r\n\r\n // --- Configuration ---\r\n\r\n getObjectConfig(): ObjectConfig[] {\r\n return Object.values(adt.OBJECT_CONFIG_MAP);\r\n }\r\n}\r\n\r\n// Create a new ADT client - validates config and returns client instance\r\nexport function createClient(config: ClientConfig): Result<ADTClient, Error> {\r\n // Validate config using Zod schema.\r\n const validation = clientConfigSchema.safeParse(config);\r\n if (!validation.success) {\r\n const issues = validation.error.issues.map(i => `${i.path.join('.')}: ${i.message}`).join(', ');\r\n return err(new Error(`Invalid client configuration: ${issues}`));\r\n }\r\n\r\n return ok(new ADTClientImpl(config));\r\n}\r\n","/**\n * Configuration loading utilities\n *\n * Matches Python reference behavior:\n * - Load system URLs from config.json\n * - Parse clientId format: \"SystemId-ClientNumber\" (e.g., \"MediaDemo-DM1-200\")\n * - Support RELAY_CONFIG environment variable\n */\n\nimport { readFileSync } from 'node:fs';\nimport { z } from 'zod';\nimport type { Result } from '../types/result';\nimport { ok, err } from '../types/result';\n\n/**\n * System configuration from config.json\n */\nexport interface SystemConfig {\n /** ADT server URL */\n adt: string | undefined;\n /** OData server URL (optional) */\n odata: string | undefined;\n /** Instance number (optional) */\n instanceNum: string | undefined;\n}\n\n/**\n * Loaded configuration map\n * Key: System ID (e.g., \"MediaDemo-DM1\")\n * Value: System configuration\n */\nexport type ConfigMap = Map<string, SystemConfig>;\n\n/**\n * Zod schema for config.json validation\n */\nconst systemConfigSchema = z.record(\n z.string(),\n z.object({\n adt: z.string().url().optional(),\n odata: z.string().url().optional(),\n instance_num: z.string().optional(),\n })\n);\n\n/**\n * Parsed client ID components\n */\nexport interface ParsedClientId {\n /** System ID for config lookup (e.g., \"MediaDemo-DM1\") */\n systemId: string;\n /** SAP client number (e.g., \"200\") */\n clientNumber: string;\n}\n\n/**\n * Global config storage\n */\nlet globalConfig: ConfigMap | null = null;\n\n/**\n * Load configuration from a JSON file\n *\n * @param path - Path to config.json\n * @returns Result with ConfigMap or error\n *\n * @example\n * ```typescript\n * const [config, err] = loadConfig('./config.json');\n * if (err) {\n * console.error('Failed to load config:', err);\n * return;\n * }\n * ```\n */\nexport function loadConfig(path: string): Result<ConfigMap, Error> {\n try {\n // Read and parse the JSON file.\n const content = readFileSync(path, 'utf-8');\n const raw = JSON.parse(content);\n\n // Validate config structure with Zod schema.\n const validation = systemConfigSchema.safeParse(raw);\n if (!validation.success) {\n const issues = validation.error.issues\n .map((i) => `${i.path.join('.')}: ${i.message}`)\n .join(', ');\n return err(new Error(`Invalid config format: ${issues}`));\n }\n\n // Convert validated data to ConfigMap.\n const configMap: ConfigMap = new Map();\n for (const [key, value] of Object.entries(validation.data)) {\n configMap.set(key, {\n adt: value.adt,\n odata: value.odata,\n instanceNum: value.instance_num,\n });\n }\n\n // Store globally for later access.\n globalConfig = configMap;\n\n return ok(configMap);\n } catch (error) {\n // Handle JSON parsing errors.\n if (error instanceof SyntaxError) {\n return err(new Error(`Invalid JSON in config file: ${error.message}`));\n }\n // Handle file not found errors.\n if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {\n return err(new Error(`Config file not found: ${path}`));\n }\n return err(error instanceof Error ? error : new Error(String(error)));\n }\n}\n\n/**\n * Default config file path\n */\nconst DEFAULT_CONFIG_PATH = './config.json';\n\n/**\n * Load configuration from RELAY_CONFIG environment variable\n *\n * Defaults to './config.json' if RELAY_CONFIG is not set.\n *\n * @returns Result with ConfigMap or error\n *\n * @example\n * ```typescript\n * // Uses RELAY_CONFIG env var, or defaults to './config.json'\n * const [config, err] = loadConfigFromEnv();\n * ```\n */\n\nexport function loadConfigFromEnv(): Result<ConfigMap, Error> {\n // Resolve config path from environment or use default.\n const configPath = process.env['RELAY_CONFIG'] ?? DEFAULT_CONFIG_PATH;\n return loadConfig(configPath);\n}\n\n/**\n * Get the currently loaded config\n *\n * @returns ConfigMap or null if not loaded\n */\nexport function getConfig(): ConfigMap | null {\n return globalConfig;\n}\n\n/**\n * Get system config by ID\n *\n * @param systemId - System ID (e.g., \"MediaDemo-DM1\")\n * @returns SystemConfig or null if not found\n */\nexport function getSystemConfig(systemId: string): SystemConfig | null {\n if (!globalConfig) return null;\n return globalConfig.get(systemId) ?? null;\n}\n\n/**\n * Parse a client ID into system ID and client number\n *\n * Format: \"SystemId-ClientNumber\" where SystemId can contain hyphens\n * Example: \"MediaDemo-DM1-200\" → { systemId: \"MediaDemo-DM1\", clientNumber: \"200\" }\n *\n * @param clientId - Full client ID string\n * @returns Result with parsed components or error\n *\n * @example\n * ```typescript\n * const [parsed, err] = parseClientId('MediaDemo-DM1-200');\n * if (err) return;\n * console.log(parsed.systemId); // \"MediaDemo-DM1\"\n * console.log(parsed.clientNumber); // \"200\"\n * ```\n */\nexport function parseClientId(clientId: string): Result<ParsedClientId, Error> {\n if (!clientId) {\n return err(new Error('Client ID is required'));\n }\n\n // Split by hyphen to extract components.\n const parts = clientId.split('-');\n if (parts.length < 2) {\n return err(new Error(`Invalid client ID format: \"${clientId}\". Expected \"SystemId-ClientNumber\" (e.g., \"MediaDemo-DM1-200\")`));\n }\n\n // Extract client number (last part) and system ID (everything before).\n const clientNumber = parts[parts.length - 1];\n const systemId = parts.slice(0, -1).join('-');\n\n // Validate client number is numeric.\n if (!clientNumber || !/^\\d+$/.test(clientNumber)) {\n return err(new Error(`Invalid client number: \"${clientNumber}\". Must be numeric (e.g., \"100\", \"200\")`));\n }\n\n // Validate system ID is not empty.\n if (!systemId) {\n return err(new Error(`Invalid system ID in client ID: \"${clientId}\"`));\n }\n\n return ok({ systemId, clientNumber });\n}\n\n/**\n * Resolve a client ID to a full URL and client number\n *\n * @param clientId - Full client ID (e.g., \"MediaDemo-DM1-200\")\n * @returns Result with URL and client number or error\n *\n * @example\n * ```typescript\n * loadConfig('./config.json');\n * const [resolved, err] = resolveClientId('MediaDemo-DM1-200');\n * if (err) return;\n * console.log(resolved.url); // \"https://50.19.106.63:443\"\n * console.log(resolved.clientNumber); // \"200\"\n * ```\n */\nexport function resolveClientId(clientId: string): Result<{ url: string; clientNumber: string }, Error> {\n // Parse the client ID into components.\n const [parsed, parseErr] = parseClientId(clientId);\n if (parseErr) {\n return err(parseErr);\n }\n\n // Ensure config is loaded.\n if (!globalConfig) {\n return err(new Error('Config not loaded. Call loadConfig() or loadConfigFromEnv() first.'));\n }\n\n // Lookup system configuration.\n const systemConfig = globalConfig.get(parsed.systemId);\n if (!systemConfig) {\n return err(new Error(`Unknown system ID: \"${parsed.systemId}\". Available: ${Array.from(globalConfig.keys()).join(', ')}`));\n }\n\n // Validate ADT URL is configured.\n if (!systemConfig.adt) {\n return err(new Error(`No ADT URL configured for system: \"${parsed.systemId}\"`));\n }\n\n return ok({\n url: systemConfig.adt,\n clientNumber: parsed.clientNumber,\n });\n}\n\n/**\n * Build a ClientConfig from a client ID and auth config\n *\n * Convenience function that resolves the client ID and builds\n * a complete ClientConfig ready for createClient().\n *\n * @param clientId - Full client ID (e.g., \"MediaDemo-DM1-200\")\n * @param auth - Authentication configuration\n * @returns Result with ClientConfig or error\n *\n * @example\n * ```typescript\n * loadConfig('./config.json');\n *\n * const [config, err] = buildClientConfig('MediaDemo-DM1-200', {\n * type: 'basic',\n * username: 'user',\n * password: 'pass',\n * });\n * if (err) return;\n *\n * const [client, clientErr] = createClient(config);\n * ```\n */\nexport function buildClientConfig(\n clientId: string,\n auth: { type: 'basic'; username: string; password: string } |\n { type: 'saml'; username: string; password: string; provider?: string } |\n { type: 'sso'; certificate?: string }\n): Result<{ url: string; client: string; auth: typeof auth }, Error> {\n // Resolve client ID to URL and client number.\n const [resolved, resolveErr] = resolveClientId(clientId);\n if (resolveErr) {\n return err(resolveErr);\n }\n\n // Build complete client configuration.\n return ok({\n url: resolved.url,\n client: resolved.clientNumber,\n auth,\n });\n}\n"],"mappings":"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","names":["text","text","text","text","text","text","text","text","buildUrl","undiciFetch","result","import_zod"]}