Оберните универсальные выражения в функцию

#javascript #parsing #lexical

Вопрос:

Я являюсь частью n8n.io, проект с открытым исходным кодом, и мы ищем способ помочь нашим пользователям манипулировать данными.

Наш инструмент позволяет пользователям получать данные из любого источника (базы данных, http-запросов, служб очередей и т.д.), манипулировать и выполнять другие действия, такие как отправка электронной почты, создание интереса в Hubspot и т.д. Это инструмент автоматизации рабочего процесса.

Мы уже предоставляем нашим пользователям способы сопоставления данных из одного места в другое, например, получаем имя пользователя из базы данных и отправляем его в качестве имени ведущего в Hubspot. Но пользователи могут захотеть манипулировать этими данными перед отправкой.

Для этого мы хотим добавить вспомогательные функции.

Наши пользователи уже могут использовать механизм шаблонов для создания некоторых интересных материалов, таких как:

{{ username.toUpperCase() }}

Учитывая, что username в приведенном выше примере это строка, а toUpperCase() это собственная строковая функция.

Мы хотели бы расширить это поведение. Добавьте больше функциональности. Например, что-то вроде {{ email.isEmail() ? email : '' }} where isEmail -это новая функция, которую мы хотели бы предоставить, и email это просто строка.

Одно важное замечание состоит в том, что мы хотели бы, чтобы эти функции были цепными, а не просто функциями, чтобы избежать ада в скобках.

Я думал о расширении собственных прототипов, но это сопровождается множеством побочных эффектов, особенно потому, что мы также хотим расширить Object свойства (с помощью таких функций, как .hasField('username') или .removeField('name') . Расширение прототипов привело к тому, что многие вещи были сломаны, поэтому мы не можем следовать по этому пути.

Также пользователи могут выполнять математические операции, например {{ (age 5) / 2 }} , поэтому нам нужны операции, которые работают с числами, строками, объектами и массивами.

Я был бы признателен за любые идеи о том, как этого достичь: предоставление функций, которые могут быть связаны для управления данными.

Мы хотели бы избежать принуждения наших пользователей заключать свои данные во вспомогательную функцию, например {{ _(name).firstName().toUpperCase() }} . В этом случае мы бы реализовали _ функцию в качестве помощника и реализовали все методы внутри нее, в зависимости от типа данных.

Есть ли способ обернуть любое выражение во вспомогательную функцию, такую как вышеупомянутая? Регулярное выражение, которое является доказательством сбоя, было бы потрясающим.

Пожалуйста, имейте в виду, что выражения могут быть очень произвольными, такими как:

 {{ (5
 
2

).isPrime
() ? 'This is prime' : 42
}}
 

Приведенный выше пример является совершенно корректным выражением, и моя цель-завернуть раздел (5 2) в нашу вспомогательную функцию, чтобы конечный результат перед отправкой в наш механизм шаблонов выглядел следующим образом:

 {{ _((5
 
2

)).isPrime
() ? 'This is prime' : 42
}}
 

Комментарии:

1. Чтобы не следовать подходу цепных методов, но и не сталкиваться с синтаксисом вложенных функций, можно использовать синтаксис предложения оператора конвейера , который уже долгое время безопасно поддерживается babel

2. из любопытства… какой код был взломан? третья сторона? твой собственный? Несмотря на то, что говорится, что по какой-либо причине не следует расширять прототипы встроенных объектов, это, с одной стороны, не считается разумным, поскольку предоставлять прототипные методы, например, не перечисляемым способом; с другой стороны, также совсем не сложно (на самом деле всегда следует чувствовать себя поощренным/обязанным) писать код, который не ломается от неожиданно обогащенных встроенных прототипов.

3. Интересное предложение @PeterSeliger Я посмотрю на это! О том, что сломалось, на самом деле, когда я расширил Object прототип, некоторые из наших Vue.js сломался внутренне, поскольку он повторял свойства объекта.