blockmine 1.20.0 → 1.22.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 (434) hide show
  1. package/.claude/agents/README.md +469 -0
  2. package/.claude/agents/auth-route-debugger.md +118 -0
  3. package/.claude/agents/auth-route-tester.md +93 -0
  4. package/.claude/agents/auto-error-resolver.md +97 -0
  5. package/.claude/agents/build-optimizer.md +236 -0
  6. package/.claude/agents/code-architecture-reviewer.md +83 -0
  7. package/.claude/agents/code-refactor-master.md +94 -0
  8. package/.claude/agents/cost-optimizer.md +134 -0
  9. package/.claude/agents/deployment-orchestrator.md +113 -0
  10. package/.claude/agents/documentation-architect.md +82 -0
  11. package/.claude/agents/frontend-error-fixer.md +77 -0
  12. package/.claude/agents/iac-code-generator.md +71 -0
  13. package/.claude/agents/incident-responder.md +346 -0
  14. package/.claude/agents/infrastructure-architect.md +31 -0
  15. package/.claude/agents/kubernetes-specialist.md +56 -0
  16. package/.claude/agents/migration-planner.md +181 -0
  17. package/.claude/agents/network-architect.md +196 -0
  18. package/.claude/agents/plan-reviewer.md +52 -0
  19. package/.claude/agents/refactor-planner.md +63 -0
  20. package/.claude/agents/security-scanner.md +102 -0
  21. package/.claude/agents/web-research-specialist.md +78 -0
  22. package/.claude/commands/cost-analysis.md +315 -0
  23. package/.claude/commands/dev-docs-update.md +55 -0
  24. package/.claude/commands/dev-docs.md +51 -0
  25. package/.claude/commands/incident-debug.md +247 -0
  26. package/.claude/commands/infra-plan.md +81 -0
  27. package/.claude/commands/migration-plan.md +478 -0
  28. package/.claude/commands/route-research-for-testing.md +37 -0
  29. package/.claude/commands/security-review.md +66 -0
  30. package/.claude/hooks/CONFIG.md +448 -0
  31. package/.claude/hooks/README.md +163 -0
  32. package/.claude/hooks/SKILL_ACTIVATION_COMPLETE.md +226 -0
  33. package/.claude/hooks/WINDOWS_HOOKS_README.md +151 -0
  34. package/.claude/hooks/add-skill-activation-banners.ts +132 -0
  35. package/.claude/hooks/comprehensive-skill-test.ts +1315 -0
  36. package/.claude/hooks/error-handling-reminder.sh +12 -0
  37. package/.claude/hooks/error-handling-reminder.ts +222 -0
  38. package/.claude/hooks/k8s-manifest-validator.sh +56 -0
  39. package/.claude/hooks/package-lock.json +556 -0
  40. package/.claude/hooks/package.json +16 -0
  41. package/.claude/hooks/post-tool-use-tracker.ps1 +174 -0
  42. package/.claude/hooks/post-tool-use-tracker.sh +183 -0
  43. package/.claude/hooks/security-policy-check.sh +247 -0
  44. package/.claude/hooks/skill-activation-prompt.ps1 +10 -0
  45. package/.claude/hooks/skill-activation-prompt.sh +10 -0
  46. package/.claude/hooks/skill-activation-prompt.ts +141 -0
  47. package/.claude/hooks/stop-build-check-enhanced.sh +130 -0
  48. package/.claude/hooks/terraform-validator.sh +53 -0
  49. package/.claude/hooks/test-input.json +7 -0
  50. package/.claude/hooks/test-skill-activation.ts +427 -0
  51. package/.claude/hooks/trigger-build-resolver.sh +79 -0
  52. package/.claude/hooks/tsc-check.sh +173 -0
  53. package/.claude/hooks/tsconfig.json +19 -0
  54. package/.claude/settings.json +55 -0
  55. package/.claude/settings.local.json +28 -3
  56. package/.claude/skills/README.md +507 -0
  57. package/.claude/skills/api-engineering/SKILL.md +63 -0
  58. package/.claude/skills/api-engineering/resources/api-versioning.md +88 -0
  59. package/.claude/skills/api-engineering/resources/graphql-patterns.md +106 -0
  60. package/.claude/skills/api-engineering/resources/rate-limiting.md +118 -0
  61. package/.claude/skills/api-engineering/resources/rest-api-design.md +105 -0
  62. package/.claude/skills/backend-dev-guidelines/SKILL.md +306 -0
  63. package/.claude/skills/backend-dev-guidelines/resources/architecture-overview.md +451 -0
  64. package/.claude/skills/backend-dev-guidelines/resources/async-and-errors.md +307 -0
  65. package/.claude/skills/backend-dev-guidelines/resources/complete-examples.md +638 -0
  66. package/.claude/skills/backend-dev-guidelines/resources/configuration.md +275 -0
  67. package/.claude/skills/backend-dev-guidelines/resources/database-patterns.md +224 -0
  68. package/.claude/skills/backend-dev-guidelines/resources/middleware-guide.md +213 -0
  69. package/.claude/skills/backend-dev-guidelines/resources/routing-and-controllers.md +756 -0
  70. package/.claude/skills/backend-dev-guidelines/resources/sentry-and-monitoring.md +336 -0
  71. package/.claude/skills/backend-dev-guidelines/resources/services-and-repositories.md +789 -0
  72. package/.claude/skills/backend-dev-guidelines/resources/testing-guide.md +235 -0
  73. package/.claude/skills/backend-dev-guidelines/resources/validation-patterns.md +754 -0
  74. package/.claude/skills/budget-and-cost-management/SKILL.md +850 -0
  75. package/.claude/skills/build-engineering/SKILL.md +431 -0
  76. package/.claude/skills/build-engineering/resources/artifact-repositories.md +72 -0
  77. package/.claude/skills/build-engineering/resources/build-caching.md +96 -0
  78. package/.claude/skills/build-engineering/resources/build-pipelines.md +105 -0
  79. package/.claude/skills/build-engineering/resources/build-security.md +95 -0
  80. package/.claude/skills/build-engineering/resources/build-systems.md +389 -0
  81. package/.claude/skills/build-engineering/resources/compilation-optimization.md +201 -0
  82. package/.claude/skills/build-engineering/resources/dependency-management.md +73 -0
  83. package/.claude/skills/build-engineering/resources/monorepo-builds.md +110 -0
  84. package/.claude/skills/build-engineering/resources/performance-optimization.md +113 -0
  85. package/.claude/skills/build-engineering/resources/reproducible-builds.md +82 -0
  86. package/.claude/skills/cloud-engineering/SKILL.md +675 -0
  87. package/.claude/skills/cloud-engineering/resources/aws-patterns.md +742 -0
  88. package/.claude/skills/cloud-engineering/resources/azure-patterns.md +714 -0
  89. package/.claude/skills/cloud-engineering/resources/cleared-cloud-environments.md +987 -0
  90. package/.claude/skills/cloud-engineering/resources/cloud-cost-optimization.md +757 -0
  91. package/.claude/skills/cloud-engineering/resources/cloud-networking.md +1058 -0
  92. package/.claude/skills/cloud-engineering/resources/cloud-security-tools.md +1530 -0
  93. package/.claude/skills/cloud-engineering/resources/cloud-security.md +990 -0
  94. package/.claude/skills/cloud-engineering/resources/gcp-patterns.md +758 -0
  95. package/.claude/skills/cloud-engineering/resources/migration-strategies.md +820 -0
  96. package/.claude/skills/cloud-engineering/resources/multi-cloud-strategies.md +670 -0
  97. package/.claude/skills/cloud-engineering/resources/oci-patterns.md +1198 -0
  98. package/.claude/skills/cloud-engineering/resources/serverless-patterns.md +795 -0
  99. package/.claude/skills/cloud-engineering/resources/well-architected-frameworks.md +966 -0
  100. package/.claude/skills/cybersecurity/SKILL.md +409 -0
  101. package/.claude/skills/cybersecurity/resources/security-architecture.md +266 -0
  102. package/.claude/skills/database-engineering/SKILL.md +61 -0
  103. package/.claude/skills/database-engineering/resources/backup-and-recovery.md +72 -0
  104. package/.claude/skills/database-engineering/resources/database-replication.md +63 -0
  105. package/.claude/skills/database-engineering/resources/postgresql-fundamentals.md +70 -0
  106. package/.claude/skills/database-engineering/resources/query-optimization.md +68 -0
  107. package/.claude/skills/devsecops/SKILL.md +374 -0
  108. package/.claude/skills/devsecops/resources/ci-cd-security.md +204 -0
  109. package/.claude/skills/devsecops/resources/compliance-automation.md +530 -0
  110. package/.claude/skills/devsecops/resources/compliance-frameworks.md +2322 -0
  111. package/.claude/skills/devsecops/resources/container-security.md +915 -0
  112. package/.claude/skills/devsecops/resources/cspm-integration.md +1440 -0
  113. package/.claude/skills/devsecops/resources/policy-enforcement.md +619 -0
  114. package/.claude/skills/devsecops/resources/secrets-management.md +755 -0
  115. package/.claude/skills/devsecops/resources/security-monitoring.md +146 -0
  116. package/.claude/skills/devsecops/resources/security-scanning.md +887 -0
  117. package/.claude/skills/devsecops/resources/security-testing.md +203 -0
  118. package/.claude/skills/devsecops/resources/supply-chain-security.md +518 -0
  119. package/.claude/skills/devsecops/resources/vulnerability-management.md +481 -0
  120. package/.claude/skills/devsecops/resources/zero-trust-architecture.md +177 -0
  121. package/.claude/skills/documentation-as-code/SKILL.md +323 -0
  122. package/.claude/skills/documentation-as-code/resources/api-documentation.md +90 -0
  123. package/.claude/skills/documentation-as-code/resources/changelog-management.md +79 -0
  124. package/.claude/skills/documentation-as-code/resources/diagram-generation.md +44 -0
  125. package/.claude/skills/documentation-as-code/resources/docs-as-code-workflow.md +99 -0
  126. package/.claude/skills/documentation-as-code/resources/documentation-automation.md +68 -0
  127. package/.claude/skills/documentation-as-code/resources/documentation-sites.md +79 -0
  128. package/.claude/skills/documentation-as-code/resources/markdown-best-practices.md +162 -0
  129. package/.claude/skills/documentation-as-code/resources/openapi-specification.md +77 -0
  130. package/.claude/skills/documentation-as-code/resources/readme-engineering.md +60 -0
  131. package/.claude/skills/documentation-as-code/resources/technical-writing-guide.md +202 -0
  132. package/.claude/skills/engineering-management/SKILL.md +356 -0
  133. package/.claude/skills/engineering-management/resources/career-ladders.md +609 -0
  134. package/.claude/skills/engineering-management/resources/hiring-and-assessment.md +555 -0
  135. package/.claude/skills/engineering-management/resources/one-on-one-guides.md +609 -0
  136. package/.claude/skills/engineering-management/resources/resource-planning.md +557 -0
  137. package/.claude/skills/engineering-management/resources/team-organization-patterns.md +491 -0
  138. package/.claude/skills/engineering-management/resources/technical-interviews.md +474 -0
  139. package/.claude/skills/engineering-operations-management/SKILL.md +817 -0
  140. package/.claude/skills/error-tracking/SKILL.md +379 -0
  141. package/.claude/skills/frontend-dev-guidelines/SKILL.md +403 -0
  142. package/.claude/skills/frontend-dev-guidelines/resources/common-patterns.md +331 -0
  143. package/.claude/skills/frontend-dev-guidelines/resources/complete-examples.md +872 -0
  144. package/.claude/skills/frontend-dev-guidelines/resources/component-patterns.md +502 -0
  145. package/.claude/skills/frontend-dev-guidelines/resources/data-fetching.md +767 -0
  146. package/.claude/skills/frontend-dev-guidelines/resources/file-organization.md +502 -0
  147. package/.claude/skills/frontend-dev-guidelines/resources/loading-and-error-states.md +501 -0
  148. package/.claude/skills/frontend-dev-guidelines/resources/performance.md +406 -0
  149. package/.claude/skills/frontend-dev-guidelines/resources/routing-guide.md +364 -0
  150. package/.claude/skills/frontend-dev-guidelines/resources/styling-guide.md +428 -0
  151. package/.claude/skills/frontend-dev-guidelines/resources/typescript-standards.md +418 -0
  152. package/.claude/skills/general-it-engineering/SKILL.md +393 -0
  153. package/.claude/skills/general-it-engineering/resources/asset-management.md +712 -0
  154. package/.claude/skills/general-it-engineering/resources/automation-orchestration.md +817 -0
  155. package/.claude/skills/general-it-engineering/resources/business-continuity.md +786 -0
  156. package/.claude/skills/general-it-engineering/resources/change-management.md +715 -0
  157. package/.claude/skills/general-it-engineering/resources/enterprise-monitoring.md +729 -0
  158. package/.claude/skills/general-it-engineering/resources/help-desk-operations.md +738 -0
  159. package/.claude/skills/general-it-engineering/resources/incident-service-management.md +834 -0
  160. package/.claude/skills/general-it-engineering/resources/it-governance.md +753 -0
  161. package/.claude/skills/general-it-engineering/resources/itil-framework.md +503 -0
  162. package/.claude/skills/general-it-engineering/resources/service-management.md +669 -0
  163. package/.claude/skills/infrastructure-architecture/SKILL.md +328 -0
  164. package/.claude/skills/infrastructure-architecture/resources/architecture-decision-records.md +505 -0
  165. package/.claude/skills/infrastructure-architecture/resources/architecture-patterns.md +528 -0
  166. package/.claude/skills/infrastructure-architecture/resources/capacity-planning.md +453 -0
  167. package/.claude/skills/infrastructure-architecture/resources/cleared-environment-architecture.md +773 -0
  168. package/.claude/skills/infrastructure-architecture/resources/cost-architecture.md +499 -0
  169. package/.claude/skills/infrastructure-architecture/resources/data-architecture.md +501 -0
  170. package/.claude/skills/infrastructure-architecture/resources/disaster-recovery.md +535 -0
  171. package/.claude/skills/infrastructure-architecture/resources/migration-architecture.md +512 -0
  172. package/.claude/skills/infrastructure-architecture/resources/multi-region-design.md +608 -0
  173. package/.claude/skills/infrastructure-architecture/resources/reference-architectures.md +562 -0
  174. package/.claude/skills/infrastructure-architecture/resources/security-architecture.md +538 -0
  175. package/.claude/skills/infrastructure-architecture/resources/system-design-principles.md +489 -0
  176. package/.claude/skills/infrastructure-architecture/resources/workload-classification.md +1000 -0
  177. package/.claude/skills/infrastructure-strategy/SKILL.md +924 -0
  178. package/.claude/skills/network-engineering/SKILL.md +385 -0
  179. package/.claude/skills/network-engineering/resources/dns-management.md +738 -0
  180. package/.claude/skills/network-engineering/resources/load-balancing.md +820 -0
  181. package/.claude/skills/network-engineering/resources/network-architecture.md +546 -0
  182. package/.claude/skills/network-engineering/resources/network-security.md +921 -0
  183. package/.claude/skills/network-engineering/resources/network-troubleshooting.md +749 -0
  184. package/.claude/skills/network-engineering/resources/routing-switching.md +373 -0
  185. package/.claude/skills/network-engineering/resources/sdn-networking.md +695 -0
  186. package/.claude/skills/network-engineering/resources/service-mesh-networking.md +777 -0
  187. package/.claude/skills/network-engineering/resources/tcp-ip-protocols.md +444 -0
  188. package/.claude/skills/network-engineering/resources/vpn-connectivity.md +672 -0
  189. package/.claude/skills/observability-engineering/SKILL.md +101 -0
  190. package/.claude/skills/observability-engineering/resources/apm-tools.md +97 -0
  191. package/.claude/skills/observability-engineering/resources/correlation-strategies.md +87 -0
  192. package/.claude/skills/observability-engineering/resources/distributed-tracing.md +98 -0
  193. package/.claude/skills/observability-engineering/resources/logs-aggregation.md +118 -0
  194. package/.claude/skills/observability-engineering/resources/observability-cost-optimization.md +141 -0
  195. package/.claude/skills/observability-engineering/resources/opentelemetry.md +110 -0
  196. package/.claude/skills/platform-engineering/SKILL.md +555 -0
  197. package/.claude/skills/platform-engineering/resources/architecture-overview.md +600 -0
  198. package/.claude/skills/platform-engineering/resources/container-orchestration.md +916 -0
  199. package/.claude/skills/platform-engineering/resources/cost-optimization.md +634 -0
  200. package/.claude/skills/platform-engineering/resources/developer-platforms.md +670 -0
  201. package/.claude/skills/platform-engineering/resources/gitops-automation.md +650 -0
  202. package/.claude/skills/platform-engineering/resources/infrastructure-as-code.md +778 -0
  203. package/.claude/skills/platform-engineering/resources/infrastructure-standards.md +708 -0
  204. package/.claude/skills/platform-engineering/resources/multi-tenancy.md +602 -0
  205. package/.claude/skills/platform-engineering/resources/platform-security.md +711 -0
  206. package/.claude/skills/platform-engineering/resources/resource-management.md +592 -0
  207. package/.claude/skills/platform-engineering/resources/service-mesh.md +628 -0
  208. package/.claude/skills/release-engineering/SKILL.md +393 -0
  209. package/.claude/skills/release-engineering/resources/artifact-management.md +108 -0
  210. package/.claude/skills/release-engineering/resources/build-optimization.md +84 -0
  211. package/.claude/skills/release-engineering/resources/ci-cd-pipelines.md +411 -0
  212. package/.claude/skills/release-engineering/resources/deployment-strategies.md +197 -0
  213. package/.claude/skills/release-engineering/resources/pipeline-security.md +62 -0
  214. package/.claude/skills/release-engineering/resources/progressive-delivery.md +83 -0
  215. package/.claude/skills/release-engineering/resources/release-automation.md +68 -0
  216. package/.claude/skills/release-engineering/resources/release-orchestration.md +77 -0
  217. package/.claude/skills/release-engineering/resources/rollback-strategies.md +66 -0
  218. package/.claude/skills/release-engineering/resources/versioning-strategies.md +59 -0
  219. package/.claude/skills/route-tester/SKILL.md +392 -0
  220. package/.claude/skills/skill-developer/ADVANCED.md +197 -0
  221. package/.claude/skills/skill-developer/HOOK_MECHANISMS.md +306 -0
  222. package/.claude/skills/skill-developer/PATTERNS_LIBRARY.md +152 -0
  223. package/.claude/skills/skill-developer/SKILL.md +430 -0
  224. package/.claude/skills/skill-developer/SKILL_RULES_REFERENCE.md +315 -0
  225. package/.claude/skills/skill-developer/TRIGGER_TYPES.md +305 -0
  226. package/.claude/skills/skill-developer/TROUBLESHOOTING.md +514 -0
  227. package/.claude/skills/skill-rules.json +2940 -0
  228. package/.claude/skills/sre/SKILL.md +464 -0
  229. package/.claude/skills/sre/resources/alerting-best-practices.md +282 -0
  230. package/.claude/skills/sre/resources/capacity-planning.md +226 -0
  231. package/.claude/skills/sre/resources/chaos-engineering.md +193 -0
  232. package/.claude/skills/sre/resources/disaster-recovery.md +232 -0
  233. package/.claude/skills/sre/resources/incident-management.md +436 -0
  234. package/.claude/skills/sre/resources/observability-stack.md +240 -0
  235. package/.claude/skills/sre/resources/on-call-runbooks.md +167 -0
  236. package/.claude/skills/sre/resources/performance-optimization.md +108 -0
  237. package/.claude/skills/sre/resources/reliability-patterns.md +183 -0
  238. package/.claude/skills/sre/resources/slo-sli-sla.md +464 -0
  239. package/.claude/skills/sre/resources/toil-reduction.md +145 -0
  240. package/.claude/skills/systems-engineering/SKILL.md +648 -0
  241. package/.claude/skills/systems-engineering/resources/automation-patterns.md +771 -0
  242. package/.claude/skills/systems-engineering/resources/configuration-management.md +998 -0
  243. package/.claude/skills/systems-engineering/resources/linux-administration.md +672 -0
  244. package/.claude/skills/systems-engineering/resources/networking-fundamentals.md +982 -0
  245. package/.claude/skills/systems-engineering/resources/performance-tuning.md +871 -0
  246. package/.claude/skills/systems-engineering/resources/powershell-scripting.md +482 -0
  247. package/.claude/skills/systems-engineering/resources/security-hardening.md +739 -0
  248. package/.claude/skills/systems-engineering/resources/shell-scripting.md +915 -0
  249. package/.claude/skills/systems-engineering/resources/storage-management.md +628 -0
  250. package/.claude/skills/systems-engineering/resources/system-monitoring.md +787 -0
  251. package/.claude/skills/systems-engineering/resources/troubleshooting-guide.md +753 -0
  252. package/.claude/skills/systems-engineering/resources/windows-administration.md +738 -0
  253. package/.claude/skills/technical-leadership/SKILL.md +728 -0
  254. package/CHANGELOG.md +90 -39
  255. package/README.md +94 -0
  256. package/backend/docs/SECRETS_DOCUMENTATION.md +327 -0
  257. package/backend/jest.config.js +59 -0
  258. package/backend/package-lock.json +6129 -0
  259. package/backend/package.json +16 -4
  260. package/backend/prisma/migrations/20251026104609_add_websocket_api/migration.sql +33 -0
  261. package/backend/prisma/schema.prisma +33 -0
  262. package/backend/src/__tests__/core/DependencyService.test.js +336 -0
  263. package/backend/src/__tests__/core/UserService.test.js +875 -0
  264. package/backend/src/__tests__/repositories/BaseRepository.test.js +146 -0
  265. package/backend/src/__tests__/repositories/BotRepository.test.js +118 -0
  266. package/backend/src/__tests__/repositories/CommandRepository.test.js +132 -0
  267. package/backend/src/__tests__/repositories/EventGraphRepository.test.js +93 -0
  268. package/backend/src/__tests__/repositories/GroupRepository.test.js +155 -0
  269. package/backend/src/__tests__/repositories/PermissionRepository.test.js +130 -0
  270. package/backend/src/__tests__/repositories/PluginRepository.test.js +107 -0
  271. package/backend/src/__tests__/repositories/ServerRepository.test.js +80 -0
  272. package/backend/src/__tests__/repositories/UserRepository.test.js +128 -0
  273. package/backend/src/__tests__/secretsFilter.test.js +425 -0
  274. package/backend/src/__tests__/services/BotLifecycleService.test.js +411 -0
  275. package/backend/src/__tests__/services/BotProcessManager.test.js +285 -0
  276. package/backend/src/__tests__/services/CacheManager.test.js +125 -0
  277. package/backend/src/__tests__/services/CommandExecutionService.test.js +460 -0
  278. package/backend/src/__tests__/services/ResourceMonitorService.test.js +207 -0
  279. package/backend/src/__tests__/services/TelemetryService.test.js +291 -0
  280. package/backend/src/__tests__/setup.js +25 -0
  281. package/backend/src/api/routes/apiKeys.js +181 -0
  282. package/backend/src/api/routes/bots.js +49 -7
  283. package/backend/src/api/routes/plugins.js +2 -1
  284. package/backend/src/api/routes/system.js +174 -0
  285. package/backend/src/container.js +82 -0
  286. package/backend/src/core/BotManager.js +142 -871
  287. package/backend/src/core/BotManager.old.js +1093 -0
  288. package/backend/src/core/BotProcess.js +1092 -850
  289. package/backend/src/core/BreakLoopSignal.js +8 -0
  290. package/backend/src/core/EventGraphManager.js +280 -193
  291. package/backend/src/core/GraphExecutionEngine.js +321 -928
  292. package/backend/src/core/MessageQueue.js +27 -6
  293. package/backend/src/core/NodeRegistry.js +37 -991
  294. package/backend/src/core/PluginManager.js +62 -12
  295. package/backend/src/core/PrismaService.js +32 -0
  296. package/backend/src/core/UserService.js +3 -3
  297. package/backend/src/core/__tests__/PrismaService.test.js +24 -0
  298. package/backend/src/core/commands/README.md +305 -0
  299. package/backend/src/core/commands/dev.js +13 -7
  300. package/backend/src/core/commands/ping.js +10 -4
  301. package/backend/src/core/commands/whois.js +63 -0
  302. package/backend/src/core/config/validation.js +27 -0
  303. package/backend/src/core/constants/graphTypes.js +21 -0
  304. package/backend/src/core/node-registries/actions.js +132 -0
  305. package/backend/src/core/node-registries/arrays.js +137 -0
  306. package/backend/src/core/node-registries/bot.js +23 -0
  307. package/backend/src/core/node-registries/data.js +290 -0
  308. package/backend/src/core/node-registries/debug.js +26 -0
  309. package/backend/src/core/node-registries/events.js +187 -0
  310. package/backend/src/core/node-registries/flow.js +139 -0
  311. package/backend/src/core/node-registries/logic.js +45 -0
  312. package/backend/src/core/node-registries/math.js +42 -0
  313. package/backend/src/core/node-registries/objects.js +98 -0
  314. package/backend/src/core/node-registries/strings.js +153 -0
  315. package/backend/src/core/node-registries/time.js +113 -0
  316. package/backend/src/core/node-registries/users.js +79 -0
  317. package/backend/src/core/nodes/actions/bot_look_at.js +36 -0
  318. package/backend/src/core/nodes/actions/bot_set_variable.js +32 -0
  319. package/backend/src/core/nodes/actions/http_request.js +98 -0
  320. package/backend/src/core/nodes/actions/send_log.js +28 -0
  321. package/backend/src/core/nodes/actions/send_message.js +32 -0
  322. package/backend/src/core/nodes/actions/send_websocket_response.js +33 -0
  323. package/backend/src/core/nodes/arrays/add_element.js +23 -0
  324. package/backend/src/core/nodes/arrays/contains.js +40 -0
  325. package/backend/src/core/nodes/arrays/find_index.js +23 -0
  326. package/backend/src/core/nodes/arrays/get_by_index.js +23 -0
  327. package/backend/src/core/nodes/arrays/get_next.js +35 -0
  328. package/backend/src/core/nodes/arrays/get_random_element.js +32 -0
  329. package/backend/src/core/nodes/arrays/remove_by_index.js +30 -0
  330. package/backend/src/core/nodes/bot/get_position.js +20 -0
  331. package/backend/src/core/nodes/data/array_literal.js +31 -0
  332. package/backend/src/core/nodes/data/boolean_literal.js +21 -0
  333. package/backend/src/core/nodes/data/cast.js +42 -0
  334. package/backend/src/core/nodes/data/datetime_literal.js +27 -0
  335. package/backend/src/core/nodes/data/entity_info.js +69 -0
  336. package/backend/src/core/nodes/data/get_argument.js +23 -0
  337. package/backend/src/core/nodes/data/get_bot_look.js +14 -0
  338. package/backend/src/core/nodes/data/get_entity_field.js +18 -0
  339. package/backend/src/core/nodes/data/get_nearby_entities.js +32 -0
  340. package/backend/src/core/nodes/data/get_nearby_players.js +64 -0
  341. package/backend/src/core/nodes/data/get_server_players.js +18 -0
  342. package/backend/src/core/nodes/data/get_user_field.js +40 -0
  343. package/backend/src/core/nodes/data/get_variable.js +23 -0
  344. package/backend/src/core/nodes/data/length.js +25 -0
  345. package/backend/src/core/nodes/data/make_object.js +31 -0
  346. package/backend/src/core/nodes/data/number_literal.js +21 -0
  347. package/backend/src/core/nodes/data/string_literal.js +34 -0
  348. package/backend/src/core/nodes/data/type_check.js +53 -0
  349. package/backend/src/core/nodes/debug/log.js +16 -0
  350. package/backend/src/core/nodes/flow/branch.js +15 -0
  351. package/backend/src/core/nodes/flow/break.js +14 -0
  352. package/backend/src/core/nodes/flow/delay.js +43 -0
  353. package/backend/src/core/nodes/flow/for_each.js +39 -0
  354. package/backend/src/core/nodes/flow/sequence.js +16 -0
  355. package/backend/src/core/nodes/flow/switch.js +47 -0
  356. package/backend/src/core/nodes/flow/while.js +64 -0
  357. package/backend/src/core/nodes/logic/__tests__/compare.test.js +83 -0
  358. package/backend/src/core/nodes/logic/compare.js +33 -0
  359. package/backend/src/core/nodes/logic/operation.js +35 -0
  360. package/backend/src/core/nodes/math/__tests__/operation.test.js +65 -0
  361. package/backend/src/core/nodes/math/operation.js +31 -0
  362. package/backend/src/core/nodes/math/random_number.js +43 -0
  363. package/backend/src/core/nodes/objects/create.js +40 -0
  364. package/backend/src/core/nodes/objects/delete.js +26 -0
  365. package/backend/src/core/nodes/objects/get.js +23 -0
  366. package/backend/src/core/nodes/objects/has_key.js +30 -0
  367. package/backend/src/core/nodes/objects/set.js +27 -0
  368. package/backend/src/core/nodes/strings/__tests__/concat.test.js +89 -0
  369. package/backend/src/core/nodes/strings/concat.js +27 -0
  370. package/backend/src/core/nodes/strings/contains.js +41 -0
  371. package/backend/src/core/nodes/strings/ends_with.js +43 -0
  372. package/backend/src/core/nodes/strings/equals.js +36 -0
  373. package/backend/src/core/nodes/strings/length.js +36 -0
  374. package/backend/src/core/nodes/strings/matches.js +39 -0
  375. package/backend/src/core/nodes/strings/split.js +37 -0
  376. package/backend/src/core/nodes/strings/starts_with.js +43 -0
  377. package/backend/src/core/nodes/time/__tests__/now.test.js +24 -0
  378. package/backend/src/core/nodes/time/add.js +33 -0
  379. package/backend/src/core/nodes/time/compare.js +35 -0
  380. package/backend/src/core/nodes/time/diff.js +29 -0
  381. package/backend/src/core/nodes/time/format.js +32 -0
  382. package/backend/src/core/nodes/time/now.js +18 -0
  383. package/backend/src/core/nodes/users/check_blacklist.js +37 -0
  384. package/backend/src/core/nodes/users/get_groups.js +36 -0
  385. package/backend/src/core/nodes/users/get_permissions.js +36 -0
  386. package/backend/src/core/nodes/users/set_blacklist.js +37 -0
  387. package/backend/src/core/services/BotLifecycleService.js +596 -0
  388. package/backend/src/core/services/BotProcessManager.js +163 -0
  389. package/backend/src/core/services/CacheManager.js +111 -0
  390. package/backend/src/core/services/CommandExecutionService.js +351 -0
  391. package/backend/src/core/services/ResourceMonitorService.js +90 -0
  392. package/backend/src/core/services/TelemetryService.js +124 -0
  393. package/backend/src/core/services/ValidationService.js +132 -0
  394. package/backend/src/core/services/__tests__/ValidationService.test.js +148 -0
  395. package/backend/src/core/services.js +20 -5
  396. package/backend/src/core/system/CommandContext.js +84 -0
  397. package/backend/src/core/system/Transport.js +78 -0
  398. package/backend/src/core/utils/__tests__/jsonParser.test.js +44 -0
  399. package/backend/src/core/utils/jsonParser.js +18 -0
  400. package/backend/src/core/utils/secretsFilter.js +262 -0
  401. package/backend/src/core/utils/variableParser.js +89 -0
  402. package/backend/src/core/validation/__tests__/nodeSchemas.test.js +175 -0
  403. package/backend/src/core/validation/nodeSchemas.js +112 -0
  404. package/backend/src/lib/prisma.js +2 -4
  405. package/backend/src/real-time/botApi/handlers/commandHandlers.js +28 -0
  406. package/backend/src/real-time/botApi/handlers/graphHandlers.js +99 -0
  407. package/backend/src/real-time/botApi/handlers/graphWebSocketHandlers.js +147 -0
  408. package/backend/src/real-time/botApi/handlers/index.js +43 -0
  409. package/backend/src/real-time/botApi/handlers/messageHandlers.js +66 -0
  410. package/backend/src/real-time/botApi/handlers/statusHandlers.js +17 -0
  411. package/backend/src/real-time/botApi/handlers/userHandlers.js +141 -0
  412. package/backend/src/real-time/botApi/index.js +40 -0
  413. package/backend/src/real-time/botApi/middleware.js +79 -0
  414. package/backend/src/real-time/botApi/utils.js +54 -0
  415. package/backend/src/real-time/socketHandler.js +6 -2
  416. package/backend/src/repositories/BaseRepository.js +43 -0
  417. package/backend/src/repositories/BotRepository.js +42 -0
  418. package/backend/src/repositories/CommandRepository.js +53 -0
  419. package/backend/src/repositories/EventGraphRepository.js +40 -0
  420. package/backend/src/repositories/GroupRepository.js +69 -0
  421. package/backend/src/repositories/PermissionRepository.js +48 -0
  422. package/backend/src/repositories/PluginRepository.js +42 -0
  423. package/backend/src/repositories/ServerRepository.js +27 -0
  424. package/backend/src/repositories/UserRepository.js +48 -0
  425. package/backend/src/server.js +3 -0
  426. package/backend/src/test-refactor.js +85 -0
  427. package/frontend/dist/assets/index-CfTo92bP.css +1 -0
  428. package/frontend/dist/assets/index-CiFD5X9Z.js +8344 -0
  429. package/frontend/dist/index.html +2 -2
  430. package/frontend/package.json +1 -5
  431. package/package.json +2 -1
  432. package/frontend/dist/assets/index-BFd7YoAj.css +0 -1
  433. package/frontend/dist/assets/index-CMMutadc.js +0 -8352
  434. package/nul +0 -0
@@ -0,0 +1,44 @@
1
+ const { safeJsonParse } = require('../jsonParser');
2
+
3
+ describe('safeJsonParse', () => {
4
+ it('should parse valid JSON string', () => {
5
+ const result = safeJsonParse('{"key":"value"}', null, 'test');
6
+ expect(result).toEqual({ key: 'value' });
7
+ });
8
+
9
+ it('should return default value for invalid JSON', () => {
10
+ const result = safeJsonParse('{invalid}', { default: true }, 'test');
11
+ expect(result).toEqual({ default: true });
12
+ });
13
+
14
+ it('should handle null input', () => {
15
+ const result = safeJsonParse(null, 'default', 'test');
16
+ expect(result).toBe('default');
17
+ });
18
+
19
+ it('should handle undefined input', () => {
20
+ const result = safeJsonParse(undefined, 'default', 'test');
21
+ expect(result).toBe('default');
22
+ });
23
+
24
+ it('should return non-string values as-is', () => {
25
+ const obj = { key: 'value' };
26
+ const result = safeJsonParse(obj, null, 'test');
27
+ expect(result).toBe(obj);
28
+ });
29
+
30
+ it('should parse arrays correctly', () => {
31
+ const result = safeJsonParse('[1,2,3]', [], 'test');
32
+ expect(result).toEqual([1, 2, 3]);
33
+ });
34
+
35
+ it('should return default for malformed JSON', () => {
36
+ const consoleSpy = jest.spyOn(console, 'error').mockImplementation();
37
+ const result = safeJsonParse('{"key": undefined}', [], 'test');
38
+
39
+ expect(result).toEqual([]);
40
+ expect(consoleSpy).toHaveBeenCalled();
41
+
42
+ consoleSpy.mockRestore();
43
+ });
44
+ });
@@ -0,0 +1,18 @@
1
+ function safeJsonParse(jsonString, defaultValue = null, context = 'unknown') {
2
+ if (jsonString === null || jsonString === undefined) {
3
+ return defaultValue;
4
+ }
5
+
6
+ if (typeof jsonString !== 'string') {
7
+ return jsonString;
8
+ }
9
+
10
+ try {
11
+ return JSON.parse(jsonString);
12
+ } catch (error) {
13
+ console.error(`[JSONParser] Failed to parse JSON in ${context}:`, error.message);
14
+ return defaultValue;
15
+ }
16
+ }
17
+
18
+ module.exports = { safeJsonParse };
@@ -0,0 +1,262 @@
1
+ /**
2
+ * Утилита для работы со скрытыми (секретными) значениями настроек плагинов
3
+ * Позволяет маскировать чувствительные данные при отправке на фронтенд
4
+ */
5
+
6
+ const SECRET_MASK = '********';
7
+
8
+ /**
9
+ * Создает глубокую копию объекта
10
+ * @param {any} obj - объект для клонирования
11
+ * @returns {any} - глубокая копия объекта
12
+ */
13
+ function deepClone(obj) {
14
+ // Используем structuredClone если доступен (Node.js 17+)
15
+ if (typeof structuredClone !== 'undefined') {
16
+ try {
17
+ return structuredClone(obj);
18
+ } catch (e) {
19
+ // Fallback для случаев когда structuredClone не может обработать объект
20
+ }
21
+ }
22
+
23
+ // Fallback на JSON parse/stringify
24
+ // Ограничения: не сохраняет функции, undefined, Symbol, circular references
25
+ try {
26
+ return JSON.parse(JSON.stringify(obj));
27
+ } catch (e) {
28
+ console.error('[secretsFilter] Ошибка клонирования объекта:', e);
29
+ return obj;
30
+ }
31
+ }
32
+
33
+ /**
34
+ * Определяет, использует ли плагин группированные настройки
35
+ * Группированные настройки имеют структуру: { "CategoryName": { label: "...", setting1: {...}, ... } }
36
+ * @param {Object} manifestSettings - настройки из манифеста плагина
37
+ * @returns {boolean}
38
+ */
39
+ function isGroupedSettings(manifestSettings) {
40
+ if (!manifestSettings || typeof manifestSettings !== 'object') {
41
+ return false;
42
+ }
43
+
44
+ const firstKey = Object.keys(manifestSettings)[0];
45
+ if (!firstKey) {
46
+ return false;
47
+ }
48
+
49
+ const firstValue = manifestSettings[firstKey];
50
+
51
+ // Проверяем, что первое значение - объект с label и без type
52
+ // (настройки имеют type, группы имеют label)
53
+ return (
54
+ firstValue &&
55
+ typeof firstValue === 'object' &&
56
+ !Array.isArray(firstValue) &&
57
+ 'label' in firstValue &&
58
+ !('type' in firstValue)
59
+ );
60
+ }
61
+
62
+ /**
63
+ * Определяет, является ли настройка секретной
64
+ * @param {Object} settingConfig - конфигурация настройки из manifest
65
+ * @returns {boolean}
66
+ */
67
+ function isSecretSetting(settingConfig) {
68
+ if (!settingConfig) {
69
+ return false;
70
+ }
71
+ return settingConfig.secret === true;
72
+ }
73
+
74
+ /**
75
+ * Маскирует секретное значение
76
+ * @param {any} value - значение для маскировки
77
+ * @param {Object} settingConfig - конфигурация настройки
78
+ * @returns {any} - замаскированное значение
79
+ */
80
+ function maskSecretValue(value, settingConfig) {
81
+ if (!isSecretSetting(settingConfig)) {
82
+ return value;
83
+ }
84
+
85
+ // Если значение пустое/null/undefined, возвращаем как есть
86
+ if (value === null || value === undefined || value === '') {
87
+ return value;
88
+ }
89
+
90
+ // Для массивов маскируем каждый элемент
91
+ if (Array.isArray(value)) {
92
+ return value.map(() => SECRET_MASK);
93
+ }
94
+
95
+ // Для объектов маскируем каждое значение
96
+ if (typeof value === 'object') {
97
+ const masked = {};
98
+ for (const key in value) {
99
+ masked[key] = SECRET_MASK;
100
+ }
101
+ return masked;
102
+ }
103
+
104
+ // Для остальных типов просто возвращаем маску
105
+ return SECRET_MASK;
106
+ }
107
+
108
+ /**
109
+ * Фильтрует настройки плагина, маскируя секретные значения
110
+ * @param {Object} settings - текущие настройки плагина
111
+ * @param {Object} manifestSettings - описание настроек из manifest
112
+ * @param {boolean} isGrouped - использует ли плагин группированные настройки
113
+ * @returns {Object} - отфильтрованные настройки
114
+ */
115
+ function filterSecretSettings(settings, manifestSettings, isGrouped = false) {
116
+ if (!settings || !manifestSettings) {
117
+ return settings;
118
+ }
119
+
120
+ const filteredSettings = { ...settings };
121
+
122
+ if (isGrouped) {
123
+ // Обработка группированных настроек
124
+ for (const categoryKey in manifestSettings) {
125
+ const categoryConfig = manifestSettings[categoryKey];
126
+ if (typeof categoryConfig !== 'object' || !categoryConfig.label) {
127
+ continue;
128
+ }
129
+
130
+ for (const settingKey in categoryConfig) {
131
+ if (settingKey === 'label') continue;
132
+
133
+ const settingConfig = categoryConfig[settingKey];
134
+ if (isSecretSetting(settingConfig) && settingKey in filteredSettings) {
135
+ filteredSettings[settingKey] = maskSecretValue(
136
+ filteredSettings[settingKey],
137
+ settingConfig
138
+ );
139
+ }
140
+ }
141
+ }
142
+ } else {
143
+ // Обработка обычных настроек
144
+ for (const settingKey in manifestSettings) {
145
+ const settingConfig = manifestSettings[settingKey];
146
+ if (isSecretSetting(settingConfig) && settingKey in filteredSettings) {
147
+ filteredSettings[settingKey] = maskSecretValue(
148
+ filteredSettings[settingKey],
149
+ settingConfig
150
+ );
151
+ }
152
+ }
153
+ }
154
+
155
+ return filteredSettings;
156
+ }
157
+
158
+ /**
159
+ * Проверяет, является ли значение замаскированным
160
+ * @param {any} value - значение для проверки
161
+ * @returns {boolean}
162
+ */
163
+ function isMaskedValue(value) {
164
+ if (value === SECRET_MASK) {
165
+ return true;
166
+ }
167
+
168
+ if (Array.isArray(value)) {
169
+ // Пустой массив не является замаскированным
170
+ if (value.length === 0) {
171
+ return false;
172
+ }
173
+ return value.every(item => item === SECRET_MASK);
174
+ }
175
+
176
+ if (typeof value === 'object' && value !== null) {
177
+ const values = Object.values(value);
178
+ // Пустой объект не является замаскированным
179
+ if (values.length === 0) {
180
+ return false;
181
+ }
182
+ return values.every(v => v === SECRET_MASK);
183
+ }
184
+
185
+ return false;
186
+ }
187
+
188
+ /**
189
+ * Фильтрует обновления настроек, удаляя замаскированные значения
190
+ * Это предотвращает сохранение маски вместо реального значения
191
+ * @param {Object} newSettings - новые настройки для сохранения
192
+ * @param {Object} existingSettings - существующие настройки
193
+ * @param {Object} manifestSettings - описание настроек из manifest
194
+ * @param {boolean} isGrouped - использует ли плагин группированные настройки
195
+ * @returns {Object} - отфильтрованные настройки для сохранения
196
+ */
197
+ function prepareSettingsForSave(newSettings, existingSettings, manifestSettings, isGrouped = false) {
198
+ if (!newSettings || !manifestSettings) {
199
+ return newSettings;
200
+ }
201
+
202
+ // Используем глубокое клонирование для избежания мутаций и side effects
203
+ const settingsToSave = deepClone(newSettings);
204
+
205
+ if (isGrouped) {
206
+ for (const categoryKey in manifestSettings) {
207
+ const categoryConfig = manifestSettings[categoryKey];
208
+ if (typeof categoryConfig !== 'object' || !categoryConfig.label) {
209
+ continue;
210
+ }
211
+
212
+ for (const settingKey in categoryConfig) {
213
+ if (settingKey === 'label') continue;
214
+
215
+ const settingConfig = categoryConfig[settingKey];
216
+
217
+ // Если настройка секретная и новое значение является маской,
218
+ // используем существующее значение
219
+ if (isSecretSetting(settingConfig) &&
220
+ settingKey in settingsToSave &&
221
+ isMaskedValue(settingsToSave[settingKey])) {
222
+
223
+ if (existingSettings && settingKey in existingSettings) {
224
+ settingsToSave[settingKey] = existingSettings[settingKey];
225
+ } else {
226
+ // Если существующего значения нет, удаляем ключ
227
+ delete settingsToSave[settingKey];
228
+ }
229
+ }
230
+ }
231
+ }
232
+ } else {
233
+ for (const settingKey in manifestSettings) {
234
+ const settingConfig = manifestSettings[settingKey];
235
+
236
+ if (isSecretSetting(settingConfig) &&
237
+ settingKey in settingsToSave &&
238
+ isMaskedValue(settingsToSave[settingKey])) {
239
+
240
+ if (existingSettings && settingKey in existingSettings) {
241
+ settingsToSave[settingKey] = existingSettings[settingKey];
242
+ } else {
243
+ delete settingsToSave[settingKey];
244
+ }
245
+ }
246
+ }
247
+ }
248
+
249
+ return settingsToSave;
250
+ }
251
+
252
+ module.exports = {
253
+ SECRET_MASK,
254
+ isSecretSetting,
255
+ maskSecretValue,
256
+ filterSecretSettings,
257
+ isMaskedValue,
258
+ prepareSettingsForSave,
259
+ isGroupedSettings,
260
+ deepClone
261
+ };
262
+
@@ -0,0 +1,89 @@
1
+ const { safeJsonParse } = require('./jsonParser');
2
+
3
+ /**
4
+ * Парсит значение переменной в зависимости от её типа
5
+ * @param {object} variable - Объект переменной с полями type, name, value
6
+ * @param {string} variable.type - Тип переменной ('number', 'boolean', 'array', 'string')
7
+ * @param {string} variable.name - Имя переменной (для логирования)
8
+ * @param {*} variable.value - Исходное значение переменной
9
+ * @param {string} [contextName] - Имя контекста для логирования (например, 'EventGraph ID 123')
10
+ * @returns {*} - Распарсенное значение переменной
11
+ */
12
+ function parseVariableValue(variable, contextName = 'unknown context') {
13
+ const { type, name, value } = variable;
14
+
15
+ try {
16
+ switch (type) {
17
+ case 'number':
18
+ return Number(value) || 0;
19
+
20
+ case 'boolean':
21
+ return value === 'true';
22
+
23
+ case 'array': {
24
+ const parsedArray = safeJsonParse(value, [], `variable ${name}`);
25
+ if (!Array.isArray(parsedArray)) {
26
+ console.warn(
27
+ `[VariableParser] Failed to parse variable "${name}" as array in ${contextName}. ` +
28
+ `Falling back to empty array. Raw value:`,
29
+ value
30
+ );
31
+ return [];
32
+ }
33
+ return parsedArray;
34
+ }
35
+
36
+ default:
37
+ return value;
38
+ }
39
+ } catch (e) {
40
+ console.error(`[VariableParser] Error parsing variable "${name}" in ${contextName}:`, e);
41
+ return getDefaultValueForType(type);
42
+ }
43
+ }
44
+
45
+ /**
46
+ * Возвращает значение по умолчанию для типа переменной
47
+ * @param {string} type - Тип переменной
48
+ * @returns {*} - Значение по умолчанию
49
+ */
50
+ function getDefaultValueForType(type) {
51
+ switch (type) {
52
+ case 'number':
53
+ return 0;
54
+ case 'boolean':
55
+ return false;
56
+ case 'array':
57
+ return [];
58
+ default:
59
+ return '';
60
+ }
61
+ }
62
+
63
+ /**
64
+ * Парсит массив переменных и возвращает объект с распарсенными значениями
65
+ * @param {Array} variables - Массив объектов переменных
66
+ * @param {string} [contextName] - Имя контекста для логирования
67
+ * @returns {object} - Объект с именами переменных в качестве ключей и распарсенными значениями
68
+ */
69
+ function parseVariables(variables, contextName = 'unknown context') {
70
+ if (!Array.isArray(variables)) {
71
+ return {};
72
+ }
73
+
74
+ const result = {};
75
+ for (const variable of variables) {
76
+ if (!variable.name) {
77
+ console.warn(`[VariableParser] Skipping variable without name in ${contextName}`);
78
+ continue;
79
+ }
80
+ result[variable.name] = parseVariableValue(variable, contextName);
81
+ }
82
+ return result;
83
+ }
84
+
85
+ module.exports = {
86
+ parseVariableValue,
87
+ parseVariables,
88
+ getDefaultValueForType,
89
+ };
@@ -0,0 +1,175 @@
1
+ const {
2
+ validateNodeConfig,
3
+ validateNodeData,
4
+ validateGraph,
5
+ } = require('../nodeSchemas');
6
+
7
+ describe('Node Validation Schemas', () => {
8
+ describe('validateNodeConfig', () => {
9
+ it('should validate correct node configuration', () => {
10
+ const validConfig = {
11
+ type: 'test:node',
12
+ label: 'Test Node',
13
+ category: 'Test',
14
+ inputs: [
15
+ { id: 'input1', name: 'Input 1', type: 'String' }
16
+ ],
17
+ outputs: [
18
+ { id: 'output1', name: 'Output 1', type: 'String' }
19
+ ],
20
+ };
21
+
22
+ const result = validateNodeConfig(validConfig);
23
+ expect(result.success).toBe(true);
24
+ expect(result.data).toBeDefined();
25
+ });
26
+
27
+ it('should fail validation for missing required fields', () => {
28
+ const invalidConfig = {
29
+ label: 'Test Node',
30
+ };
31
+
32
+ const result = validateNodeConfig(invalidConfig);
33
+ expect(result.success).toBe(false);
34
+ expect(result.error).toBeDefined();
35
+ });
36
+
37
+ it('should fail validation for invalid pin structure', () => {
38
+ const invalidConfig = {
39
+ type: 'test:node',
40
+ label: 'Test Node',
41
+ category: 'Test',
42
+ inputs: [
43
+ { id: '', name: 'Input 1', type: 'String' }
44
+ ],
45
+ };
46
+
47
+ const result = validateNodeConfig(invalidConfig);
48
+ expect(result.success).toBe(false);
49
+ });
50
+
51
+ it('should accept optional fields', () => {
52
+ const configWithOptional = {
53
+ type: 'test:node',
54
+ label: 'Test Node',
55
+ category: 'Test',
56
+ description: 'A test node',
57
+ inputs: [],
58
+ outputs: [],
59
+ };
60
+
61
+ const result = validateNodeConfig(configWithOptional);
62
+ expect(result.success).toBe(true);
63
+ });
64
+ });
65
+
66
+ describe('validateNodeData', () => {
67
+ it('should validate correct node data', () => {
68
+ const validNodeData = {
69
+ id: 'node-123',
70
+ type: 'test:node',
71
+ position: { x: 100, y: 200 },
72
+ data: { pinCount: 2 },
73
+ };
74
+
75
+ const result = validateNodeData(validNodeData);
76
+ expect(result.success).toBe(true);
77
+ });
78
+
79
+ it('should fail validation for missing position coordinates', () => {
80
+ const invalidNodeData = {
81
+ id: 'node-123',
82
+ type: 'test:node',
83
+ position: { x: 100 },
84
+ };
85
+
86
+ const result = validateNodeData(invalidNodeData);
87
+ expect(result.success).toBe(false);
88
+ });
89
+
90
+ it('should accept empty data object', () => {
91
+ const nodeDataWithEmptyData = {
92
+ id: 'node-123',
93
+ type: 'test:node',
94
+ position: { x: 100, y: 200 },
95
+ };
96
+
97
+ const result = validateNodeData(nodeDataWithEmptyData);
98
+ expect(result.success).toBe(true);
99
+ expect(result.data.data).toEqual({});
100
+ });
101
+ });
102
+
103
+ describe('validateGraph', () => {
104
+ it('should validate correct graph structure', () => {
105
+ const validGraph = {
106
+ nodes: [
107
+ {
108
+ id: 'node-1',
109
+ type: 'test:node',
110
+ position: { x: 100, y: 200 },
111
+ data: {},
112
+ }
113
+ ],
114
+ connections: [
115
+ {
116
+ id: 'conn-1',
117
+ sourceNodeId: 'node-1',
118
+ targetNodeId: 'node-2',
119
+ sourcePinId: 'output1',
120
+ targetPinId: 'input1',
121
+ }
122
+ ],
123
+ variables: [
124
+ {
125
+ id: 'var-1',
126
+ name: 'testVar',
127
+ type: 'string',
128
+ value: 'test',
129
+ }
130
+ ],
131
+ };
132
+
133
+ const result = validateGraph(validGraph);
134
+ expect(result.success).toBe(true);
135
+ });
136
+
137
+ it('should fail validation for missing nodes array', () => {
138
+ const invalidGraph = {
139
+ connections: [],
140
+ };
141
+
142
+ const result = validateGraph(invalidGraph);
143
+ expect(result.success).toBe(false);
144
+ });
145
+
146
+ it('should accept graph with empty variables', () => {
147
+ const graphWithoutVars = {
148
+ nodes: [],
149
+ connections: [],
150
+ };
151
+
152
+ const result = validateGraph(graphWithoutVars);
153
+ expect(result.success).toBe(true);
154
+ expect(result.data.variables).toEqual([]);
155
+ });
156
+
157
+ it('should fail validation for invalid variable type', () => {
158
+ const invalidGraph = {
159
+ nodes: [],
160
+ connections: [],
161
+ variables: [
162
+ {
163
+ id: 'var-1',
164
+ name: 'testVar',
165
+ type: 'invalid_type',
166
+ value: 'test',
167
+ }
168
+ ],
169
+ };
170
+
171
+ const result = validateGraph(invalidGraph);
172
+ expect(result.success).toBe(false);
173
+ });
174
+ });
175
+ });
@@ -0,0 +1,112 @@
1
+ const { z } = require('zod');
2
+ const { GRAPH_TYPES } = require('../constants/graphTypes');
3
+
4
+ const PinSchema = z.object({
5
+ id: z.string().min(1),
6
+ name: z.string().min(1),
7
+ type: z.string().min(1),
8
+ required: z.boolean().optional(),
9
+ defaultValue: z.any().optional(),
10
+ });
11
+
12
+ const NodeConfigSchema = z.object({
13
+ type: z.string().min(1),
14
+ label: z.string().min(1),
15
+ category: z.string().min(1),
16
+ description: z.string().optional(),
17
+ name: z.string().optional(),
18
+ graphType: z.enum([GRAPH_TYPES.ALL, GRAPH_TYPES.COMMAND, GRAPH_TYPES.EVENT]).optional(),
19
+ isEvent: z.boolean().optional(),
20
+ dynamicPins: z.boolean().optional(),
21
+ inputs: z.array(PinSchema).optional().default([]),
22
+ outputs: z.array(PinSchema).optional().default([]),
23
+ pins: z.object({
24
+ inputs: z.array(PinSchema).optional().default([]),
25
+ outputs: z.array(PinSchema).optional().default([]),
26
+ }).optional(),
27
+ executor: z.function().optional(),
28
+ evaluator: z.function().optional(),
29
+ }).passthrough();
30
+
31
+ const NodeDataSchema = z.object({
32
+ id: z.string().min(1),
33
+ type: z.string().min(1),
34
+ position: z.object({
35
+ x: z.number(),
36
+ y: z.number(),
37
+ }),
38
+ data: z.any().optional().default({}),
39
+ deletable: z.boolean().optional(),
40
+ });
41
+
42
+ const ConnectionSchema = z.object({
43
+ id: z.string().min(1),
44
+ sourceNodeId: z.string().min(1),
45
+ targetNodeId: z.string().min(1),
46
+ sourcePinId: z.string().min(1),
47
+ targetPinId: z.string().min(1),
48
+ });
49
+
50
+ const GraphSchema = z.object({
51
+ nodes: z.array(NodeDataSchema),
52
+ connections: z.array(ConnectionSchema),
53
+ variables: z.array(z.object({
54
+ id: z.string().min(1),
55
+ name: z.string().min(1),
56
+ type: z.enum(['string', 'number', 'boolean', 'array', 'object']),
57
+ value: z.any(),
58
+ })).optional().default([]),
59
+ });
60
+
61
+ function validateNodeConfig(nodeConfig) {
62
+ try {
63
+ return {
64
+ success: true,
65
+ data: NodeConfigSchema.parse(nodeConfig),
66
+ };
67
+ } catch (error) {
68
+ return {
69
+ success: false,
70
+ error: error.issues || error.errors || [{ message: error.message }],
71
+ };
72
+ }
73
+ }
74
+
75
+ function validateNodeData(nodeData) {
76
+ try {
77
+ return {
78
+ success: true,
79
+ data: NodeDataSchema.parse(nodeData),
80
+ };
81
+ } catch (error) {
82
+ return {
83
+ success: false,
84
+ error: error.issues || error.errors || [{ message: error.message }],
85
+ };
86
+ }
87
+ }
88
+
89
+ function validateGraph(graph) {
90
+ try {
91
+ return {
92
+ success: true,
93
+ data: GraphSchema.parse(graph),
94
+ };
95
+ } catch (error) {
96
+ return {
97
+ success: false,
98
+ error: error.issues || error.errors || [{ message: error.message }],
99
+ };
100
+ }
101
+ }
102
+
103
+ module.exports = {
104
+ PinSchema,
105
+ NodeConfigSchema,
106
+ NodeDataSchema,
107
+ ConnectionSchema,
108
+ GraphSchema,
109
+ validateNodeConfig,
110
+ validateNodeData,
111
+ validateGraph,
112
+ };