фикс#44
Conversation
|
Caution Review failedThe pull request is closed. 📝 WalkthroughWalkthroughВыпуск версии 1.23.0 с централизованной системой подстановки переменных в ядре графа, обновленными определениями действий (HTTP-запрос, отправка сообщений, строковый литерал), упрощением логики вычисления входов на фронтенде и улучшением обработки клавиатурных команд копирования и удаления узлов в визуальном редакторе. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45–60 minutes Области повышенного внимания:
Poem
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (12)
Tip 📝 Customizable high-level summaries are now available in beta!You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.
Example instruction:
Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Руководство для ревьюераРефакторинг обработки плейсхолдеров переменных для универсального использования во всех нодах, расширение возможностей ноды HTTP-запроса, улучшение взаимодействия с клавиатурой в визуальном редакторе и обновление версионирования/чейнджлога для релиза 1.23.0. Диаграмма последовательности для универсального разрешения плейсхолдеров переменных в resolvePinValuesequenceDiagram
participant NodeInstance
participant GraphExecutionEngine
participant VariablePins
NodeInstance->>GraphExecutionEngine: resolvePinValue(node, pinId, defaultValue)
alt pin is connected to another node
GraphExecutionEngine->>GraphExecutionEngine: evaluateOutputPin(sourceNode, sourcePinId, defaultValue)
GraphExecutionEngine-->>NodeInstance: valueFromConnection
else pin is local data field
GraphExecutionEngine->>GraphExecutionEngine: read node.data[pinId] or defaultValue
GraphExecutionEngine->>GraphExecutionEngine: check if value is string and contains {
alt value contains placeholders
GraphExecutionEngine->>GraphExecutionEngine: _replaceVariablesInString(text, node)
loop for each {varName}
GraphExecutionEngine->>VariablePins: resolvePinValue(node, var_varName, "")
VariablePins-->>GraphExecutionEngine: varValue
GraphExecutionEngine->>GraphExecutionEngine: replace {varName} with varValue in text
end
GraphExecutionEngine-->>NodeInstance: valueWithReplacedVariables
else no placeholders
GraphExecutionEngine-->>NodeInstance: originalValue
end
end
Диаграмма последовательности для ноды HTTP-запроса с query-параметрами и заголовкамиsequenceDiagram
participant GraphExecutionEngine
participant HttpRequestActionNode
participant ExternalHttpService
GraphExecutionEngine->>HttpRequestActionNode: execute(node, context, helpers)
activate HttpRequestActionNode
HttpRequestActionNode->>GraphExecutionEngine: resolvePinValue(node, url, "")
GraphExecutionEngine-->>HttpRequestActionNode: url
HttpRequestActionNode->>GraphExecutionEngine: resolvePinValue(node, method, node.data.method or GET)
GraphExecutionEngine-->>HttpRequestActionNode: method
HttpRequestActionNode->>GraphExecutionEngine: resolvePinValue(node, queryParams, null)
GraphExecutionEngine-->>HttpRequestActionNode: queryParamsInput
HttpRequestActionNode->>GraphExecutionEngine: resolvePinValue(node, headers, null)
GraphExecutionEngine-->>HttpRequestActionNode: headersInput
HttpRequestActionNode->>GraphExecutionEngine: resolvePinValue(node, body, "")
GraphExecutionEngine-->>HttpRequestActionNode: body
HttpRequestActionNode->>GraphExecutionEngine: resolvePinValue(node, timeout, 5000)
GraphExecutionEngine-->>HttpRequestActionNode: timeout
alt queryParamsInput exists and is valid
HttpRequestActionNode->>HttpRequestActionNode: parse queryParamsInput to params
HttpRequestActionNode->>HttpRequestActionNode: append params to url as ?key=value
else invalid or absent
HttpRequestActionNode->>HttpRequestActionNode: keep original url
end
alt headersInput exists and is valid
HttpRequestActionNode->>HttpRequestActionNode: parse headersInput to headers object
else invalid or absent
HttpRequestActionNode->>HttpRequestActionNode: use empty headers
end
HttpRequestActionNode->>ExternalHttpService: HTTP method url with headers, body, timeout
ExternalHttpService-->>HttpRequestActionNode: HTTP response
HttpRequestActionNode-->>GraphExecutionEngine: store response in outputs
deactivate HttpRequestActionNode
Обновлённая диаграмма классов для обработки переменных в NodeDefinition и GraphExecutionEngineclassDiagram
class NodeDefinition {
+computeInputs(data, context)
+getInputs(data, context)
}
class VariableExtractor {
+extractVariables(text) string[]
}
class GraphExecutionEngine {
+resolvePinValue(node, pinId, defaultValue) any
+evaluateOutputPin(node, pinId, defaultValue) any
-_replaceVariablesInString(text, node) string
-activeGraph
}
class HttpRequestActionNode {
+execute(node, context, helpers) Promise
}
class SendMessageActionNode {
+execute(node, context, helpers) Promise
}
class StringLiteralNode {
+evaluate(node, pinId, context, helpers) Promise
}
VariableExtractor <.. NodeDefinition : uses for
GraphExecutionEngine <.. VariableExtractor : uses for
GraphExecutionEngine <.. HttpRequestActionNode : helper resolvePinValue
GraphExecutionEngine <.. SendMessageActionNode : helper resolvePinValue
GraphExecutionEngine <.. StringLiteralNode : helper resolvePinValue
NodeDefinition <|-- HttpRequestActionNode
NodeDefinition <|-- SendMessageActionNode
NodeDefinition <|-- StringLiteralNode
Изменения на уровне файлов
Подсказки и командыВзаимодействие с Sourcery
Настройка опыта работыЗайдите в свою панель управления, чтобы:
Получение помощи
Original review guide in EnglishReviewer's GuideRefactors variable placeholder handling to be generic across nodes, enhances HTTP request node capabilities, improves visual editor keyboard interactions, and updates versioning/changelog for the 1.23.0 release. Sequence diagram for generic variable placeholder resolution in resolvePinValuesequenceDiagram
participant NodeInstance
participant GraphExecutionEngine
participant VariablePins
NodeInstance->>GraphExecutionEngine: resolvePinValue(node, pinId, defaultValue)
alt pin is connected to another node
GraphExecutionEngine->>GraphExecutionEngine: evaluateOutputPin(sourceNode, sourcePinId, defaultValue)
GraphExecutionEngine-->>NodeInstance: valueFromConnection
else pin is local data field
GraphExecutionEngine->>GraphExecutionEngine: read node.data[pinId] or defaultValue
GraphExecutionEngine->>GraphExecutionEngine: check if value is string and contains {
alt value contains placeholders
GraphExecutionEngine->>GraphExecutionEngine: _replaceVariablesInString(text, node)
loop for each {varName}
GraphExecutionEngine->>VariablePins: resolvePinValue(node, var_varName, "")
VariablePins-->>GraphExecutionEngine: varValue
GraphExecutionEngine->>GraphExecutionEngine: replace {varName} with varValue in text
end
GraphExecutionEngine-->>NodeInstance: valueWithReplacedVariables
else no placeholders
GraphExecutionEngine-->>NodeInstance: originalValue
end
end
Sequence diagram for HTTP request node with query params and headerssequenceDiagram
participant GraphExecutionEngine
participant HttpRequestActionNode
participant ExternalHttpService
GraphExecutionEngine->>HttpRequestActionNode: execute(node, context, helpers)
activate HttpRequestActionNode
HttpRequestActionNode->>GraphExecutionEngine: resolvePinValue(node, url, "")
GraphExecutionEngine-->>HttpRequestActionNode: url
HttpRequestActionNode->>GraphExecutionEngine: resolvePinValue(node, method, node.data.method or GET)
GraphExecutionEngine-->>HttpRequestActionNode: method
HttpRequestActionNode->>GraphExecutionEngine: resolvePinValue(node, queryParams, null)
GraphExecutionEngine-->>HttpRequestActionNode: queryParamsInput
HttpRequestActionNode->>GraphExecutionEngine: resolvePinValue(node, headers, null)
GraphExecutionEngine-->>HttpRequestActionNode: headersInput
HttpRequestActionNode->>GraphExecutionEngine: resolvePinValue(node, body, "")
GraphExecutionEngine-->>HttpRequestActionNode: body
HttpRequestActionNode->>GraphExecutionEngine: resolvePinValue(node, timeout, 5000)
GraphExecutionEngine-->>HttpRequestActionNode: timeout
alt queryParamsInput exists and is valid
HttpRequestActionNode->>HttpRequestActionNode: parse queryParamsInput to params
HttpRequestActionNode->>HttpRequestActionNode: append params to url as ?key=value
else invalid or absent
HttpRequestActionNode->>HttpRequestActionNode: keep original url
end
alt headersInput exists and is valid
HttpRequestActionNode->>HttpRequestActionNode: parse headersInput to headers object
else invalid or absent
HttpRequestActionNode->>HttpRequestActionNode: use empty headers
end
HttpRequestActionNode->>ExternalHttpService: HTTP method url with headers, body, timeout
ExternalHttpService-->>HttpRequestActionNode: HTTP response
HttpRequestActionNode-->>GraphExecutionEngine: store response in outputs
deactivate HttpRequestActionNode
Updated class diagram for NodeDefinition and GraphExecutionEngine variable handlingclassDiagram
class NodeDefinition {
+computeInputs(data, context)
+getInputs(data, context)
}
class VariableExtractor {
+extractVariables(text) string[]
}
class GraphExecutionEngine {
+resolvePinValue(node, pinId, defaultValue) any
+evaluateOutputPin(node, pinId, defaultValue) any
-_replaceVariablesInString(text, node) string
-activeGraph
}
class HttpRequestActionNode {
+execute(node, context, helpers) Promise
}
class SendMessageActionNode {
+execute(node, context, helpers) Promise
}
class StringLiteralNode {
+evaluate(node, pinId, context, helpers) Promise
}
VariableExtractor <.. NodeDefinition : uses for
GraphExecutionEngine <.. VariableExtractor : uses for
GraphExecutionEngine <.. HttpRequestActionNode : helper resolvePinValue
GraphExecutionEngine <.. SendMessageActionNode : helper resolvePinValue
GraphExecutionEngine <.. StringLiteralNode : helper resolvePinValue
NodeDefinition <|-- HttpRequestActionNode
NodeDefinition <|-- SendMessageActionNode
NodeDefinition <|-- StringLiteralNode
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Привет! Я посмотрел твои изменения — вот несколько замечаний:
- В
NodeDefinition.getInputsты изменяешь массив, возвращаемый изcomputeInputs, добавляя в него динамические var‑пины черезpush. Если какая‑то нода переиспользует общий константный массив дляcomputeInputs, это приведёт к «протеканию» пинов между инстансами. Подумай о том, чтобы клонировать массив перед модификацией (inputs = [...this.computeInputs(...)]) или явно зафиксировать контракт, чтоcomputeInputsвсегда должен возвращать новый массив. - Новое автоматическое развёртывание переменных в
resolvePinValue/_replaceVariablesInStringможет зациклиться, если сам пинvar_...содержит плейсхолдеры{varName}(например, значение дляvar_xсодержит{x}), потому чтоresolvePinValueснова вызывается для той же логической переменной. Безопаснее было бы отключать замену для пиновvar_или передавать флаг, запрещающий повторный вход в подстановку. - Обобщённое извлечение переменных в
NodeDefinition.getInputsтеперь добавляет пиныvar_*для любого строкового поля вdata. Это может затронуть ноды, которые концептуально не поддерживают шаблонные переменные. Рассмотри вариант сделать это поведение опциональным через флаг в определении ноды, а не применять его глобально ко всем нодам.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `NodeDefinition.getInputs`, you mutate the array returned from `computeInputs` by pushing dynamic var pins; if any node reuses a shared constant array for `computeInputs` this will leak pins across instances—consider cloning (`inputs = [...this.computeInputs(...)]`) before mutation or clearly enforcing that `computeInputs` must always return a fresh array.
- The new automatic variable expansion in `resolvePinValue`/`_replaceVariablesInString` can recurse indefinitely if a `var_...` pin itself contains `{varName}` placeholders (e.g. `value` for `var_x` contains `{x}`) because `resolvePinValue` is called again on the same logical variable; it would be safer to short‑circuit replacement for `var_` pins or pass a flag to avoid re‑entering substitution.
- The generic variable extraction in `NodeDefinition.getInputs` now adds `var_*` pins for any string field in `data`; this may affect nodes that don’t conceptually support template variables—consider making this behavior opt‑in via a flag on the node definition instead of applying it to all nodes globally.
## Individual Comments
### Comment 1
<location> `frontend/src/components/visual-editor/core/registry/NodeDefinition.js:58-65` </location>
<code_context>
getInputs(data, context = {}) {
+ let inputs = [];
+
if (this.computeInputs) {
- return this.computeInputs(data, context);
+ inputs = this.computeInputs(data, context);
}
- return [];
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Guard against computeInputs returning a falsy or non-array value.
Since `inputs` is used with `.find`/`.push`, a non-array or `undefined` return from `computeInputs` will cause a runtime error. Consider defaulting to an empty array (e.g. `inputs = this.computeInputs(data, context) || [];`) and optionally validating that the result is actually an array to guard against misbehaving implementations.
```suggestion
getInputs(data, context = {}) {
let inputs = [];
if (this.computeInputs) {
const computedInputs = this.computeInputs(data, context);
inputs = Array.isArray(computedInputs) ? computedInputs : [];
}
const allVars = new Set();
```
</issue_to_address>
### Comment 2
<location> `backend/src/core/nodes/actions/http_request.js:25-29` </location>
<code_context>
+ ? JSON.parse(queryParamsInput)
+ : queryParamsInput;
+
+ const urlObj = new URL(url);
+ Object.entries(params).forEach(([key, value]) => {
+ urlObj.searchParams.append(key, value);
+ });
+ url = urlObj.toString();
+ } catch (e) {
+ console.error('[HTTP Request] Ошибка обработки query params:', e);
</code_context>
<issue_to_address>
**issue:** Using `new URL(url)` will throw for relative URLs; consider a fallback or base.
Since `queryParams` are now parsed unconditionally, any relative `url` (e.g. `/api/users`) will cause `new URL(url)` to throw and the request to drop into the `catch`, silently skipping query param handling. To make this more robust, either support a configurable base (e.g. `new URL(url, context.baseUrl)`) or detect relative URLs and append query parameters via string/`URLSearchParams` without `new URL` so relative paths don’t fail unexpectedly.
</issue_to_address>
### Comment 3
<location> `CHANGELOG.md:19` </location>
<code_context>
+
+* дебаг режим для графов ([ffc910b](https://github.com/blockmineJS/blockmine/commit/ffc910b772bccf9b64ca828eb55debddb11715d7))
+* добавлен ai помощник в blockmine ide ([d7c5f7e](https://github.com/blockmineJS/blockmine/commit/d7c5f7e555beacf614b6cdc94706339880aac55c))
+* добавлен diff для просмотра изменений кода от ии ([d0159f0](https://github.com/blockmineJS/blockmine/commit/d0159f0884863ec10136f4bf32ea7daf0702d476))
+* новая вкладка - прокси ([3094b8b](https://github.com/blockmineJS/blockmine/commit/3094b8b5f1b9a59dd6494ff54c721f1e720b28f6))
+* новая ивент нода - При запуске бота ([5189a02](https://github.com/blockmineJS/blockmine/commit/5189a024c5e57fe8cb28f557b946247644367491))
</code_context>
<issue_to_address>
**issue (typo):** Исправить регистр аббревиатуры «ИИ» для единообразия.
Рекомендуется заменить «ии» на «ИИ», чтобы не выглядело как опечатка и соответствовало написанию аббревиатуры в остальных пунктах.
```suggestion
* добавлен diff для просмотра изменений кода от ИИ ([d0159f0](https://github.com/blockmineJS/blockmine/commit/d0159f0884863ec10136f4bf32ea7daf0702d476))
```
</issue_to_address>
### Comment 4
<location> `CHANGELOG.md:25-26` </location>
<code_context>
+* новый ide редактор ([2d7b302](https://github.com/blockmineJS/blockmine/commit/2d7b3026882b56a226760ba38c52cba0815a0720))
+* подсветки при соединении нод ([dd06cdd](https://github.com/blockmineJS/blockmine/commit/dd06cdd4fca871713688382c9b73d0eaa4d1b8bd))
+* теперь за бота можно ходить прямо в браузере! ([42f9257](https://github.com/blockmineJS/blockmine/commit/42f9257ee3ce166fda648e9a2ca6947c630a21e2))
+* фиксы и для нод копирование вставка графов ([aa1308d](https://github.com/blockmineJS/blockmine/commit/aa1308d19122ebc762ec1ebd3f523e12c2fb5aa2))
+
## [1.22.0](https://github.com/blockmineJS/blockmine/compare/v1.21.0...v1.22.0) (2025-11-16)
</code_context>
<issue_to_address>
**issue (typo):** Уточнить формулировку: сейчас фраза выглядит обрезанной и грамматически невыверенной.
Конкретно, фраза «фиксы и для нод копирование вставка графов» тяжело читается: нет союза или разделителя между «копирование» и «вставка», структура неочевидна. Лучше переформулировать, например: «фиксы копирования и вставки графов для нод» или «фиксы копирования/вставки графов и для нод», чтобы смысл был однозначным.
```suggestion
* теперь за бота можно ходить прямо в браузере! ([42f9257](https://github.com/blockmineJS/blockmine/commit/42f9257ee3ce166fda648e9a2ca6947c630a21e2))
* фиксы копирования и вставки графов для нод ([aa1308d](https://github.com/blockmineJS/blockmine/commit/aa1308d19122ebc762ec1ebd3f523e12c2fb5aa2))
```
</issue_to_address>
### Comment 5
<location> `backend/src/core/nodes/data/string_literal.js:14-15` </location>
<code_context>
const text = String(await resolvePinValue(node, 'value', ''));
return text;
</code_context>
<issue_to_address>
**suggestion (code-quality):** Inline variable that is immediately returned ([`inline-immediately-returned-variable`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/inline-immediately-returned-variable))
```suggestion
return String(await resolvePinValue(node, 'value', ''));
```
<br/><details><summary>Explanation</summary>Something that we often see in people's code is assigning to a result variable
and then immediately returning it.
Returning the result directly shortens the code and removes an unnecessary
variable, reducing the mental load of reading the function.
Where intermediate variables can be useful is if they then get used as a
parameter or a condition, and the name can act like a comment on what the
variable represents. In the case where you're returning it from a function, the
function name is there to tell you what the result is, so the variable name
is unnecessary.
</details>
</issue_to_address>Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Original comment in English
Hey there - I've reviewed your changes - here's some feedback:
- In
NodeDefinition.getInputs, you mutate the array returned fromcomputeInputsby pushing dynamic var pins; if any node reuses a shared constant array forcomputeInputsthis will leak pins across instances—consider cloning (inputs = [...this.computeInputs(...)]) before mutation or clearly enforcing thatcomputeInputsmust always return a fresh array. - The new automatic variable expansion in
resolvePinValue/_replaceVariablesInStringcan recurse indefinitely if avar_...pin itself contains{varName}placeholders (e.g.valueforvar_xcontains{x}) becauseresolvePinValueis called again on the same logical variable; it would be safer to short‑circuit replacement forvar_pins or pass a flag to avoid re‑entering substitution. - The generic variable extraction in
NodeDefinition.getInputsnow addsvar_*pins for any string field indata; this may affect nodes that don’t conceptually support template variables—consider making this behavior opt‑in via a flag on the node definition instead of applying it to all nodes globally.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `NodeDefinition.getInputs`, you mutate the array returned from `computeInputs` by pushing dynamic var pins; if any node reuses a shared constant array for `computeInputs` this will leak pins across instances—consider cloning (`inputs = [...this.computeInputs(...)]`) before mutation or clearly enforcing that `computeInputs` must always return a fresh array.
- The new automatic variable expansion in `resolvePinValue`/`_replaceVariablesInString` can recurse indefinitely if a `var_...` pin itself contains `{varName}` placeholders (e.g. `value` for `var_x` contains `{x}`) because `resolvePinValue` is called again on the same logical variable; it would be safer to short‑circuit replacement for `var_` pins or pass a flag to avoid re‑entering substitution.
- The generic variable extraction in `NodeDefinition.getInputs` now adds `var_*` pins for any string field in `data`; this may affect nodes that don’t conceptually support template variables—consider making this behavior opt‑in via a flag on the node definition instead of applying it to all nodes globally.
## Individual Comments
### Comment 1
<location> `frontend/src/components/visual-editor/core/registry/NodeDefinition.js:58-65` </location>
<code_context>
getInputs(data, context = {}) {
+ let inputs = [];
+
if (this.computeInputs) {
- return this.computeInputs(data, context);
+ inputs = this.computeInputs(data, context);
}
- return [];
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Guard against computeInputs returning a falsy or non-array value.
Since `inputs` is used with `.find`/`.push`, a non-array or `undefined` return from `computeInputs` will cause a runtime error. Consider defaulting to an empty array (e.g. `inputs = this.computeInputs(data, context) || [];`) and optionally validating that the result is actually an array to guard against misbehaving implementations.
```suggestion
getInputs(data, context = {}) {
let inputs = [];
if (this.computeInputs) {
const computedInputs = this.computeInputs(data, context);
inputs = Array.isArray(computedInputs) ? computedInputs : [];
}
const allVars = new Set();
```
</issue_to_address>
### Comment 2
<location> `backend/src/core/nodes/actions/http_request.js:25-29` </location>
<code_context>
+ ? JSON.parse(queryParamsInput)
+ : queryParamsInput;
+
+ const urlObj = new URL(url);
+ Object.entries(params).forEach(([key, value]) => {
+ urlObj.searchParams.append(key, value);
+ });
+ url = urlObj.toString();
+ } catch (e) {
+ console.error('[HTTP Request] Ошибка обработки query params:', e);
</code_context>
<issue_to_address>
**issue:** Using `new URL(url)` will throw for relative URLs; consider a fallback or base.
Since `queryParams` are now parsed unconditionally, any relative `url` (e.g. `/api/users`) will cause `new URL(url)` to throw and the request to drop into the `catch`, silently skipping query param handling. To make this more robust, either support a configurable base (e.g. `new URL(url, context.baseUrl)`) or detect relative URLs and append query parameters via string/`URLSearchParams` without `new URL` so relative paths don’t fail unexpectedly.
</issue_to_address>
### Comment 3
<location> `CHANGELOG.md:19` </location>
<code_context>
+
+* дебаг режим для графов ([ffc910b](https://github.com/blockmineJS/blockmine/commit/ffc910b772bccf9b64ca828eb55debddb11715d7))
+* добавлен ai помощник в blockmine ide ([d7c5f7e](https://github.com/blockmineJS/blockmine/commit/d7c5f7e555beacf614b6cdc94706339880aac55c))
+* добавлен diff для просмотра изменений кода от ии ([d0159f0](https://github.com/blockmineJS/blockmine/commit/d0159f0884863ec10136f4bf32ea7daf0702d476))
+* новая вкладка - прокси ([3094b8b](https://github.com/blockmineJS/blockmine/commit/3094b8b5f1b9a59dd6494ff54c721f1e720b28f6))
+* новая ивент нода - При запуске бота ([5189a02](https://github.com/blockmineJS/blockmine/commit/5189a024c5e57fe8cb28f557b946247644367491))
</code_context>
<issue_to_address>
**issue (typo):** Исправить регистр аббревиатуры «ИИ» для единообразия.
Рекомендуется заменить «ии» на «ИИ», чтобы не выглядело как опечатка и соответствовало написанию аббревиатуры в остальных пунктах.
```suggestion
* добавлен diff для просмотра изменений кода от ИИ ([d0159f0](https://github.com/blockmineJS/blockmine/commit/d0159f0884863ec10136f4bf32ea7daf0702d476))
```
</issue_to_address>
### Comment 4
<location> `CHANGELOG.md:25-26` </location>
<code_context>
+* новый ide редактор ([2d7b302](https://github.com/blockmineJS/blockmine/commit/2d7b3026882b56a226760ba38c52cba0815a0720))
+* подсветки при соединении нод ([dd06cdd](https://github.com/blockmineJS/blockmine/commit/dd06cdd4fca871713688382c9b73d0eaa4d1b8bd))
+* теперь за бота можно ходить прямо в браузере! ([42f9257](https://github.com/blockmineJS/blockmine/commit/42f9257ee3ce166fda648e9a2ca6947c630a21e2))
+* фиксы и для нод копирование вставка графов ([aa1308d](https://github.com/blockmineJS/blockmine/commit/aa1308d19122ebc762ec1ebd3f523e12c2fb5aa2))
+
## [1.22.0](https://github.com/blockmineJS/blockmine/compare/v1.21.0...v1.22.0) (2025-11-16)
</code_context>
<issue_to_address>
**issue (typo):** Уточнить формулировку: сейчас фраза выглядит обрезанной и грамматически невыверенной.
Конкретно, фраза «фиксы и для нод копирование вставка графов» тяжело читается: нет союза или разделителя между «копирование» и «вставка», структура неочевидна. Лучше переформулировать, например: «фиксы копирования и вставки графов для нод» или «фиксы копирования/вставки графов и для нод», чтобы смысл был однозначным.
```suggestion
* теперь за бота можно ходить прямо в браузере! ([42f9257](https://github.com/blockmineJS/blockmine/commit/42f9257ee3ce166fda648e9a2ca6947c630a21e2))
* фиксы копирования и вставки графов для нод ([aa1308d](https://github.com/blockmineJS/blockmine/commit/aa1308d19122ebc762ec1ebd3f523e12c2fb5aa2))
```
</issue_to_address>
### Comment 5
<location> `backend/src/core/nodes/data/string_literal.js:14-15` </location>
<code_context>
const text = String(await resolvePinValue(node, 'value', ''));
return text;
</code_context>
<issue_to_address>
**suggestion (code-quality):** Inline variable that is immediately returned ([`inline-immediately-returned-variable`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/inline-immediately-returned-variable))
```suggestion
return String(await resolvePinValue(node, 'value', ''));
```
<br/><details><summary>Explanation</summary>Something that we often see in people's code is assigning to a result variable
and then immediately returning it.
Returning the result directly shortens the code and removes an unnecessary
variable, reducing the mental load of reading the function.
Where intermediate variables can be useful is if they then get used as a
parameter or a condition, and the name can act like a comment on what the
variable represents. In the case where you're returning it from a function, the
function name is there to tell you what the result is, so the variable name
is unnecessary.
</details>
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| getInputs(data, context = {}) { | ||
| let inputs = []; | ||
|
|
||
| if (this.computeInputs) { | ||
| return this.computeInputs(data, context); | ||
| inputs = this.computeInputs(data, context); | ||
| } | ||
| return []; | ||
|
|
||
| const allVars = new Set(); |
There was a problem hiding this comment.
suggestion (bug_risk): Защититься от ситуации, когда computeInputs возвращает ложное (falsy) или не‑массивное значение.
Так как inputs используется с .find/.push, возврат не массива или undefined из computeInputs приведёт к ошибке во время выполнения. Рассмотри вариант по умолчанию использовать пустой массив (например, inputs = this.computeInputs(data, context) || [];) и при необходимости дополнительно проверить, что результат действительно является массивом, чтобы защититься от некорректных реализаций.
| getInputs(data, context = {}) { | |
| let inputs = []; | |
| if (this.computeInputs) { | |
| return this.computeInputs(data, context); | |
| inputs = this.computeInputs(data, context); | |
| } | |
| return []; | |
| const allVars = new Set(); | |
| getInputs(data, context = {}) { | |
| let inputs = []; | |
| if (this.computeInputs) { | |
| const computedInputs = this.computeInputs(data, context); | |
| inputs = Array.isArray(computedInputs) ? computedInputs : []; | |
| } | |
| const allVars = new Set(); |
Original comment in English
suggestion (bug_risk): Guard against computeInputs returning a falsy or non-array value.
Since inputs is used with .find/.push, a non-array or undefined return from computeInputs will cause a runtime error. Consider defaulting to an empty array (e.g. inputs = this.computeInputs(data, context) || [];) and optionally validating that the result is actually an array to guard against misbehaving implementations.
| getInputs(data, context = {}) { | |
| let inputs = []; | |
| if (this.computeInputs) { | |
| return this.computeInputs(data, context); | |
| inputs = this.computeInputs(data, context); | |
| } | |
| return []; | |
| const allVars = new Set(); | |
| getInputs(data, context = {}) { | |
| let inputs = []; | |
| if (this.computeInputs) { | |
| const computedInputs = this.computeInputs(data, context); | |
| inputs = Array.isArray(computedInputs) ? computedInputs : []; | |
| } | |
| const allVars = new Set(); |
| const urlObj = new URL(url); | ||
| Object.entries(params).forEach(([key, value]) => { | ||
| urlObj.searchParams.append(key, value); | ||
| }); | ||
| url = urlObj.toString(); |
There was a problem hiding this comment.
issue: Использование new URL(url) приведёт к ошибке для относительных URL; стоит предусмотреть запасной вариант или базовый URL.
Так как queryParams теперь парсятся безусловно, любой относительный url (например, /api/users) вызовет исключение в new URL(url) и переведёт запрос в ветку catch, из‑за чего обработка query‑параметров будет тихо пропущена. Чтобы сделать это поведение более надёжным, можно либо поддержать настраиваемый базовый адрес (например, new URL(url, context.baseUrl)), либо определять относительные URL и добавлять query‑параметры через строку/URLSearchParams без new URL, чтобы относительные пути не ломались неожиданно.
Original comment in English
issue: Using new URL(url) will throw for relative URLs; consider a fallback or base.
Since queryParams are now parsed unconditionally, any relative url (e.g. /api/users) will cause new URL(url) to throw and the request to drop into the catch, silently skipping query param handling. To make this more robust, either support a configurable base (e.g. new URL(url, context.baseUrl)) or detect relative URLs and append query parameters via string/URLSearchParams without new URL so relative paths don’t fail unexpectedly.
|
|
||
| * дебаг режим для графов ([ffc910b](https://github.com/blockmineJS/blockmine/commit/ffc910b772bccf9b64ca828eb55debddb11715d7)) | ||
| * добавлен ai помощник в blockmine ide ([d7c5f7e](https://github.com/blockmineJS/blockmine/commit/d7c5f7e555beacf614b6cdc94706339880aac55c)) | ||
| * добавлен diff для просмотра изменений кода от ии ([d0159f0](https://github.com/blockmineJS/blockmine/commit/d0159f0884863ec10136f4bf32ea7daf0702d476)) |
There was a problem hiding this comment.
issue (typo): Исправить регистр аббревиатуры «ИИ» для единообразия.
Рекомендуется заменить «ии» на «ИИ», чтобы не выглядело как опечатка и соответствовало написанию аббревиатуры в остальных пунктах.
| * добавлен diff для просмотра изменений кода от ии ([d0159f0](https://github.com/blockmineJS/blockmine/commit/d0159f0884863ec10136f4bf32ea7daf0702d476)) | |
| * добавлен diff для просмотра изменений кода от ИИ ([d0159f0](https://github.com/blockmineJS/blockmine/commit/d0159f0884863ec10136f4bf32ea7daf0702d476)) |
Original comment in English
issue (typo): Исправить регистр аббревиатуры «ИИ» для единообразия.
Рекомендуется заменить «ии» на «ИИ», чтобы не выглядело как опечатка и соответствовало написанию аббревиатуры в остальных пунктах.
| * добавлен diff для просмотра изменений кода от ии ([d0159f0](https://github.com/blockmineJS/blockmine/commit/d0159f0884863ec10136f4bf32ea7daf0702d476)) | |
| * добавлен diff для просмотра изменений кода от ИИ ([d0159f0](https://github.com/blockmineJS/blockmine/commit/d0159f0884863ec10136f4bf32ea7daf0702d476)) |
| * теперь за бота можно ходить прямо в браузере! ([42f9257](https://github.com/blockmineJS/blockmine/commit/42f9257ee3ce166fda648e9a2ca6947c630a21e2)) | ||
| * фиксы и для нод копирование вставка графов ([aa1308d](https://github.com/blockmineJS/blockmine/commit/aa1308d19122ebc762ec1ebd3f523e12c2fb5aa2)) |
There was a problem hiding this comment.
issue (typo): Уточнить формулировку: сейчас фраза выглядит обрезанной и грамматически невыверенной.
Конкретно, фраза «фиксы и для нод копирование вставка графов» тяжело читается: нет союза или разделителя между «копирование» и «вставка», структура неочевидна. Лучше переформулировать, например: «фиксы копирования и вставки графов для нод» или «фиксы копирования/вставки графов и для нод», чтобы смысл был однозначным.
| * теперь за бота можно ходить прямо в браузере! ([42f9257](https://github.com/blockmineJS/blockmine/commit/42f9257ee3ce166fda648e9a2ca6947c630a21e2)) | |
| * фиксы и для нод копирование вставка графов ([aa1308d](https://github.com/blockmineJS/blockmine/commit/aa1308d19122ebc762ec1ebd3f523e12c2fb5aa2)) | |
| * теперь за бота можно ходить прямо в браузере! ([42f9257](https://github.com/blockmineJS/blockmine/commit/42f9257ee3ce166fda648e9a2ca6947c630a21e2)) | |
| * фиксы копирования и вставки графов для нод ([aa1308d](https://github.com/blockmineJS/blockmine/commit/aa1308d19122ebc762ec1ebd3f523e12c2fb5aa2)) |
Original comment in English
issue (typo): Уточнить формулировку: сейчас фраза выглядит обрезанной и грамматически невыверенной.
Конкретно, фраза «фиксы и для нод копирование вставка графов» тяжело читается: нет союза или разделителя между «копирование» и «вставка», структура неочевидна. Лучше переформулировать, например: «фиксы копирования и вставки графов для нод» или «фиксы копирования/вставки графов и для нод», чтобы смысл был однозначным.
| * теперь за бота можно ходить прямо в браузере! ([42f9257](https://github.com/blockmineJS/blockmine/commit/42f9257ee3ce166fda648e9a2ca6947c630a21e2)) | |
| * фиксы и для нод копирование вставка графов ([aa1308d](https://github.com/blockmineJS/blockmine/commit/aa1308d19122ebc762ec1ebd3f523e12c2fb5aa2)) | |
| * теперь за бота можно ходить прямо в браузере! ([42f9257](https://github.com/blockmineJS/blockmine/commit/42f9257ee3ce166fda648e9a2ca6947c630a21e2)) | |
| * фиксы копирования и вставки графов для нод ([aa1308d](https://github.com/blockmineJS/blockmine/commit/aa1308d19122ebc762ec1ebd3f523e12c2fb5aa2)) |
| const text = String(await resolvePinValue(node, 'value', '')); | ||
| return text; |
There was a problem hiding this comment.
suggestion (code-quality): Инлайнить переменную, которая сразу же возвращается (inline-immediately-returned-variable)
| const text = String(await resolvePinValue(node, 'value', '')); | |
| return text; | |
| return String(await resolvePinValue(node, 'value', '')); | |
Explanation
Something that we often see in people's code is assigning to a result variableand then immediately returning it.
Returning the result directly shortens the code and removes an unnecessary
variable, reducing the mental load of reading the function.
Where intermediate variables can be useful is if they then get used as a
parameter or a condition, and the name can act like a comment on what the
variable represents. In the case where you're returning it from a function, the
function name is there to tell you what the result is, so the variable name
is unnecessary.
Original comment in English
suggestion (code-quality): Inline variable that is immediately returned (inline-immediately-returned-variable)
| const text = String(await resolvePinValue(node, 'value', '')); | |
| return text; | |
| return String(await resolvePinValue(node, 'value', '')); | |
Explanation
Something that we often see in people's code is assigning to a result variableand then immediately returning it.
Returning the result directly shortens the code and removes an unnecessary
variable, reducing the mental load of reading the function.
Where intermediate variables can be useful is if they then get used as a
parameter or a condition, and the name can act like a comment on what the
variable represents. In the case where you're returning it from a function, the
function name is there to tell you what the result is, so the variable name
is unnecessary.
Summary by Sourcery
Унификация обработки плейсхолдеров переменных между нодами, расширение конфигурации HTTP-запросов, улучшение работы с клавиатурой в визуальном редакторе и повышение версии проекта до 1.23.0 с обновлённым changelog.
New Features:
{varName}из данных ноды для автоматической генерации соответствующих входных пинов-джокеров (wildcard).Bug Fixes:
Enhancements:
{varName}.Build:
Documentation:
Original summary in English
Summary by Sourcery
Unify variable placeholder handling across nodes, enhance HTTP request configuration, improve visual editor keyboard interactions, and bump the project version to 1.23.0 with updated changelog.
New Features:
Bug Fixes:
Enhancements:
Build:
Documentation:
Summary by CodeRabbit
Выпуск 1.23.0
Новые возможности
Исправления ошибок
✏️ Tip: You can customize this high-level summary in your review settings.