arc-1 0.1.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.
Files changed (160) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +222 -0
  3. package/bin/arc1.js +12 -0
  4. package/dist/adt/btp.d.ts +122 -0
  5. package/dist/adt/btp.d.ts.map +1 -0
  6. package/dist/adt/btp.js +392 -0
  7. package/dist/adt/btp.js.map +1 -0
  8. package/dist/adt/client.d.ts +89 -0
  9. package/dist/adt/client.d.ts.map +1 -0
  10. package/dist/adt/client.js +208 -0
  11. package/dist/adt/client.js.map +1 -0
  12. package/dist/adt/codeintel.d.ts +38 -0
  13. package/dist/adt/codeintel.d.ts.map +1 -0
  14. package/dist/adt/codeintel.js +61 -0
  15. package/dist/adt/codeintel.js.map +1 -0
  16. package/dist/adt/config.d.ts +65 -0
  17. package/dist/adt/config.d.ts.map +1 -0
  18. package/dist/adt/config.js +35 -0
  19. package/dist/adt/config.js.map +1 -0
  20. package/dist/adt/cookies.d.ts +27 -0
  21. package/dist/adt/cookies.d.ts.map +1 -0
  22. package/dist/adt/cookies.js +67 -0
  23. package/dist/adt/cookies.js.map +1 -0
  24. package/dist/adt/crud.d.ts +35 -0
  25. package/dist/adt/crud.d.ts.map +1 -0
  26. package/dist/adt/crud.js +87 -0
  27. package/dist/adt/crud.js.map +1 -0
  28. package/dist/adt/devtools.d.ts +32 -0
  29. package/dist/adt/devtools.d.ts.map +1 -0
  30. package/dist/adt/devtools.js +154 -0
  31. package/dist/adt/devtools.js.map +1 -0
  32. package/dist/adt/errors.d.ts +49 -0
  33. package/dist/adt/errors.d.ts.map +1 -0
  34. package/dist/adt/errors.js +80 -0
  35. package/dist/adt/errors.js.map +1 -0
  36. package/dist/adt/features.d.ts +44 -0
  37. package/dist/adt/features.d.ts.map +1 -0
  38. package/dist/adt/features.js +173 -0
  39. package/dist/adt/features.js.map +1 -0
  40. package/dist/adt/http.d.ts +116 -0
  41. package/dist/adt/http.d.ts.map +1 -0
  42. package/dist/adt/http.js +374 -0
  43. package/dist/adt/http.js.map +1 -0
  44. package/dist/adt/safety.d.ts +70 -0
  45. package/dist/adt/safety.d.ts.map +1 -0
  46. package/dist/adt/safety.js +222 -0
  47. package/dist/adt/safety.js.map +1 -0
  48. package/dist/adt/transport.d.ts +18 -0
  49. package/dist/adt/transport.d.ts.map +1 -0
  50. package/dist/adt/transport.js +66 -0
  51. package/dist/adt/transport.js.map +1 -0
  52. package/dist/adt/types.d.ts +91 -0
  53. package/dist/adt/types.d.ts.map +1 -0
  54. package/dist/adt/types.js +9 -0
  55. package/dist/adt/types.js.map +1 -0
  56. package/dist/adt/xml-parser.d.ts +109 -0
  57. package/dist/adt/xml-parser.d.ts.map +1 -0
  58. package/dist/adt/xml-parser.js +283 -0
  59. package/dist/adt/xml-parser.js.map +1 -0
  60. package/dist/cache/cache.d.ts +61 -0
  61. package/dist/cache/cache.d.ts.map +1 -0
  62. package/dist/cache/cache.js +14 -0
  63. package/dist/cache/cache.js.map +1 -0
  64. package/dist/cache/memory.d.ts +25 -0
  65. package/dist/cache/memory.d.ts.map +1 -0
  66. package/dist/cache/memory.js +69 -0
  67. package/dist/cache/memory.js.map +1 -0
  68. package/dist/cache/sqlite.d.ts +26 -0
  69. package/dist/cache/sqlite.d.ts.map +1 -0
  70. package/dist/cache/sqlite.js +130 -0
  71. package/dist/cache/sqlite.js.map +1 -0
  72. package/dist/cli.d.ts +14 -0
  73. package/dist/cli.d.ts.map +1 -0
  74. package/dist/cli.js +101 -0
  75. package/dist/cli.js.map +1 -0
  76. package/dist/context/compressor.d.ts +33 -0
  77. package/dist/context/compressor.d.ts.map +1 -0
  78. package/dist/context/compressor.js +208 -0
  79. package/dist/context/compressor.js.map +1 -0
  80. package/dist/context/contract.d.ts +14 -0
  81. package/dist/context/contract.d.ts.map +1 -0
  82. package/dist/context/contract.js +202 -0
  83. package/dist/context/contract.js.map +1 -0
  84. package/dist/context/deps.d.ts +32 -0
  85. package/dist/context/deps.d.ts.map +1 -0
  86. package/dist/context/deps.js +240 -0
  87. package/dist/context/deps.js.map +1 -0
  88. package/dist/context/types.d.ts +56 -0
  89. package/dist/context/types.d.ts.map +1 -0
  90. package/dist/context/types.js +10 -0
  91. package/dist/context/types.js.map +1 -0
  92. package/dist/handlers/intent.d.ts +46 -0
  93. package/dist/handlers/intent.d.ts.map +1 -0
  94. package/dist/handlers/intent.js +539 -0
  95. package/dist/handlers/intent.js.map +1 -0
  96. package/dist/handlers/tools.d.ts +21 -0
  97. package/dist/handlers/tools.d.ts.map +1 -0
  98. package/dist/handlers/tools.js +260 -0
  99. package/dist/handlers/tools.js.map +1 -0
  100. package/dist/index.d.ts +10 -0
  101. package/dist/index.d.ts.map +1 -0
  102. package/dist/index.js +16 -0
  103. package/dist/index.js.map +1 -0
  104. package/dist/lint/lint.d.ts +35 -0
  105. package/dist/lint/lint.d.ts.map +1 -0
  106. package/dist/lint/lint.js +67 -0
  107. package/dist/lint/lint.js.map +1 -0
  108. package/dist/server/audit.d.ts +96 -0
  109. package/dist/server/audit.d.ts.map +1 -0
  110. package/dist/server/audit.js +27 -0
  111. package/dist/server/audit.js.map +1 -0
  112. package/dist/server/config.d.ts +19 -0
  113. package/dist/server/config.d.ts.map +1 -0
  114. package/dist/server/config.js +101 -0
  115. package/dist/server/config.js.map +1 -0
  116. package/dist/server/context.d.ts +20 -0
  117. package/dist/server/context.d.ts.map +1 -0
  118. package/dist/server/context.js +20 -0
  119. package/dist/server/context.js.map +1 -0
  120. package/dist/server/elicit.d.ts +43 -0
  121. package/dist/server/elicit.d.ts.map +1 -0
  122. package/dist/server/elicit.js +183 -0
  123. package/dist/server/elicit.js.map +1 -0
  124. package/dist/server/http.d.ts +34 -0
  125. package/dist/server/http.d.ts.map +1 -0
  126. package/dist/server/http.js +328 -0
  127. package/dist/server/http.js.map +1 -0
  128. package/dist/server/logger.d.ts +57 -0
  129. package/dist/server/logger.d.ts.map +1 -0
  130. package/dist/server/logger.js +129 -0
  131. package/dist/server/logger.js.map +1 -0
  132. package/dist/server/server.d.ts +25 -0
  133. package/dist/server/server.d.ts.map +1 -0
  134. package/dist/server/server.js +307 -0
  135. package/dist/server/server.js.map +1 -0
  136. package/dist/server/sinks/btp-auditlog.d.ts +48 -0
  137. package/dist/server/sinks/btp-auditlog.d.ts.map +1 -0
  138. package/dist/server/sinks/btp-auditlog.js +232 -0
  139. package/dist/server/sinks/btp-auditlog.js.map +1 -0
  140. package/dist/server/sinks/file.d.ts +22 -0
  141. package/dist/server/sinks/file.d.ts.map +1 -0
  142. package/dist/server/sinks/file.js +59 -0
  143. package/dist/server/sinks/file.js.map +1 -0
  144. package/dist/server/sinks/stderr.d.ts +19 -0
  145. package/dist/server/sinks/stderr.d.ts.map +1 -0
  146. package/dist/server/sinks/stderr.js +63 -0
  147. package/dist/server/sinks/stderr.js.map +1 -0
  148. package/dist/server/sinks/types.d.ts +14 -0
  149. package/dist/server/sinks/types.d.ts.map +1 -0
  150. package/dist/server/sinks/types.js +8 -0
  151. package/dist/server/sinks/types.js.map +1 -0
  152. package/dist/server/types.d.ts +54 -0
  153. package/dist/server/types.d.ts.map +1 -0
  154. package/dist/server/types.js +42 -0
  155. package/dist/server/types.js.map +1 -0
  156. package/dist/server/xsuaa.d.ts +77 -0
  157. package/dist/server/xsuaa.d.ts.map +1 -0
  158. package/dist/server/xsuaa.js +364 -0
  159. package/dist/server/xsuaa.js.map +1 -0
  160. package/package.json +66 -0
@@ -0,0 +1,283 @@
1
+ /**
2
+ * XML parser for SAP ADT responses.
3
+ *
4
+ * SAP ADT returns XML with multiple namespace conventions:
5
+ * - adtcore: (http://www.sap.com/adt/core) — object references, search results
6
+ * - asx: (http://www.sap.com/abapxml) — table contents, package structure
7
+ * - atom: (http://www.w3.org/2005/Atom) — feed entries
8
+ *
9
+ * We use fast-xml-parser v5 with removeNSPrefix to strip namespaces,
10
+ * since we know the expected structure and don't need namespace dispatch.
11
+ *
12
+ * Key design choice: parse to plain objects, then map to our types.
13
+ * This decouples the XML format from our internal types, making it
14
+ * easier to handle SAP's inconsistent XML across different endpoints.
15
+ */
16
+ import { XMLParser } from 'fast-xml-parser';
17
+ /** Shared parser instance — configured for ADT XML conventions */
18
+ const parser = new XMLParser({
19
+ ignoreAttributes: false,
20
+ attributeNamePrefix: '@_',
21
+ removeNSPrefix: true, // Strip adtcore:, asx:, etc.
22
+ isArray: (name) => {
23
+ // These elements can appear 0-N times; force array even for single item
24
+ return [
25
+ 'objectReference',
26
+ 'entry',
27
+ 'link',
28
+ 'objectStructure',
29
+ 'field',
30
+ 'functionModule',
31
+ 'COLUMN',
32
+ 'columns',
33
+ 'DATA',
34
+ 'data',
35
+ 'SEU_ADT_REPOSITORY_OBJ_NODE',
36
+ 'component',
37
+ 'objectStructureElement',
38
+ 'task',
39
+ ].includes(name);
40
+ },
41
+ parseAttributeValue: false, // Keep attributes as strings
42
+ parseTagValue: false, // Keep tag values as strings (prevents "001" → 1)
43
+ });
44
+ /** Parse raw XML string to a JS object */
45
+ export function parseXml(xml) {
46
+ return parser.parse(xml);
47
+ }
48
+ /**
49
+ * Parse ADT search results XML.
50
+ *
51
+ * Expected format:
52
+ * <adtcore:objectReferences>
53
+ * <adtcore:objectReference uri="..." type="PROG/P" name="ZTEST" packageName="$TMP" description="..."/>
54
+ * </adtcore:objectReferences>
55
+ */
56
+ export function parseSearchResults(xml) {
57
+ const parsed = parseXml(xml);
58
+ const refs = getNestedArray(parsed, 'objectReferences', 'objectReference');
59
+ return refs.map((ref) => ({
60
+ objectType: String(ref['@_type'] ?? ''),
61
+ objectName: String(ref['@_name'] ?? ''),
62
+ description: String(ref['@_description'] ?? ''),
63
+ packageName: String(ref['@_packageName'] ?? ''),
64
+ uri: String(ref['@_uri'] ?? ''),
65
+ }));
66
+ }
67
+ /**
68
+ * Parse ADT package contents (nodestructure response).
69
+ *
70
+ * Expected format:
71
+ * <asx:abap><asx:values><DATA><TREE_CONTENT>
72
+ * <SEU_ADT_REPOSITORY_OBJ_NODE>
73
+ * <OBJECT_TYPE>PROG/P</OBJECT_TYPE>
74
+ * <OBJECT_NAME>ZTEST</OBJECT_NAME>
75
+ * <DESCRIPTION>...</DESCRIPTION>
76
+ * </SEU_ADT_REPOSITORY_OBJ_NODE>
77
+ * </TREE_CONTENT></DATA></asx:values></asx:abap>
78
+ */
79
+ export function parsePackageContents(xml) {
80
+ const parsed = parseXml(xml);
81
+ // After namespace stripping, asx:abap → abap, asx:values → values
82
+ // fast-xml-parser structure depends on XML depth — use recursive finder as fallback
83
+ let nodes = getDeepArray(parsed, ['abap', 'values', 'DATA', 'TREE_CONTENT', 'SEU_ADT_REPOSITORY_OBJ_NODE']);
84
+ if (nodes.length === 0) {
85
+ nodes = findDeepNodes(parsed, 'SEU_ADT_REPOSITORY_OBJ_NODE');
86
+ }
87
+ return nodes.map((node) => ({
88
+ type: String(node.OBJECT_TYPE ?? ''),
89
+ name: String(node.OBJECT_NAME ?? ''),
90
+ description: String(node.DESCRIPTION ?? ''),
91
+ uri: String(node.OBJECT_URI ?? ''),
92
+ }));
93
+ }
94
+ /**
95
+ * Parse table contents (datapreview response).
96
+ *
97
+ * SAP ADT returns two possible formats for data preview:
98
+ *
99
+ * Format 1 (older/asx): COLUMNS/COLUMN/METADATA + DATASET/DATA
100
+ * Format 2 (newer/dataPreview namespace): columns/metadata + dataSet/data
101
+ *
102
+ * After namespace stripping, both converge but with different casing.
103
+ * We try both patterns with fallback.
104
+ */
105
+ export function parseTableContents(xml) {
106
+ const parsed = parseXml(xml);
107
+ // Try old format first: abap > values > COLUMNS > COLUMN
108
+ let columns = getDeepArray(parsed, ['abap', 'values', 'COLUMNS', 'COLUMN']);
109
+ if (columns.length === 0) {
110
+ columns = findDeepNodes(parsed, 'COLUMN');
111
+ }
112
+ // New format: dataPreview:columns → "columns" after NS strip
113
+ // Each "columns" element contains "metadata" and "dataSet"
114
+ if (columns.length === 0) {
115
+ columns = findDeepNodes(parsed, 'columns');
116
+ }
117
+ const colNames = [];
118
+ const colData = [];
119
+ for (const col of columns) {
120
+ // Old format: METADATA/@_name, DATASET/DATA
121
+ // New format: metadata/@_name, dataSet/data
122
+ const metadata = (col.METADATA ?? col.metadata);
123
+ const name = String(metadata?.['@_name'] ?? metadata?.['@_dataPreview:name'] ?? '');
124
+ if (!name)
125
+ continue; // skip non-column entries like totalRows, name, etc.
126
+ colNames.push(name);
127
+ const dataset = (col.DATASET ?? col.dataSet);
128
+ const rawData = dataset?.DATA ?? dataset?.data;
129
+ const data = Array.isArray(rawData) ? rawData.map(String) : rawData != null ? [String(rawData)] : [];
130
+ colData.push(data);
131
+ }
132
+ // Pivot column-oriented to row-oriented
133
+ const rowCount = colData.length > 0 ? colData[0]?.length : 0;
134
+ const rows = [];
135
+ for (let i = 0; i < rowCount; i++) {
136
+ const row = {};
137
+ for (let j = 0; j < colNames.length; j++) {
138
+ row[colNames[j]] = colData[j]?.[i] ?? '';
139
+ }
140
+ rows.push(row);
141
+ }
142
+ return { columns: colNames, rows };
143
+ }
144
+ /**
145
+ * Parse installed components response.
146
+ *
147
+ * SAP returns an Atom feed for /sap/bc/adt/system/components:
148
+ * <atom:feed>
149
+ * <atom:entry>
150
+ * <atom:id>SAP_BASIS</atom:id>
151
+ * <atom:title>753;SAPKB75308;0008;SAP Basis Component</atom:title>
152
+ * </atom:entry>
153
+ * </atom:feed>
154
+ *
155
+ * The title field is semicolon-separated: release;sp_name;sp_level;description
156
+ */
157
+ export function parseInstalledComponents(xml) {
158
+ const parsed = parseXml(xml);
159
+ // After removeNSPrefix: atom:feed → feed, atom:entry → entry
160
+ const entries = getNestedArray(parsed, 'feed', 'entry');
161
+ return entries.map((entry) => {
162
+ const name = String(entry.id ?? '');
163
+ const title = String(entry.title ?? '');
164
+ // Title format: "release;sp_name;sp_level;description"
165
+ const parts = title.split(';');
166
+ return {
167
+ name,
168
+ release: parts[0]?.trim() ?? '',
169
+ description: parts[3]?.trim() ?? title,
170
+ };
171
+ });
172
+ }
173
+ /**
174
+ * Parse function group structure.
175
+ *
176
+ * <group name="ZGROUP" type="FUGR/F">
177
+ * <functionModule name="ZFUNC" type="FUNC/FM"/>
178
+ * </group>
179
+ */
180
+ export function parseFunctionGroup(xml) {
181
+ const parsed = parseXml(xml);
182
+ const group = (parsed.group ?? {});
183
+ const fmods = Array.isArray(group.functionModule) ? group.functionModule : [];
184
+ return {
185
+ name: String(group['@_name'] ?? ''),
186
+ functions: fmods.map((fm) => String(fm['@_name'] ?? '')),
187
+ };
188
+ }
189
+ /**
190
+ * Parse ADT system discovery XML into structured info.
191
+ *
192
+ * The discovery response is an Atom service document that lists available
193
+ * ADT workspaces/collections. We extract collection titles and hrefs
194
+ * to determine what capabilities the SAP system has.
195
+ *
196
+ * The authenticated username is passed in from the client config since
197
+ * the discovery XML doesn't directly contain "you are logged in as X".
198
+ */
199
+ export function parseSystemInfo(xml, username) {
200
+ const parsed = parseXml(xml);
201
+ // Atom service document: service > workspace > collection
202
+ const collections = [];
203
+ // After namespace stripping: app:service → service, app:workspace → workspace, app:collection → collection
204
+ const service = (parsed.service ?? parsed['service'] ?? {});
205
+ const workspaces = Array.isArray(service.workspace)
206
+ ? service.workspace
207
+ : service.workspace
208
+ ? [service.workspace]
209
+ : [];
210
+ for (const ws of workspaces) {
211
+ const cols = Array.isArray(ws.collection) ? ws.collection : ws.collection ? [ws.collection] : [];
212
+ for (const col of cols) {
213
+ const title = String(col.title ?? col['@_title'] ?? '');
214
+ const href = String(col['@_href'] ?? '');
215
+ if (title || href) {
216
+ collections.push({ title, href });
217
+ }
218
+ }
219
+ }
220
+ return { user: username ?? '', collections };
221
+ }
222
+ // ─── Helpers ────────────────────────────────────────────────────────
223
+ /** Safely get a nested array from parsed XML */
224
+ function getNestedArray(obj, parent, child) {
225
+ const parentObj = obj[parent];
226
+ if (!parentObj)
227
+ return [];
228
+ const arr = parentObj[child];
229
+ if (Array.isArray(arr))
230
+ return arr;
231
+ if (arr && typeof arr === 'object')
232
+ return [arr];
233
+ return [];
234
+ }
235
+ /** Recursively find an array by key name, anywhere in the object tree */
236
+ export function findDeepNodes(obj, key) {
237
+ if (!obj || typeof obj !== 'object')
238
+ return [];
239
+ if (Array.isArray(obj)) {
240
+ for (const item of obj) {
241
+ const found = findDeepNodes(item, key);
242
+ if (found.length > 0)
243
+ return found;
244
+ }
245
+ return [];
246
+ }
247
+ const record = obj;
248
+ if (key in record) {
249
+ const val = record[key];
250
+ if (Array.isArray(val))
251
+ return val;
252
+ if (val && typeof val === 'object')
253
+ return [val];
254
+ }
255
+ for (const val of Object.values(record)) {
256
+ const found = findDeepNodes(val, key);
257
+ if (found.length > 0)
258
+ return found;
259
+ }
260
+ return [];
261
+ }
262
+ /** Safely traverse a deep path and return an array at the end */
263
+ function getDeepArray(obj, path) {
264
+ let current = obj;
265
+ for (const key of path.slice(0, -1)) {
266
+ if (current && typeof current === 'object' && !Array.isArray(current)) {
267
+ current = current[key];
268
+ }
269
+ else {
270
+ return [];
271
+ }
272
+ }
273
+ const lastKey = path[path.length - 1];
274
+ if (current && typeof current === 'object' && !Array.isArray(current)) {
275
+ const arr = current[lastKey];
276
+ if (Array.isArray(arr))
277
+ return arr;
278
+ if (arr && typeof arr === 'object')
279
+ return [arr];
280
+ }
281
+ return [];
282
+ }
283
+ //# sourceMappingURL=xml-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xml-parser.js","sourceRoot":"","sources":["../../ts-src/adt/xml-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Cache interface and types for ARC-1.
3
+ *
4
+ * Two implementations:
5
+ * - MemoryCache: fast, ephemeral (default)
6
+ * - SqliteCache: persistent, cross-session (optional)
7
+ *
8
+ * Cache stores three types of data:
9
+ * - Nodes: ABAP objects (class, program, table, etc.)
10
+ * - Edges: Dependencies between objects (calls, uses, implements)
11
+ * - APIs: Released API objects (for clean core checks)
12
+ */
13
+ /** Cached ABAP object */
14
+ export interface CacheNode {
15
+ id: string;
16
+ objectType: string;
17
+ objectName: string;
18
+ packageName: string;
19
+ sourceHash?: string;
20
+ cachedAt: string;
21
+ valid: boolean;
22
+ metadata?: Record<string, unknown>;
23
+ }
24
+ /** Dependency edge between objects */
25
+ export interface CacheEdge {
26
+ fromId: string;
27
+ toId: string;
28
+ edgeType: 'CALLS' | 'USES' | 'IMPLEMENTS' | 'INCLUDES';
29
+ source?: string;
30
+ discoveredAt: string;
31
+ valid: boolean;
32
+ }
33
+ /** Released API object */
34
+ export interface CacheApi {
35
+ name: string;
36
+ type: string;
37
+ releaseState: string;
38
+ cleanCoreLevel?: string;
39
+ applicationComponent?: string;
40
+ }
41
+ /** Cache statistics */
42
+ export interface CacheStats {
43
+ nodeCount: number;
44
+ edgeCount: number;
45
+ apiCount: number;
46
+ }
47
+ /** Cache interface — both MemoryCache and SqliteCache implement this */
48
+ export interface Cache {
49
+ putNode(node: CacheNode): void;
50
+ getNode(id: string): CacheNode | null;
51
+ getNodesByPackage(packageName: string): CacheNode[];
52
+ invalidateNode(id: string): void;
53
+ putEdge(edge: CacheEdge): void;
54
+ getEdgesFrom(fromId: string): CacheEdge[];
55
+ putApi(api: CacheApi): void;
56
+ getApi(name: string, type: string): CacheApi | null;
57
+ clear(): void;
58
+ stats(): CacheStats;
59
+ close(): void;
60
+ }
61
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../ts-src/cache/cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,yBAAyB;AACzB,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,sCAAsC;AACtC,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,YAAY,GAAG,UAAU,CAAC;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,0BAA0B;AAC1B,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,uBAAuB;AACvB,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wEAAwE;AACxE,MAAM,WAAW,KAAK;IAEpB,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IAC/B,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IACtC,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,CAAC;IACpD,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAGjC,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IAC/B,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,CAAC;IAG1C,MAAM,CAAC,GAAG,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC5B,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAAC;IAGpD,KAAK,IAAI,IAAI,CAAC;IACd,KAAK,IAAI,UAAU,CAAC;IACpB,KAAK,IAAI,IAAI,CAAC;CACf"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Cache interface and types for ARC-1.
3
+ *
4
+ * Two implementations:
5
+ * - MemoryCache: fast, ephemeral (default)
6
+ * - SqliteCache: persistent, cross-session (optional)
7
+ *
8
+ * Cache stores three types of data:
9
+ * - Nodes: ABAP objects (class, program, table, etc.)
10
+ * - Edges: Dependencies between objects (calls, uses, implements)
11
+ * - APIs: Released API objects (for clean core checks)
12
+ */
13
+ export {};
14
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../ts-src/cache/cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * In-memory cache implementation.
3
+ *
4
+ * Default cache backend — fast, ephemeral.
5
+ * Data is lost when the process exits.
6
+ * Thread-safe by default in Node.js (single-threaded event loop).
7
+ */
8
+ import type { Cache, CacheApi, CacheEdge, CacheNode, CacheStats } from './cache.js';
9
+ export declare class MemoryCache implements Cache {
10
+ private nodes;
11
+ private edges;
12
+ private apis;
13
+ putNode(node: CacheNode): void;
14
+ getNode(id: string): CacheNode | null;
15
+ getNodesByPackage(packageName: string): CacheNode[];
16
+ invalidateNode(id: string): void;
17
+ putEdge(edge: CacheEdge): void;
18
+ getEdgesFrom(fromId: string): CacheEdge[];
19
+ putApi(api: CacheApi): void;
20
+ getApi(name: string, type: string): CacheApi | null;
21
+ clear(): void;
22
+ stats(): CacheStats;
23
+ close(): void;
24
+ }
25
+ //# sourceMappingURL=memory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../ts-src/cache/memory.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEpF,qBAAa,WAAY,YAAW,KAAK;IACvC,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,KAAK,CAAkC;IAC/C,OAAO,CAAC,IAAI,CAA+B;IAE3C,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAI9B,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAIrC,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE;IAWnD,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAOhC,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAO9B,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE;IAIzC,MAAM,CAAC,GAAG,EAAE,QAAQ,GAAG,IAAI;IAI3B,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;IAInD,KAAK,IAAI,IAAI;IAMb,KAAK,IAAI,UAAU;IAYnB,KAAK,IAAI,IAAI;CAGd"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * In-memory cache implementation.
3
+ *
4
+ * Default cache backend — fast, ephemeral.
5
+ * Data is lost when the process exits.
6
+ * Thread-safe by default in Node.js (single-threaded event loop).
7
+ */
8
+ export class MemoryCache {
9
+ nodes = new Map();
10
+ edges = new Map();
11
+ apis = new Map();
12
+ putNode(node) {
13
+ this.nodes.set(node.id, { ...node });
14
+ }
15
+ getNode(id) {
16
+ return this.nodes.get(id) ?? null;
17
+ }
18
+ getNodesByPackage(packageName) {
19
+ const upper = packageName.toUpperCase();
20
+ const result = [];
21
+ for (const node of this.nodes.values()) {
22
+ if (node.packageName.toUpperCase() === upper) {
23
+ result.push(node);
24
+ }
25
+ }
26
+ return result;
27
+ }
28
+ invalidateNode(id) {
29
+ const node = this.nodes.get(id);
30
+ if (node) {
31
+ node.valid = false;
32
+ }
33
+ }
34
+ putEdge(edge) {
35
+ const key = edge.fromId;
36
+ const existing = this.edges.get(key) ?? [];
37
+ existing.push({ ...edge });
38
+ this.edges.set(key, existing);
39
+ }
40
+ getEdgesFrom(fromId) {
41
+ return this.edges.get(fromId) ?? [];
42
+ }
43
+ putApi(api) {
44
+ this.apis.set(`${api.type}:${api.name}`, { ...api });
45
+ }
46
+ getApi(name, type) {
47
+ return this.apis.get(`${type}:${name}`) ?? null;
48
+ }
49
+ clear() {
50
+ this.nodes.clear();
51
+ this.edges.clear();
52
+ this.apis.clear();
53
+ }
54
+ stats() {
55
+ let edgeCount = 0;
56
+ for (const edges of this.edges.values()) {
57
+ edgeCount += edges.length;
58
+ }
59
+ return {
60
+ nodeCount: this.nodes.size,
61
+ edgeCount,
62
+ apiCount: this.apis.size,
63
+ };
64
+ }
65
+ close() {
66
+ this.clear();
67
+ }
68
+ }
69
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../ts-src/cache/memory.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,OAAO,WAAW;IACd,KAAK,GAAG,IAAI,GAAG,EAAqB,CAAC;IACrC,KAAK,GAAG,IAAI,GAAG,EAAuB,CAAC;IACvC,IAAI,GAAG,IAAI,GAAG,EAAoB,CAAC;IAE3C,OAAO,CAAC,IAAe;QACrB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,CAAC,EAAU;QAChB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC;IACpC,CAAC;IAED,iBAAiB,CAAC,WAAmB;QACnC,MAAM,KAAK,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC;QACxC,MAAM,MAAM,GAAgB,EAAE,CAAC;QAC/B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YACvC,IAAI,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,KAAK,KAAK,EAAE,CAAC;gBAC7C,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpB,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,cAAc,CAAC,EAAU;QACvB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChC,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACrB,CAAC;IACH,CAAC;IAED,OAAO,CAAC,IAAe;QACrB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;QACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAC3C,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;QAC3B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAChC,CAAC;IAED,YAAY,CAAC,MAAc;QACzB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IACtC,CAAC;IAED,MAAM,CAAC,GAAa;QAClB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,CAAC,IAAY,EAAE,IAAY;QAC/B,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC,IAAI,IAAI,CAAC;IAClD,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;IACpB,CAAC;IAED,KAAK;QACH,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YACxC,SAAS,IAAI,KAAK,CAAC,MAAM,CAAC;QAC5B,CAAC;QACD,OAAO;YACL,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI;YAC1B,SAAS;YACT,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI;SACzB,CAAC;IACJ,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,EAAE,CAAC;IACf,CAAC;CACF"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * SQLite cache implementation using better-sqlite3.
3
+ *
4
+ * Persistent cache — survives process restarts.
5
+ * Uses WAL mode for concurrent read performance.
6
+ * better-sqlite3 is synchronous, which is actually faster than async
7
+ * alternatives for single-process use (no Promise overhead).
8
+ */
9
+ import type { Cache, CacheApi, CacheEdge, CacheNode, CacheStats } from './cache.js';
10
+ export declare class SqliteCache implements Cache {
11
+ private db;
12
+ constructor(dbPath: string);
13
+ private createTables;
14
+ putNode(node: CacheNode): void;
15
+ getNode(id: string): CacheNode | null;
16
+ getNodesByPackage(packageName: string): CacheNode[];
17
+ invalidateNode(id: string): void;
18
+ putEdge(edge: CacheEdge): void;
19
+ getEdgesFrom(fromId: string): CacheEdge[];
20
+ putApi(api: CacheApi): void;
21
+ getApi(name: string, type: string): CacheApi | null;
22
+ clear(): void;
23
+ stats(): CacheStats;
24
+ close(): void;
25
+ }
26
+ //# sourceMappingURL=sqlite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../ts-src/cache/sqlite.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEpF,qBAAa,WAAY,YAAW,KAAK;IACvC,OAAO,CAAC,EAAE,CAAoB;gBAElB,MAAM,EAAE,MAAM;IAO1B,OAAO,CAAC,YAAY;IAqCpB,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAgB9B,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAMrC,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE;IAOnD,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAIhC,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAO9B,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE;IAKzC,MAAM,CAAC,GAAG,EAAE,QAAQ,GAAG,IAAI;IAO3B,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;IAcnD,KAAK,IAAI,IAAI;IAIb,KAAK,IAAI,UAAU;IAOnB,KAAK,IAAI,IAAI;CAGd"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * SQLite cache implementation using better-sqlite3.
3
+ *
4
+ * Persistent cache — survives process restarts.
5
+ * Uses WAL mode for concurrent read performance.
6
+ * better-sqlite3 is synchronous, which is actually faster than async
7
+ * alternatives for single-process use (no Promise overhead).
8
+ */
9
+ import Database from 'better-sqlite3';
10
+ export class SqliteCache {
11
+ db;
12
+ constructor(dbPath) {
13
+ this.db = new Database(dbPath);
14
+ this.db.pragma('journal_mode = WAL');
15
+ this.db.pragma('synchronous = NORMAL');
16
+ this.createTables();
17
+ }
18
+ createTables() {
19
+ this.db.exec(`
20
+ CREATE TABLE IF NOT EXISTS nodes (
21
+ id TEXT PRIMARY KEY,
22
+ object_type TEXT NOT NULL,
23
+ object_name TEXT NOT NULL,
24
+ package_name TEXT NOT NULL,
25
+ source_hash TEXT,
26
+ cached_at TEXT NOT NULL,
27
+ valid INTEGER NOT NULL DEFAULT 1,
28
+ metadata TEXT
29
+ );
30
+
31
+ CREATE TABLE IF NOT EXISTS edges (
32
+ from_id TEXT NOT NULL,
33
+ to_id TEXT NOT NULL,
34
+ edge_type TEXT NOT NULL,
35
+ source TEXT,
36
+ discovered_at TEXT NOT NULL,
37
+ valid INTEGER NOT NULL DEFAULT 1,
38
+ PRIMARY KEY (from_id, to_id, edge_type)
39
+ );
40
+
41
+ CREATE TABLE IF NOT EXISTS apis (
42
+ name TEXT NOT NULL,
43
+ type TEXT NOT NULL,
44
+ release_state TEXT NOT NULL,
45
+ clean_core_level TEXT,
46
+ application_component TEXT,
47
+ PRIMARY KEY (type, name)
48
+ );
49
+
50
+ CREATE INDEX IF NOT EXISTS idx_nodes_package ON nodes(package_name);
51
+ CREATE INDEX IF NOT EXISTS idx_edges_from ON edges(from_id);
52
+ `);
53
+ }
54
+ putNode(node) {
55
+ const stmt = this.db.prepare('INSERT OR REPLACE INTO nodes (id, object_type, object_name, package_name, source_hash, cached_at, valid, metadata) VALUES (?, ?, ?, ?, ?, ?, ?, ?)');
56
+ stmt.run(node.id, node.objectType, node.objectName, node.packageName, node.sourceHash ?? null, node.cachedAt, node.valid ? 1 : 0, node.metadata ? JSON.stringify(node.metadata) : null);
57
+ }
58
+ getNode(id) {
59
+ const row = this.db.prepare('SELECT * FROM nodes WHERE id = ?').get(id);
60
+ if (!row)
61
+ return null;
62
+ return rowToNode(row);
63
+ }
64
+ getNodesByPackage(packageName) {
65
+ const rows = this.db.prepare('SELECT * FROM nodes WHERE UPPER(package_name) = UPPER(?)').all(packageName);
66
+ return rows.map(rowToNode);
67
+ }
68
+ invalidateNode(id) {
69
+ this.db.prepare('UPDATE nodes SET valid = 0 WHERE id = ?').run(id);
70
+ }
71
+ putEdge(edge) {
72
+ const stmt = this.db.prepare('INSERT OR REPLACE INTO edges (from_id, to_id, edge_type, source, discovered_at, valid) VALUES (?, ?, ?, ?, ?, ?)');
73
+ stmt.run(edge.fromId, edge.toId, edge.edgeType, edge.source ?? null, edge.discoveredAt, edge.valid ? 1 : 0);
74
+ }
75
+ getEdgesFrom(fromId) {
76
+ const rows = this.db.prepare('SELECT * FROM edges WHERE from_id = ?').all(fromId);
77
+ return rows.map(rowToEdge);
78
+ }
79
+ putApi(api) {
80
+ const stmt = this.db.prepare('INSERT OR REPLACE INTO apis (name, type, release_state, clean_core_level, application_component) VALUES (?, ?, ?, ?, ?)');
81
+ stmt.run(api.name, api.type, api.releaseState, api.cleanCoreLevel ?? null, api.applicationComponent ?? null);
82
+ }
83
+ getApi(name, type) {
84
+ const row = this.db.prepare('SELECT * FROM apis WHERE type = ? AND name = ?').get(type, name);
85
+ if (!row)
86
+ return null;
87
+ return {
88
+ name: String(row.name),
89
+ type: String(row.type),
90
+ releaseState: String(row.release_state),
91
+ cleanCoreLevel: row.clean_core_level,
92
+ applicationComponent: row.application_component,
93
+ };
94
+ }
95
+ clear() {
96
+ this.db.exec('DELETE FROM nodes; DELETE FROM edges; DELETE FROM apis;');
97
+ }
98
+ stats() {
99
+ const nodeCount = this.db.prepare('SELECT COUNT(*) as cnt FROM nodes').get().cnt;
100
+ const edgeCount = this.db.prepare('SELECT COUNT(*) as cnt FROM edges').get().cnt;
101
+ const apiCount = this.db.prepare('SELECT COUNT(*) as cnt FROM apis').get().cnt;
102
+ return { nodeCount, edgeCount, apiCount };
103
+ }
104
+ close() {
105
+ this.db.close();
106
+ }
107
+ }
108
+ function rowToNode(row) {
109
+ return {
110
+ id: String(row.id),
111
+ objectType: String(row.object_type),
112
+ objectName: String(row.object_name),
113
+ packageName: String(row.package_name),
114
+ sourceHash: row.source_hash,
115
+ cachedAt: String(row.cached_at),
116
+ valid: row.valid === 1,
117
+ metadata: row.metadata ? JSON.parse(String(row.metadata)) : undefined,
118
+ };
119
+ }
120
+ function rowToEdge(row) {
121
+ return {
122
+ fromId: String(row.from_id),
123
+ toId: String(row.to_id),
124
+ edgeType: String(row.edge_type),
125
+ source: row.source,
126
+ discoveredAt: String(row.discovered_at),
127
+ valid: row.valid === 1,
128
+ };
129
+ }
130
+ //# sourceMappingURL=sqlite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../ts-src/cache/sqlite.ts"],"names":[],"mappings":"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"}