onescript

n8n community node that executes OneScript

Package Information

Released: this month
Downloads: 0 weekly / 0 monthly
Latest Version: 0.1.2
Author: Иван Карло

Documentation

n8n-nodes-onescript

Community-нода n8n, которая выполняет код OneScript через CLI oscript. Бинарник должен быть в PATH того же процесса, что и n8n. Пакет его не содержит.

Нода программная (execute), API community-нод n8nNodesApiVersion: 1. Сборка: npm run build (n8n-node build).

Установка oscript

Нужен OneScript 2.x (платформа .NET 8). JSON читается и пишется штатными ПрочитатьJSON / ЗаписатьJSON и типами ЧтениеJSON / ЗаписьJSON.

Рекомендуемый способ с сайта OneScript — менеджер версий ovm. На Linux и macOS ovm запускается через Mono 6+ (mono ovm.exe), затем:

ovm install stable
ovm use stable

Для сервера с n8n проще самостоятельный дистрибутив SCD со страницы загрузок (файл вида OneScript-<версия>-linux-x64.zip):

unzip OneScript-*-linux-x64.zip -d /opt/onescript
chmod +x /opt/onescript/bin/oscript
export PATH="/opt/onescript/bin:$PATH"
oscript -version

Каталог bin нужно добавить в PATH пользователя или сервиса, под которым запущен n8n, и перезапустить n8n. На Linux для SCD часто нужны tzdata и ICU (libicu74 или пакет с другим номером в вашем дистрибутиве). Подробности: установка OneScript.

Проверка:

printf '%s\n' 'Сообщить("Привет, OneScript!");' > /tmp/hello.os
oscript /tmp/hello.os

Установка ноды локально

Соберите пакет:

npm install
npm run build

Неопубликованный пакет нельзя поставить из Settings → Community nodes: этот экран ставит пакеты из npm. Пока пакет не опубликован, подключите каталог dist.

n8n ищет файлы **/*.node.js в ~/.n8n/custom и в каталоге из N8N_CUSTOM_EXTENSIONS (один путь; несколько путей через ; в текущих версиях n8n ненадёжны). Укажите именно dist, не корень репозитория: из корня загрузчик может подхватить чужие *.node.js из node_modules.

export N8N_CUSTOM_EXTENSIONS="/абсолютный/путь/n8n-nodes-onescript/dist"

Либо скопируйте собранные файлы в каталог по умолчанию и перезапустите n8n:

mkdir -p ~/.n8n/custom
cp -a dist/nodes ~/.n8n/custom/nodes

После публикации в npm пакет ставится так:

  • в интерфейсе: Settings → Community nodes → Install, имя n8n-nodes-onescript;
  • из командной строки, в каталоге узлов n8n: npm install n8n-nodes-onescript.

Локальный каталог до публикации можно поставить той же командой: npm install /абсолютный/путь/n8n-nodes-onescript из ~/.n8n/nodes. Перед этим нужен успешный npm run build: в пакет попадает dist.

Docker и custom extensions

Официальный образ n8n собран на Alpine (musl). SCD-сборки OneScript для Linux рассчитаны на glibc; в документации OneScript для контейнера указан образ mcr.microsoft.com/dotnet/runtime-deps:8.0, а не Alpine. Бинарник oscript нужно положить в PATH контейнера и проверить, что он реально запускается. Команды apk add oscript нет.

Нода подключается отдельным томом. N8N_CUSTOM_EXTENSIONS смотрит на dist:

services:
  n8n:
    image: docker.n8n.io/n8nio/n8n:latest
    ports:
      - "5678:5678"
    environment:
      - N8N_CUSTOM_EXTENSIONS=/opt/n8n-nodes-onescript/dist
    volumes:
      - n8n_data:/home/node/.n8n
      - ./n8n-nodes-onescript:/opt/n8n-nodes-onescript:ro
volumes:
  n8n_data:

Каталог на хосте должен уже содержать dist после npm run build. Рядом с OneScript.node.js должны лежать onescript.svg и onescript.dark.svg.

Параметры

Нода выполняется один раз на все входящие items. Параметры читаются для первого item.

Параметр Что делает
Режим Код в ноде или Файл на диске
Код Редактор сценария. Виден в режиме «Код в ноде»
Путь к файлу Путь к .os на машине n8n. Виден в режиме файла
Таймаут (сек.) Ожидание oscript, по умолчанию 30. Допустимо от 1 до 86400
Передать входящие данные Записать items в JSON и передать путь первым аргументом

Код выполняется с правами пользователя процесса n8n. Песочницы нет.

Что приходит на вход

Передаётся только поле json каждого item. Бинарные данные n8n в скрипт не попадают.

Файл на диске выглядит так:

[
  { "json": { "name": "Товар", "price": 10 } }
]

Путь к этому файлу — АргументыКоманднойСтроки[0]. Команда без оболочки:

oscript <сценарий.os> <путь-к-input.json>

Если флаг выключен, дополнительный аргумент не передаётся и обёртка не добавляется.

Режим «Код в ноде»

Нода дописывает перед вашим текстом обёртку. Она читает JSON штатным API и кладёт результат в переменную ВходящиеДанные:

ЧтениеВходящихN8n = Новый ЧтениеJSON;
ЧтениеВходящихN8n.ОткрытьФайл(АргументыКоманднойСтроки[0], "UTF-8");
ВходящиеДанные = ПрочитатьJSON(ЧтениеВходящихN8n, Истина);
ЧтениеВходящихN8n.Закрыть();

Истина во втором аргументе ПрочитатьJSON обязательна для произвольных имён полей: объекты становятся Соответствие, а не Структура. Массив остаётся массивом. Поле item читается так: Элемент["json"].

Имя ЧтениеВходящихN8n занято обёрткой. Директива #Использовать в этом режиме не сработает: она должна быть в начале файла, а обёртка уже стоит выше. Библиотеки подключайте в режиме файла.

Код по умолчанию печатает ВходящиеДанные обратно в stdout.

Режим «Файл на диске»

Файл запускается как есть, без обёртки, чтобы сохранились #Использовать и собственная точка входа. Переменной ВходящиеДанные нет, пока скрипт сам не прочитает аргумент. Готовый пример: examples/echo-items.os.

Чтение = Новый ЧтениеJSON;
Чтение.ОткрытьФайл(АргументыКоманднойСтроки[0], "UTF-8");
ВходящиеДанные = ПрочитатьJSON(Чтение, Истина);
Чтение.Закрыть();

Рабочий каталог процесса — каталог этого файла. В режиме кода рабочий каталог — временный каталог ноды.

Что уходит на выход

Скрипт печатает результат в stdout. Для этого в OneScript используется Сообщить. ЗаписьJSON.Закрыть() после УстановитьСтроку() возвращает строку JSON.

Если весь stdout — один JSON-документ:

  • массив: каждый элемент становится item;
  • элемент вида { "json": { ... } } возвращается как item n8n с этим json;
  • прочий объект становится json целиком;
  • число, строка, null и вложенный массив приходят как { "value": ... }, потому что поле json у item n8n должно быть объектом;
  • один объект без массива — это один item;
  • пустой массив — пустой выход.

Иначе нода отдаёт один item:

{ "stdout": "...", "stderr": "...", "exitCode": 0 }

Ненулевой код завершения — ошибка ноды, в тексте ошибки stderr. Если stderr пуст, в тексте это сказано явно, и при наличии добавляется stdout.

Если oscript нет в PATH, нода падает с сообщением oscript не найден в PATH процесса n8n (stderr у такого запуска нет: процесс не стартовал).

Таймаут и вывод больше 16 МиБ тоже ошибка ноды: процесс останавливается.

Пример

Вход предыдущей ноды: item { "name": "Стул" }.

Код в ноде:

Для Каждого Элемент Из ВходящиеДанные Цикл
	Данные = Элемент["json"];
	Данные.Вставить("processed", Истина);
КонецЦикла;

Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку();
ЗаписатьJSON(Запись, ВходящиеДанные);
Сообщить(Запись.Закрыть());

Выход: один item { "name": "Стул", "processed": true }.

Текст вместо JSON, например Сообщить("готово");, даёт item { "stdout": "готово\n", "stderr": "", "exitCode": 0 }. Точный перевод строки зависит от Сообщить.

Выпуск версии

В GitHub откройте Actions → Publish → Run workflow. В поле версии укажите тег с префиксом v, например v0.2.0.

Workflow запишет эту версию в package.json и package-lock.json, соберёт CHANGELOG.md через git-cliff, создаст тег и страницу релиза и опубликует пакет в npm.

Ограничения

  • Нужен self-hosted n8n. На n8n Cloud свой бинарник oscript не поставить, поэтому у пакета выключена проверка n8n Cloud (n8n.strict: false).
  • Текущие типы n8n допускают usableAsTool только как true. Нода может быть инструментом AI-агента и тогда тоже выполняет код на машине n8n.
  • В скрипт не передаются binary, pairedItem и прочие служебные поля item — только json.
  • Параметры ноды берутся из первого item. Выражения, разные для каждого item, не исполняются по очереди.
  • В режиме кода нельзя начать сценарий с #Использовать.
  • Ошибка компиляции или ВызватьИсключение — ненулевой код и stderr, выполнение workflow на этой ноде останавливается. Если у ноды включён Continue On Fail, вместо остановки выходит один item с полем error.
  • Код не изолирован от файловой системы и сети машины n8n.

Автор и поддержка

Автор: Ivan Karlo (i.karlo@outlook.com)

Поддержать проект:

Discussion