@grafema/util 0.3.0-beta

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 (324) hide show
  1. package/LICENSE +190 -0
  2. package/dist/api/GraphAPI.d.ts +87 -0
  3. package/dist/api/GraphAPI.d.ts.map +1 -0
  4. package/dist/api/GraphAPI.js +212 -0
  5. package/dist/api/GraphAPI.js.map +1 -0
  6. package/dist/api/GuaranteeAPI.d.ts +147 -0
  7. package/dist/api/GuaranteeAPI.d.ts.map +1 -0
  8. package/dist/api/GuaranteeAPI.js +290 -0
  9. package/dist/api/GuaranteeAPI.js.map +1 -0
  10. package/dist/config/ConfigLoader.d.ts +214 -0
  11. package/dist/config/ConfigLoader.d.ts.map +1 -0
  12. package/dist/config/ConfigLoader.js +441 -0
  13. package/dist/config/ConfigLoader.js.map +1 -0
  14. package/dist/config/index.d.ts +6 -0
  15. package/dist/config/index.d.ts.map +1 -0
  16. package/dist/config/index.js +5 -0
  17. package/dist/config/index.js.map +1 -0
  18. package/dist/core/CoverageAnalyzer.d.ts +65 -0
  19. package/dist/core/CoverageAnalyzer.d.ts.map +1 -0
  20. package/dist/core/CoverageAnalyzer.js +199 -0
  21. package/dist/core/CoverageAnalyzer.js.map +1 -0
  22. package/dist/core/FileExplainer.d.ts +101 -0
  23. package/dist/core/FileExplainer.d.ts.map +1 -0
  24. package/dist/core/FileExplainer.js +140 -0
  25. package/dist/core/FileExplainer.js.map +1 -0
  26. package/dist/core/FileOverview.d.ts +124 -0
  27. package/dist/core/FileOverview.d.ts.map +1 -0
  28. package/dist/core/FileOverview.js +279 -0
  29. package/dist/core/FileOverview.js.map +1 -0
  30. package/dist/core/GrafemaUri.d.ts +66 -0
  31. package/dist/core/GrafemaUri.d.ts.map +1 -0
  32. package/dist/core/GrafemaUri.js +191 -0
  33. package/dist/core/GrafemaUri.js.map +1 -0
  34. package/dist/core/GraphBackend.d.ts +158 -0
  35. package/dist/core/GraphBackend.d.ts.map +1 -0
  36. package/dist/core/GraphBackend.js +85 -0
  37. package/dist/core/GraphBackend.js.map +1 -0
  38. package/dist/core/GraphFreshnessChecker.d.ts +33 -0
  39. package/dist/core/GraphFreshnessChecker.d.ts.map +1 -0
  40. package/dist/core/GraphFreshnessChecker.js +104 -0
  41. package/dist/core/GraphFreshnessChecker.js.map +1 -0
  42. package/dist/core/GuaranteeManager.d.ts +254 -0
  43. package/dist/core/GuaranteeManager.d.ts.map +1 -0
  44. package/dist/core/GuaranteeManager.js +447 -0
  45. package/dist/core/GuaranteeManager.js.map +1 -0
  46. package/dist/core/HashUtils.d.ts +24 -0
  47. package/dist/core/HashUtils.d.ts.map +1 -0
  48. package/dist/core/HashUtils.js +46 -0
  49. package/dist/core/HashUtils.js.map +1 -0
  50. package/dist/core/IncrementalReanalyzer.d.ts +33 -0
  51. package/dist/core/IncrementalReanalyzer.d.ts.map +1 -0
  52. package/dist/core/IncrementalReanalyzer.js +67 -0
  53. package/dist/core/IncrementalReanalyzer.js.map +1 -0
  54. package/dist/core/ResourceRegistry.d.ts +17 -0
  55. package/dist/core/ResourceRegistry.d.ts.map +1 -0
  56. package/dist/core/ResourceRegistry.js +32 -0
  57. package/dist/core/ResourceRegistry.js.map +1 -0
  58. package/dist/core/SemanticId.d.ts +159 -0
  59. package/dist/core/SemanticId.d.ts.map +1 -0
  60. package/dist/core/SemanticId.js +291 -0
  61. package/dist/core/SemanticId.js.map +1 -0
  62. package/dist/core/VersionManager.d.ts +166 -0
  63. package/dist/core/VersionManager.d.ts.map +1 -0
  64. package/dist/core/VersionManager.js +239 -0
  65. package/dist/core/VersionManager.js.map +1 -0
  66. package/dist/core/brandNodeInternal.d.ts +14 -0
  67. package/dist/core/brandNodeInternal.d.ts.map +1 -0
  68. package/dist/core/brandNodeInternal.js +4 -0
  69. package/dist/core/brandNodeInternal.js.map +1 -0
  70. package/dist/core/nodes/GuaranteeNode.d.ts +76 -0
  71. package/dist/core/nodes/GuaranteeNode.d.ts.map +1 -0
  72. package/dist/core/nodes/GuaranteeNode.js +118 -0
  73. package/dist/core/nodes/GuaranteeNode.js.map +1 -0
  74. package/dist/core/nodes/IssueNode.d.ts +73 -0
  75. package/dist/core/nodes/IssueNode.d.ts.map +1 -0
  76. package/dist/core/nodes/IssueNode.js +130 -0
  77. package/dist/core/nodes/IssueNode.js.map +1 -0
  78. package/dist/core/nodes/NodeKind.d.ts +104 -0
  79. package/dist/core/nodes/NodeKind.d.ts.map +1 -0
  80. package/dist/core/nodes/NodeKind.js +166 -0
  81. package/dist/core/nodes/NodeKind.js.map +1 -0
  82. package/dist/diagnostics/DiagnosticCollector.d.ts +103 -0
  83. package/dist/diagnostics/DiagnosticCollector.d.ts.map +1 -0
  84. package/dist/diagnostics/DiagnosticCollector.js +133 -0
  85. package/dist/diagnostics/DiagnosticCollector.js.map +1 -0
  86. package/dist/diagnostics/DiagnosticReporter.d.ts +122 -0
  87. package/dist/diagnostics/DiagnosticReporter.d.ts.map +1 -0
  88. package/dist/diagnostics/DiagnosticReporter.js +300 -0
  89. package/dist/diagnostics/DiagnosticReporter.js.map +1 -0
  90. package/dist/diagnostics/DiagnosticWriter.d.ts +31 -0
  91. package/dist/diagnostics/DiagnosticWriter.d.ts.map +1 -0
  92. package/dist/diagnostics/DiagnosticWriter.js +44 -0
  93. package/dist/diagnostics/DiagnosticWriter.js.map +1 -0
  94. package/dist/diagnostics/categories.d.ts +57 -0
  95. package/dist/diagnostics/categories.d.ts.map +1 -0
  96. package/dist/diagnostics/categories.js +71 -0
  97. package/dist/diagnostics/categories.js.map +1 -0
  98. package/dist/diagnostics/index.d.ts +17 -0
  99. package/dist/diagnostics/index.d.ts.map +1 -0
  100. package/dist/diagnostics/index.js +15 -0
  101. package/dist/diagnostics/index.js.map +1 -0
  102. package/dist/errors/GrafemaError.d.ts +200 -0
  103. package/dist/errors/GrafemaError.d.ts.map +1 -0
  104. package/dist/errors/GrafemaError.js +209 -0
  105. package/dist/errors/GrafemaError.js.map +1 -0
  106. package/dist/index.d.ts +75 -0
  107. package/dist/index.d.ts.map +1 -0
  108. package/dist/index.js +76 -0
  109. package/dist/index.js.map +1 -0
  110. package/dist/instructions/index.d.ts +8 -0
  111. package/dist/instructions/index.d.ts.map +1 -0
  112. package/dist/instructions/index.js +20 -0
  113. package/dist/instructions/index.js.map +1 -0
  114. package/dist/instructions/onboarding.md +133 -0
  115. package/dist/knowledge/KnowledgeBase.d.ts +113 -0
  116. package/dist/knowledge/KnowledgeBase.d.ts.map +1 -0
  117. package/dist/knowledge/KnowledgeBase.js +420 -0
  118. package/dist/knowledge/KnowledgeBase.js.map +1 -0
  119. package/dist/knowledge/SemanticAddressResolver.d.ts +59 -0
  120. package/dist/knowledge/SemanticAddressResolver.d.ts.map +1 -0
  121. package/dist/knowledge/SemanticAddressResolver.js +160 -0
  122. package/dist/knowledge/SemanticAddressResolver.js.map +1 -0
  123. package/dist/knowledge/git-ingest.d.ts +58 -0
  124. package/dist/knowledge/git-ingest.d.ts.map +1 -0
  125. package/dist/knowledge/git-ingest.js +301 -0
  126. package/dist/knowledge/git-ingest.js.map +1 -0
  127. package/dist/knowledge/git-queries.d.ts +86 -0
  128. package/dist/knowledge/git-queries.d.ts.map +1 -0
  129. package/dist/knowledge/git-queries.js +177 -0
  130. package/dist/knowledge/git-queries.js.map +1 -0
  131. package/dist/knowledge/index.d.ts +14 -0
  132. package/dist/knowledge/index.d.ts.map +1 -0
  133. package/dist/knowledge/index.js +10 -0
  134. package/dist/knowledge/index.js.map +1 -0
  135. package/dist/knowledge/parser.d.ts +39 -0
  136. package/dist/knowledge/parser.d.ts.map +1 -0
  137. package/dist/knowledge/parser.js +292 -0
  138. package/dist/knowledge/parser.js.map +1 -0
  139. package/dist/knowledge/types.d.ts +133 -0
  140. package/dist/knowledge/types.d.ts.map +1 -0
  141. package/dist/knowledge/types.js +8 -0
  142. package/dist/knowledge/types.js.map +1 -0
  143. package/dist/logging/Logger.d.ts +98 -0
  144. package/dist/logging/Logger.d.ts.map +1 -0
  145. package/dist/logging/Logger.js +274 -0
  146. package/dist/logging/Logger.js.map +1 -0
  147. package/dist/notation/archetypes.d.ts +36 -0
  148. package/dist/notation/archetypes.d.ts.map +1 -0
  149. package/dist/notation/archetypes.js +173 -0
  150. package/dist/notation/archetypes.js.map +1 -0
  151. package/dist/notation/fold.d.ts +25 -0
  152. package/dist/notation/fold.d.ts.map +1 -0
  153. package/dist/notation/fold.js +598 -0
  154. package/dist/notation/fold.js.map +1 -0
  155. package/dist/notation/index.d.ts +18 -0
  156. package/dist/notation/index.d.ts.map +1 -0
  157. package/dist/notation/index.js +16 -0
  158. package/dist/notation/index.js.map +1 -0
  159. package/dist/notation/lodExtractor.d.ts +32 -0
  160. package/dist/notation/lodExtractor.d.ts.map +1 -0
  161. package/dist/notation/lodExtractor.js +149 -0
  162. package/dist/notation/lodExtractor.js.map +1 -0
  163. package/dist/notation/nameShortener.d.ts +22 -0
  164. package/dist/notation/nameShortener.d.ts.map +1 -0
  165. package/dist/notation/nameShortener.js +24 -0
  166. package/dist/notation/nameShortener.js.map +1 -0
  167. package/dist/notation/perspectives.d.ts +11 -0
  168. package/dist/notation/perspectives.d.ts.map +1 -0
  169. package/dist/notation/perspectives.js +16 -0
  170. package/dist/notation/perspectives.js.map +1 -0
  171. package/dist/notation/renderer.d.ts +31 -0
  172. package/dist/notation/renderer.d.ts.map +1 -0
  173. package/dist/notation/renderer.js +315 -0
  174. package/dist/notation/renderer.js.map +1 -0
  175. package/dist/notation/traceRenderer.d.ts +39 -0
  176. package/dist/notation/traceRenderer.d.ts.map +1 -0
  177. package/dist/notation/traceRenderer.js +358 -0
  178. package/dist/notation/traceRenderer.js.map +1 -0
  179. package/dist/notation/types.d.ts +66 -0
  180. package/dist/notation/types.d.ts.map +1 -0
  181. package/dist/notation/types.js +10 -0
  182. package/dist/notation/types.js.map +1 -0
  183. package/dist/queries/NodeContext.d.ts +81 -0
  184. package/dist/queries/NodeContext.d.ts.map +1 -0
  185. package/dist/queries/NodeContext.js +196 -0
  186. package/dist/queries/NodeContext.js.map +1 -0
  187. package/dist/queries/findCallsInFunction.d.ts +62 -0
  188. package/dist/queries/findCallsInFunction.d.ts.map +1 -0
  189. package/dist/queries/findCallsInFunction.js +169 -0
  190. package/dist/queries/findCallsInFunction.js.map +1 -0
  191. package/dist/queries/findContainingFunction.d.ts +57 -0
  192. package/dist/queries/findContainingFunction.d.ts.map +1 -0
  193. package/dist/queries/findContainingFunction.js +91 -0
  194. package/dist/queries/findContainingFunction.js.map +1 -0
  195. package/dist/queries/index.d.ts +18 -0
  196. package/dist/queries/index.d.ts.map +1 -0
  197. package/dist/queries/index.js +14 -0
  198. package/dist/queries/index.js.map +1 -0
  199. package/dist/queries/traceDataflow.d.ts +65 -0
  200. package/dist/queries/traceDataflow.d.ts.map +1 -0
  201. package/dist/queries/traceDataflow.js +754 -0
  202. package/dist/queries/traceDataflow.js.map +1 -0
  203. package/dist/queries/traceValues.d.ts +70 -0
  204. package/dist/queries/traceValues.d.ts.map +1 -0
  205. package/dist/queries/traceValues.js +373 -0
  206. package/dist/queries/traceValues.js.map +1 -0
  207. package/dist/queries/types.d.ts +166 -0
  208. package/dist/queries/types.d.ts.map +1 -0
  209. package/dist/queries/types.js +10 -0
  210. package/dist/queries/types.js.map +1 -0
  211. package/dist/schema/GraphSchemaExtractor.d.ts +53 -0
  212. package/dist/schema/GraphSchemaExtractor.d.ts.map +1 -0
  213. package/dist/schema/GraphSchemaExtractor.js +125 -0
  214. package/dist/schema/GraphSchemaExtractor.js.map +1 -0
  215. package/dist/schema/InterfaceSchemaExtractor.d.ts +73 -0
  216. package/dist/schema/InterfaceSchemaExtractor.d.ts.map +1 -0
  217. package/dist/schema/InterfaceSchemaExtractor.js +113 -0
  218. package/dist/schema/InterfaceSchemaExtractor.js.map +1 -0
  219. package/dist/schema/index.d.ts +5 -0
  220. package/dist/schema/index.d.ts.map +1 -0
  221. package/dist/schema/index.js +3 -0
  222. package/dist/schema/index.js.map +1 -0
  223. package/dist/storage/backends/RFDBServerBackend.d.ts +356 -0
  224. package/dist/storage/backends/RFDBServerBackend.d.ts.map +1 -0
  225. package/dist/storage/backends/RFDBServerBackend.js +748 -0
  226. package/dist/storage/backends/RFDBServerBackend.js.map +1 -0
  227. package/dist/storage/backends/typeValidation.d.ts +47 -0
  228. package/dist/storage/backends/typeValidation.d.ts.map +1 -0
  229. package/dist/storage/backends/typeValidation.js +141 -0
  230. package/dist/storage/backends/typeValidation.js.map +1 -0
  231. package/dist/utils/findRfdbBinary.d.ts +67 -0
  232. package/dist/utils/findRfdbBinary.d.ts.map +1 -0
  233. package/dist/utils/findRfdbBinary.js +261 -0
  234. package/dist/utils/findRfdbBinary.js.map +1 -0
  235. package/dist/utils/lazyDownload.d.ts +43 -0
  236. package/dist/utils/lazyDownload.d.ts.map +1 -0
  237. package/dist/utils/lazyDownload.js +175 -0
  238. package/dist/utils/lazyDownload.js.map +1 -0
  239. package/dist/utils/moduleResolution.d.ts +134 -0
  240. package/dist/utils/moduleResolution.d.ts.map +1 -0
  241. package/dist/utils/moduleResolution.js +189 -0
  242. package/dist/utils/moduleResolution.js.map +1 -0
  243. package/dist/utils/resolveNodeFile.d.ts +13 -0
  244. package/dist/utils/resolveNodeFile.d.ts.map +1 -0
  245. package/dist/utils/resolveNodeFile.js +18 -0
  246. package/dist/utils/resolveNodeFile.js.map +1 -0
  247. package/dist/utils/startRfdbServer.d.ts +63 -0
  248. package/dist/utils/startRfdbServer.d.ts.map +1 -0
  249. package/dist/utils/startRfdbServer.js +142 -0
  250. package/dist/utils/startRfdbServer.js.map +1 -0
  251. package/dist/validation/PathValidator.d.ts +80 -0
  252. package/dist/validation/PathValidator.d.ts.map +1 -0
  253. package/dist/validation/PathValidator.js +252 -0
  254. package/dist/validation/PathValidator.js.map +1 -0
  255. package/dist/version.d.ts +11 -0
  256. package/dist/version.d.ts.map +1 -0
  257. package/dist/version.js +26 -0
  258. package/dist/version.js.map +1 -0
  259. package/package.json +50 -0
  260. package/src/api/GraphAPI.ts +307 -0
  261. package/src/api/GuaranteeAPI.ts +402 -0
  262. package/src/config/ConfigLoader.ts +653 -0
  263. package/src/config/index.ts +13 -0
  264. package/src/core/CoverageAnalyzer.ts +243 -0
  265. package/src/core/FileExplainer.ts +179 -0
  266. package/src/core/FileOverview.ts +397 -0
  267. package/src/core/GrafemaUri.ts +216 -0
  268. package/src/core/GraphBackend.ts +266 -0
  269. package/src/core/GraphFreshnessChecker.ts +145 -0
  270. package/src/core/GuaranteeManager.ts +684 -0
  271. package/src/core/HashUtils.ts +48 -0
  272. package/src/core/IncrementalReanalyzer.ts +106 -0
  273. package/src/core/ResourceRegistry.ts +39 -0
  274. package/src/core/SemanticId.ts +423 -0
  275. package/src/core/VersionManager.ts +405 -0
  276. package/src/core/brandNodeInternal.ts +16 -0
  277. package/src/core/nodes/GuaranteeNode.ts +162 -0
  278. package/src/core/nodes/IssueNode.ts +177 -0
  279. package/src/core/nodes/NodeKind.ts +192 -0
  280. package/src/diagnostics/DiagnosticCollector.ts +170 -0
  281. package/src/diagnostics/DiagnosticReporter.ts +395 -0
  282. package/src/diagnostics/DiagnosticWriter.ts +50 -0
  283. package/src/diagnostics/categories.ts +104 -0
  284. package/src/diagnostics/index.ts +30 -0
  285. package/src/errors/GrafemaError.ts +297 -0
  286. package/src/index.ts +261 -0
  287. package/src/instructions/index.ts +21 -0
  288. package/src/instructions/onboarding.md +133 -0
  289. package/src/knowledge/KnowledgeBase.ts +486 -0
  290. package/src/knowledge/SemanticAddressResolver.ts +191 -0
  291. package/src/knowledge/git-ingest.ts +402 -0
  292. package/src/knowledge/git-queries.ts +269 -0
  293. package/src/knowledge/index.ts +29 -0
  294. package/src/knowledge/parser.ts +294 -0
  295. package/src/knowledge/types.ts +146 -0
  296. package/src/logging/Logger.ts +303 -0
  297. package/src/notation/archetypes.ts +189 -0
  298. package/src/notation/fold.ts +696 -0
  299. package/src/notation/index.ts +27 -0
  300. package/src/notation/lodExtractor.ts +177 -0
  301. package/src/notation/nameShortener.ts +24 -0
  302. package/src/notation/perspectives.ts +18 -0
  303. package/src/notation/renderer.ts +394 -0
  304. package/src/notation/traceRenderer.ts +458 -0
  305. package/src/notation/types.ts +79 -0
  306. package/src/queries/NodeContext.ts +280 -0
  307. package/src/queries/findCallsInFunction.ts +249 -0
  308. package/src/queries/findContainingFunction.ts +124 -0
  309. package/src/queries/index.ts +44 -0
  310. package/src/queries/traceDataflow.ts +838 -0
  311. package/src/queries/traceValues.ts +531 -0
  312. package/src/queries/types.ts +191 -0
  313. package/src/schema/GraphSchemaExtractor.ts +177 -0
  314. package/src/schema/InterfaceSchemaExtractor.ts +173 -0
  315. package/src/schema/index.ts +5 -0
  316. package/src/storage/backends/RFDBServerBackend.ts +895 -0
  317. package/src/storage/backends/typeValidation.ts +154 -0
  318. package/src/utils/findRfdbBinary.ts +288 -0
  319. package/src/utils/lazyDownload.ts +206 -0
  320. package/src/utils/moduleResolution.ts +271 -0
  321. package/src/utils/resolveNodeFile.ts +18 -0
  322. package/src/utils/startRfdbServer.ts +197 -0
  323. package/src/validation/PathValidator.ts +334 -0
  324. package/src/version.ts +28 -0
@@ -0,0 +1,334 @@
1
+ /**
2
+ * PathValidator - проверяет безопасность рефакторинга через path equivalence
3
+ *
4
+ * КОНЦЕПЦИЯ:
5
+ * 1. Трассируем пути от main версии функции до endpoints (DATABASE, HTTP, EXTERNAL)
6
+ * 2. Трассируем пути от __local версии до тех же endpoints
7
+ * 3. Сравниваем: если все пути сохранились → safe, если нет → breaking change
8
+ *
9
+ * ENDPOINTS (критические точки):
10
+ * - DATABASE_QUERY: запросы к БД
11
+ * - HTTP_REQUEST: HTTP запросы
12
+ * - EXTERNAL: внешние сервисы
13
+ * - FILESYSTEM: операции с файлами
14
+ * - MODULE_BOUNDARY: exported functions
15
+ * - SIDE_EFFECTS: console.log, process.exit и т.д.
16
+ */
17
+
18
+ import type { GraphBackend } from '@grafema/types';
19
+ import type { BaseNodeRecord } from '@grafema/types';
20
+
21
+
22
+ /**
23
+ * Node with optional version field for version tracking
24
+ */
25
+ interface VersionedNode extends BaseNodeRecord {
26
+ version?: string;
27
+ }
28
+
29
+ /**
30
+ * Validation result
31
+ */
32
+ export interface PathValidationResult {
33
+ safe: boolean;
34
+ severity: 'info' | 'warning' | 'error';
35
+ message: string;
36
+ deleted?: boolean;
37
+ missing?: EndpointDiff[];
38
+ added?: EndpointDiff[];
39
+ endpointsChecked: number;
40
+ }
41
+
42
+ /**
43
+ * Endpoint diff info
44
+ */
45
+ export interface EndpointDiff {
46
+ type: string;
47
+ name: string;
48
+ reason: string;
49
+ }
50
+
51
+ /**
52
+ * Endpoint node from graph
53
+ */
54
+ interface EndpointNode extends VersionedNode {
55
+ query?: string;
56
+ service?: string;
57
+ exported?: boolean;
58
+ }
59
+
60
+ export class PathValidator {
61
+ private backend: GraphBackend;
62
+
63
+ constructor(backend: GraphBackend) {
64
+ this.backend = backend;
65
+ }
66
+
67
+ /**
68
+ * Проверить эквивалентность путей между main и __local версиями функции
69
+ *
70
+ * @param functionName - Имя функции
71
+ * @param file - Путь к файлу
72
+ * @returns Результат валидации
73
+ */
74
+ async checkPathEquivalence(functionName: string, file: string): Promise<PathValidationResult> {
75
+ // 1. Найти все версии функции (main и __local) по имени
76
+ const allVersions: VersionedNode[] = [];
77
+ for await (const node of this.backend.queryNodes({ type: 'FUNCTION', name: functionName })) {
78
+ // Дополнительно фильтруем по file если он указан
79
+ if (node.file === file || node.file === undefined) {
80
+ allVersions.push(node as VersionedNode);
81
+ }
82
+ }
83
+
84
+ const mainFunction = allVersions.find(n => n.version === 'main');
85
+ const localFunction = allVersions.find(n => n.version === '__local');
86
+
87
+ // 3. Обработать случаи: deleted, added, exists
88
+ if (!mainFunction && localFunction) {
89
+ // Новая функция
90
+ return {
91
+ safe: true,
92
+ severity: 'info',
93
+ message: `New function added: ${functionName}`,
94
+ endpointsChecked: 0
95
+ };
96
+ }
97
+
98
+ if (mainFunction && !localFunction) {
99
+ // Функция удалена
100
+ return {
101
+ safe: false,
102
+ severity: 'error',
103
+ deleted: true,
104
+ message: `Function deleted: ${functionName}`,
105
+ endpointsChecked: 0
106
+ };
107
+ }
108
+
109
+ if (!mainFunction && !localFunction) {
110
+ // Функция не найдена вообще
111
+ return {
112
+ safe: false,
113
+ severity: 'error',
114
+ message: `Function not found: ${functionName}`,
115
+ endpointsChecked: 0
116
+ };
117
+ }
118
+
119
+ // 4. Получить все endpoints для main версии
120
+ const mainEndpoints = await this._getReachableEndpoints(mainFunction!.id);
121
+
122
+ // 5. Получить все endpoints для local версии
123
+ const localEndpoints = await this._getReachableEndpoints(localFunction!.id);
124
+
125
+ // 6. Сравнить endpoints
126
+ const comparison = this._compareEndpoints(mainEndpoints, localEndpoints);
127
+
128
+ // 7. Определить результат
129
+ if (comparison.missing.length > 0) {
130
+ // Breaking change - критические endpoints удалены
131
+ return {
132
+ safe: false,
133
+ severity: 'error',
134
+ message: `Breaking change detected: ${comparison.missing.length} endpoint(s) no longer reachable`,
135
+ missing: comparison.missing,
136
+ endpointsChecked: mainEndpoints.length
137
+ };
138
+ }
139
+
140
+ if (comparison.added.length > 0) {
141
+ // Warning - новые endpoints добавлены
142
+ return {
143
+ safe: true,
144
+ severity: 'warning',
145
+ message: `New behavior added: ${comparison.added.length} new endpoint(s) reachable`,
146
+ added: comparison.added,
147
+ endpointsChecked: mainEndpoints.length
148
+ };
149
+ }
150
+
151
+ // Safe refactoring - все endpoints сохранены
152
+ return {
153
+ safe: true,
154
+ severity: 'info',
155
+ message: `Safe refactoring: all endpoints preserved`,
156
+ endpointsChecked: mainEndpoints.length
157
+ };
158
+ }
159
+
160
+ /**
161
+ * Получить все достижимые endpoints из данной ноды
162
+ *
163
+ * @param nodeId - ID начальной ноды
164
+ * @returns Массив endpoint нод
165
+ */
166
+ private async _getReachableEndpoints(nodeId: string): Promise<EndpointNode[]> {
167
+ // Трассируем пути через CALLS рёбра (BFS до глубины 10)
168
+ // Endpoints - это ноды типа: DATABASE_QUERY, HTTP_REQUEST, EXTERNAL, FILESYSTEM, SIDE_EFFECT
169
+ // Или exported FUNCTION (MODULE_BOUNDARY)
170
+
171
+ const CALLS_EDGE_TYPE = 'CALLS';
172
+ const MAX_DEPTH = 10;
173
+
174
+ // BFS для поиска всех достижимых нод
175
+ const visited = new Set<string>();
176
+ const queue: Array<{ id: string; depth: number }> = [{ id: nodeId, depth: 0 }];
177
+ const endpoints: EndpointNode[] = [];
178
+
179
+ while (queue.length > 0) {
180
+ const { id, depth } = queue.shift()!;
181
+
182
+ if (visited.has(id) || depth > MAX_DEPTH) {
183
+ continue;
184
+ }
185
+ visited.add(id);
186
+
187
+ // Получить ноду и проверить является ли она endpoint
188
+ const node = await this.backend.getNode(id);
189
+ if (node && id !== nodeId) {
190
+ // Check for endpoint types (new namespaced types + legacy names for backward compat)
191
+ const endpointTypes = [
192
+ 'db:query', 'DATABASE_QUERY',
193
+ 'http:request', 'HTTP_REQUEST',
194
+ 'EXTERNAL',
195
+ 'fs:operation', 'FILESYSTEM',
196
+ 'SIDE_EFFECT',
197
+ 'net:request', 'EXTERNAL_NETWORK',
198
+ 'net:stdio', 'EXTERNAL_STDIO'
199
+ ];
200
+ const isEndpoint =
201
+ endpointTypes.includes(node.type) ||
202
+ (node.type === 'FUNCTION' && (node as EndpointNode).exported === true);
203
+
204
+ if (isEndpoint) {
205
+ endpoints.push(node as EndpointNode);
206
+ }
207
+ }
208
+
209
+ // Получить исходящие CALLS рёбра
210
+ const outgoingEdges = await this.backend.getOutgoingEdges(id, [CALLS_EDGE_TYPE]);
211
+ for (const edge of outgoingEdges) {
212
+ const dstId = typeof edge.dst === 'string' ? edge.dst : String(edge.dst);
213
+ if (!visited.has(dstId)) {
214
+ queue.push({ id: dstId, depth: depth + 1 });
215
+ }
216
+ }
217
+ }
218
+
219
+ return endpoints;
220
+ }
221
+
222
+ /**
223
+ * Сравнить два набора endpoints
224
+ *
225
+ * @param mainEndpoints - Endpoints из main версии
226
+ * @param localEndpoints - Endpoints из __local версии
227
+ * @returns { missing: [], added: [] }
228
+ */
229
+ private _compareEndpoints(mainEndpoints: EndpointNode[], localEndpoints: EndpointNode[]): { missing: EndpointDiff[]; added: EndpointDiff[] } {
230
+ const missing: EndpointDiff[] = [];
231
+ const added: EndpointDiff[] = [];
232
+
233
+ // Создаём Map для быстрого поиска
234
+ const localMap = new Map<string, EndpointNode>();
235
+ localEndpoints.forEach(ep => {
236
+ const key = this._getEndpointKey(ep);
237
+ localMap.set(key, ep);
238
+ });
239
+
240
+ const mainMap = new Map<string, EndpointNode>();
241
+ mainEndpoints.forEach(ep => {
242
+ const key = this._getEndpointKey(ep);
243
+ mainMap.set(key, ep);
244
+ });
245
+
246
+ // Находим missing endpoints (есть в main, но нет в local)
247
+ for (const [key, endpoint] of mainMap.entries()) {
248
+ if (!localMap.has(key)) {
249
+ missing.push({
250
+ type: endpoint.type,
251
+ name: (endpoint.name as string) || endpoint.query || 'unknown',
252
+ reason: this._getMissingReason(endpoint)
253
+ });
254
+ }
255
+ }
256
+
257
+ // Находим added endpoints (есть в local, но нет в main)
258
+ for (const [key, endpoint] of localMap.entries()) {
259
+ if (!mainMap.has(key)) {
260
+ added.push({
261
+ type: endpoint.type,
262
+ name: (endpoint.name as string) || endpoint.query || 'unknown',
263
+ reason: this._getAddedReason(endpoint)
264
+ });
265
+ }
266
+ }
267
+
268
+ return { missing, added };
269
+ }
270
+
271
+ /**
272
+ * Получить уникальный ключ для endpoint
273
+ *
274
+ * @param endpoint - Endpoint нода
275
+ * @returns Уникальный ключ
276
+ */
277
+ private _getEndpointKey(endpoint: EndpointNode): string {
278
+ if (endpoint.type === 'DATABASE_QUERY' || endpoint.type === 'db:query') {
279
+ // Для DB query используем query text
280
+ return `db:query:${endpoint.query || endpoint.name}`;
281
+ }
282
+
283
+ if (endpoint.type === 'FUNCTION' && endpoint.exported) {
284
+ // Для exported functions используем stable ID
285
+ return `${endpoint.type}:${endpoint.name}:${endpoint.file}`;
286
+ }
287
+
288
+ if (endpoint.type === 'EXTERNAL') {
289
+ // Для external используем service + name
290
+ return `${endpoint.type}:${endpoint.service}:${endpoint.name}`;
291
+ }
292
+
293
+ // Для остальных используем type + name
294
+ return `${endpoint.type}:${endpoint.name}`;
295
+ }
296
+
297
+ /**
298
+ * Получить reason для missing endpoint
299
+ */
300
+ private _getMissingReason(endpoint: EndpointNode): string {
301
+ if (endpoint.type === 'DATABASE_QUERY') {
302
+ return `Database query no longer executed: ${endpoint.query}`;
303
+ }
304
+
305
+ if (endpoint.type === 'FUNCTION' && endpoint.exported) {
306
+ return `Exported function no longer called: ${endpoint.name}`;
307
+ }
308
+
309
+ if (endpoint.type === 'EXTERNAL') {
310
+ return `External service no longer called: ${endpoint.service}/${endpoint.name}`;
311
+ }
312
+
313
+ return `Endpoint no longer reachable: ${endpoint.name}`;
314
+ }
315
+
316
+ /**
317
+ * Получить reason для added endpoint
318
+ */
319
+ private _getAddedReason(endpoint: EndpointNode): string {
320
+ if (endpoint.type === 'DATABASE_QUERY') {
321
+ return `New database query added: ${endpoint.query}`;
322
+ }
323
+
324
+ if (endpoint.type === 'FUNCTION' && endpoint.exported) {
325
+ return `New call to exported function: ${endpoint.name}`;
326
+ }
327
+
328
+ if (endpoint.type === 'EXTERNAL') {
329
+ return `New external service call: ${endpoint.service}/${endpoint.name}`;
330
+ }
331
+
332
+ return `New endpoint reachable: ${endpoint.name}`;
333
+ }
334
+ }
package/src/version.ts ADDED
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Grafema version constants.
3
+ *
4
+ * Reads version from @grafema/util package.json at module load time.
5
+ * This is the single source of truth for runtime version checks.
6
+ */
7
+ import { readFileSync } from 'fs';
8
+ import { join, dirname } from 'path';
9
+ import { fileURLToPath } from 'url';
10
+
11
+ const __dirname = dirname(fileURLToPath(import.meta.url));
12
+ const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'));
13
+
14
+ /** Full Grafema version string (e.g., "0.2.5-beta") */
15
+ export const GRAFEMA_VERSION: string = pkg.version;
16
+
17
+ /**
18
+ * Extract major.minor.patch from a version string, stripping pre-release tags.
19
+ *
20
+ * "0.2.5-beta" → "0.2.5"
21
+ * "0.2.5" → "0.2.5"
22
+ * "1.0.0-alpha.1" → "1.0.0"
23
+ */
24
+ export function getSchemaVersion(version: string): string {
25
+ // Strip pre-release tag (everything after first hyphen)
26
+ const base = version.split('-')[0];
27
+ return base;
28
+ }