Add Activepieces integration for workflow automation
- Add Activepieces fork with SmoothSchedule custom piece - Create integrations app with Activepieces service layer - Add embed token endpoint for iframe integration - Create Automations page with embedded workflow builder - Add sidebar visibility fix for embed mode - Add list inactive customers endpoint to Public API - Include SmoothSchedule triggers: event created/updated/cancelled - Include SmoothSchedule actions: create/update/cancel events, list resources/services/customers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"Tables": "Tables",
|
||||
"Create Record(s)": "Create Record(s)",
|
||||
"Delete Record(s)": "Delete Record(s)",
|
||||
"Update Record": "Update Record",
|
||||
"Get Record": "Get Record",
|
||||
"Find Records": "Find Records",
|
||||
"Insert one or more new records to a table.": "Insert one or more new records to a table.",
|
||||
"Delete record(s) from a table": "Delete record(s) from a table",
|
||||
"Update values in an existing record": "Update values in an existing record",
|
||||
"Get single record by its id.": "Get single record by its id.",
|
||||
"Find records in a table with filters.": "Find records in a table with filters.",
|
||||
"Table Name": "Table Name",
|
||||
"Records": "Records",
|
||||
"Records IDs": "Records IDs",
|
||||
"Record ID": "Record ID",
|
||||
"Values": "Values",
|
||||
"Limit": "Limit",
|
||||
"Filters": "Filters",
|
||||
"The records to create.": "The records to create.",
|
||||
"The IDs of the records to delete": "The IDs of the records to delete",
|
||||
"The ID of the record to do the action on.": "The ID of the record to do the action on.",
|
||||
"The values to update. Leave empty to keep current value.": "The values to update. Leave empty to keep current value.",
|
||||
"Maximum number of records to return (default no limit).": "Maximum number of records to return (default no limit).",
|
||||
"Filter conditions to apply": "Filter conditions to apply",
|
||||
"New Record Created": "New Record Created",
|
||||
"Record Updated": "Record Updated",
|
||||
"Record Deleted": "Record Deleted",
|
||||
"Triggers when a new record is added to the selected table.": "Triggers when a new record is added to the selected table.",
|
||||
"Triggers when a record is updated in the selected table.": "Triggers when a record is updated in the selected table.",
|
||||
"Triggers when a record is deleted from the selected table.": "Triggers when a record is deleted from the selected table."
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"Create Record(s)": "Datensatz(e) erstellen",
|
||||
"Delete Record(s)": "Datensatz(e) löschen",
|
||||
"Update Record": "Datensatz aktualisieren",
|
||||
"Get Record": "Datensatz abrufen",
|
||||
"Find Records": "Datensätze finden",
|
||||
"Insert one or more new records to a table.": "Fügen Sie einen oder mehrere neue Datensätze in eine Tabelle ein.",
|
||||
"Delete record(s) from a table": "Datensatze(n) aus einer Tabelle löschen",
|
||||
"Update values in an existing record": "Werte in einem vorhandenen Datensatz aktualisieren",
|
||||
"Get single record by its id.": "Holen Sie sich einen einzelnen Datensatz durch seine ID.",
|
||||
"Find records in a table with filters.": "Suchen Sie Datensätze in einer Tabelle mit Filtern.",
|
||||
"Table Name": "Tabellenname",
|
||||
"Records": "Datensätze",
|
||||
"Records IDs": "Datensatz-ID",
|
||||
"Record ID": "Datensatz-ID",
|
||||
"Values": "Werte",
|
||||
"Limit": "Limit",
|
||||
"Filters": "Filter",
|
||||
"The records to create.": "Zu erstellende Datensätze.",
|
||||
"The IDs of the records to delete": "Die IDs der zu löschenden Datensätze",
|
||||
"The ID of the record to do the action on.": "Die ID des Datensatzes, auf dem die Aktion ausgeführt wird.",
|
||||
"The values to update. Leave empty to keep current value.": "Die zu aktualisierenden Werte. Leer lassen, um den aktuellen Wert zu behalten.",
|
||||
"Maximum number of records to return (default no limit).": "Maximale Anzahl der zurückzugebenden Datensätze (Standard kein Limit).",
|
||||
"Filter conditions to apply": "Zu verwendende Bedingungen filtern",
|
||||
"New Record Created": "Neuer Datensatz erstellt",
|
||||
"Record Updated": "Datensatz aktualisiert",
|
||||
"Record Deleted": "Eintrag gelöscht",
|
||||
"Triggers when a new record is added to the selected table.": "Wird ausgelöst, wenn ein neuer Datensatz zur ausgewählten Tabelle hinzugefügt wird.",
|
||||
"Triggers when a record is updated in the selected table.": "Wird ausgelöst, wenn ein Datensatz in der ausgewählten Tabelle aktualisiert wird.",
|
||||
"Triggers when a record is deleted from the selected table.": "Wird ausgelöst, wenn ein Datensatz aus der ausgewählten Tabelle gelöscht wird."
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"Create Record(s)": "Crear registro(s)",
|
||||
"Delete Record(s)": "Eliminar registro(s)",
|
||||
"Update Record": "Actualizar registro",
|
||||
"Get Record": "Obtener registro",
|
||||
"Find Records": "Buscar registros",
|
||||
"Insert one or more new records to a table.": "Inserte uno o más registros nuevos en una tabla.",
|
||||
"Delete record(s) from a table": "Eliminar registro(s) de una tabla",
|
||||
"Update values in an existing record": "Actualizar valores en un registro existente",
|
||||
"Get single record by its id.": "Obtener un único registro por su id.",
|
||||
"Find records in a table with filters.": "Buscar registros en una tabla con filtros.",
|
||||
"Table Name": "Nombre de tabla",
|
||||
"Records": "Registros",
|
||||
"Records IDs": "ID de registros",
|
||||
"Record ID": "ID de registro",
|
||||
"Values": "Valores",
|
||||
"Limit": "Límite",
|
||||
"Filters": "Filtros",
|
||||
"The records to create.": "Los registros a crear.",
|
||||
"The IDs of the records to delete": "Los IDs de los registros a eliminar",
|
||||
"The ID of the record to do the action on.": "El ID del registro en el que realizar la acción.",
|
||||
"The values to update. Leave empty to keep current value.": "Los valores a actualizar. Dejar en blanco para mantener el valor actual.",
|
||||
"Maximum number of records to return (default no limit).": "Número máximo de registros a devolver (por defecto sin límite).",
|
||||
"Filter conditions to apply": "Filtrar condiciones a aplicar",
|
||||
"New Record Created": "Nuevo registro creado",
|
||||
"Record Updated": "Registro actualizado",
|
||||
"Record Deleted": "Registro eliminado",
|
||||
"Triggers when a new record is added to the selected table.": "Se activa cuando se añade un nuevo registro a la tabla seleccionada.",
|
||||
"Triggers when a record is updated in the selected table.": "Se activa cuando un registro se actualiza en la tabla seleccionada.",
|
||||
"Triggers when a record is deleted from the selected table.": "Se activa cuando se elimina un registro de la tabla seleccionada."
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"Create Record(s)": "Créer un ou des enregistrement(s)",
|
||||
"Delete Record(s)": "Supprimer les enregistrement(s)",
|
||||
"Update Record": "Mettre à jour l'enregistrement",
|
||||
"Get Record": "Obtenir un enregistrement",
|
||||
"Find Records": "Trouver des enregistrements",
|
||||
"Insert one or more new records to a table.": "Insérer un ou plusieurs nouveaux enregistrements dans une table.",
|
||||
"Delete record(s) from a table": "Supprimer le(s) enregistrement(s) d'une table",
|
||||
"Update values in an existing record": "Mettre à jour les valeurs dans un enregistrement existant",
|
||||
"Get single record by its id.": "Obtenir un enregistrement unique par son identifiant.",
|
||||
"Find records in a table with filters.": "Rechercher les enregistrements dans une table avec des filtres.",
|
||||
"Table Name": "Nom de la table",
|
||||
"Records": "Enregistrements",
|
||||
"Records IDs": "ID d'enregistrements",
|
||||
"Record ID": "ID de l'enregistrement",
|
||||
"Values": "Valeurs",
|
||||
"Limit": "Limite",
|
||||
"Filters": "Filtres",
|
||||
"The records to create.": "Les enregistrements à créer.",
|
||||
"The IDs of the records to delete": "Les identifiants des enregistrements à supprimer",
|
||||
"The ID of the record to do the action on.": "L'ID de l'enregistrement sur lequel effectuer l'action.",
|
||||
"The values to update. Leave empty to keep current value.": "Les valeurs à mettre à jour. Laisser vide pour conserver la valeur actuelle.",
|
||||
"Maximum number of records to return (default no limit).": "Nombre maximum d'enregistrements à retourner (sans limite par défaut).",
|
||||
"Filter conditions to apply": "Filtrer les conditions à appliquer",
|
||||
"New Record Created": "Nouvel enregistrement créé",
|
||||
"Record Updated": "Enregistrement mis à jour",
|
||||
"Record Deleted": "Enregistrement supprimé",
|
||||
"Triggers when a new record is added to the selected table.": "Déclenche lorsqu'un nouvel enregistrement est ajouté à la table sélectionnée.",
|
||||
"Triggers when a record is updated in the selected table.": "Déclenche lorsqu'un enregistrement est mis à jour dans le tableau sélectionné.",
|
||||
"Triggers when a record is deleted from the selected table.": "Déclenche lorsqu'un enregistrement est supprimé de la table sélectionnée."
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"Tables": "Tables",
|
||||
"Create Record(s)": "Create Record(s)",
|
||||
"Delete Record(s)": "Delete Record(s)",
|
||||
"Update Record": "Update Record",
|
||||
"Get Record": "Get Record",
|
||||
"Find Records": "Find Records",
|
||||
"Insert one or more new records to a table.": "Insert one or more new records to a table.",
|
||||
"Delete record(s) from a table": "Delete record(s) from a table",
|
||||
"Update values in an existing record": "Update values in an existing record",
|
||||
"Get single record by its id.": "Get single record by its id.",
|
||||
"Find records in a table with filters.": "Find records in a table with filters.",
|
||||
"Table Name": "Table Name",
|
||||
"Records": "Records",
|
||||
"Records IDs": "Records IDs",
|
||||
"Record ID": "Record ID",
|
||||
"Values": "Values",
|
||||
"Limit": "Limit",
|
||||
"Filters": "Filters",
|
||||
"The records to create.": "The records to create.",
|
||||
"The IDs of the records to delete": "The IDs of the records to delete",
|
||||
"The ID of the record to do the action on.": "The ID of the record to do the action on.",
|
||||
"The values to update. Leave empty to keep current value.": "The values to update. Leave empty to keep current value.",
|
||||
"Maximum number of records to return (default no limit).": "Maximum number of records to return (default no limit).",
|
||||
"Filter conditions to apply": "Filter conditions to apply",
|
||||
"New Record Created": "New Record Created",
|
||||
"Record Updated": "Record Updated",
|
||||
"Record Deleted": "Record Deleted",
|
||||
"Triggers when a new record is added to the selected table.": "Triggers when a new record is added to the selected table.",
|
||||
"Triggers when a record is updated in the selected table.": "Triggers when a record is updated in the selected table.",
|
||||
"Triggers when a record is deleted from the selected table.": "Triggers when a record is deleted from the selected table."
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"Tables": "Tables",
|
||||
"Create Record(s)": "Create Record(s)",
|
||||
"Delete Record(s)": "Delete Record(s)",
|
||||
"Update Record": "Update Record",
|
||||
"Get Record": "Get Record",
|
||||
"Find Records": "Find Records",
|
||||
"Insert one or more new records to a table.": "Insert one or more new records to a table.",
|
||||
"Delete record(s) from a table": "Delete record(s) from a table",
|
||||
"Update values in an existing record": "Update values in an existing record",
|
||||
"Get single record by its id.": "Get single record by its id.",
|
||||
"Find records in a table with filters.": "Find records in a table with filters.",
|
||||
"Table Name": "Table Name",
|
||||
"Records": "Records",
|
||||
"Records IDs": "Records IDs",
|
||||
"Record ID": "Record ID",
|
||||
"Values": "Values",
|
||||
"Limit": "Limit",
|
||||
"Filters": "Filter",
|
||||
"The records to create.": "The records to create.",
|
||||
"The IDs of the records to delete": "The IDs of the records to delete",
|
||||
"The ID of the record to do the action on.": "The ID of the record to do the action on.",
|
||||
"The values to update. Leave empty to keep current value.": "The values to update. Leave empty to keep current value.",
|
||||
"Maximum number of records to return (default no limit).": "Maximum number of records to return (default no limit).",
|
||||
"Filter conditions to apply": "Filter conditions to apply",
|
||||
"New Record Created": "New Record Created",
|
||||
"Record Updated": "Record Updated",
|
||||
"Record Deleted": "Record Deleted",
|
||||
"Triggers when a new record is added to the selected table.": "Triggers when a new record is added to the selected table.",
|
||||
"Triggers when a record is updated in the selected table.": "Triggers when a record is updated in the selected table.",
|
||||
"Triggers when a record is deleted from the selected table.": "Triggers when a record is deleted from the selected table."
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"Create Record(s)": "レコードを作成",
|
||||
"Delete Record(s)": "レコードを削除",
|
||||
"Update Record": "更新記録",
|
||||
"Get Record": "レコードを取得",
|
||||
"Find Records": "レコードを検索",
|
||||
"Insert one or more new records to a table.": "1つ以上の新しいレコードをテーブルに挿入します。",
|
||||
"Delete record(s) from a table": "テーブルからレコードを削除",
|
||||
"Update values in an existing record": "既存のレコードの値を更新",
|
||||
"Get single record by its id.": "IDでシングルレコードを取得します。",
|
||||
"Find records in a table with filters.": "フィルタ付きのテーブル内のレコードを検索します。",
|
||||
"Table Name": "テーブル名",
|
||||
"Records": "レコード",
|
||||
"Records IDs": "レコードID",
|
||||
"Record ID": "レコードID",
|
||||
"Values": "値",
|
||||
"Limit": "制限",
|
||||
"Filters": "絞り込み",
|
||||
"The records to create.": "作成するレコード。",
|
||||
"The IDs of the records to delete": "削除するレコードの ID",
|
||||
"The ID of the record to do the action on.": "アクションを実行するレコードの ID。",
|
||||
"The values to update. Leave empty to keep current value.": "更新する値。空のままにすると現在の値が維持されます。",
|
||||
"Maximum number of records to return (default no limit).": "Maximum number of records to return (default no limit).",
|
||||
"Filter conditions to apply": "適用するフィルタ条件",
|
||||
"New Record Created": "新しいレコードが作成されました",
|
||||
"Record Updated": "レコードが更新されました",
|
||||
"Record Deleted": "レコードが削除されました",
|
||||
"Triggers when a new record is added to the selected table.": "選択したテーブルに新しいレコードが追加されたときにトリガーされます。",
|
||||
"Triggers when a record is updated in the selected table.": "選択したテーブルでレコードが更新されたときにトリガーされます。",
|
||||
"Triggers when a record is deleted from the selected table.": "選択したテーブルからレコードが削除されたときにトリガーされます。"
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"Create Record(s)": "Maak Opname(s)",
|
||||
"Delete Record(s)": "Opname(s) verwijderen",
|
||||
"Update Record": "Update Record",
|
||||
"Get Record": "Krijg Record",
|
||||
"Find Records": "Records zoeken",
|
||||
"Insert one or more new records to a table.": "Een of meer nieuwe records toevoegen aan een tabel.",
|
||||
"Delete record(s) from a table": "Verwijder record(s) uit een tabel",
|
||||
"Update values in an existing record": "Waarden in een bestaand record bijwerken",
|
||||
"Get single record by its id.": "Krijg enkele record bij zijn id.",
|
||||
"Find records in a table with filters.": "Zoek records in een tabel met filters.",
|
||||
"Table Name": "Tafel naam",
|
||||
"Records": "Records",
|
||||
"Records IDs": "Records ID's",
|
||||
"Record ID": "Record ID",
|
||||
"Values": "Waarden",
|
||||
"Limit": "Limiet",
|
||||
"Filters": "Filters",
|
||||
"The records to create.": "De records om te maken.",
|
||||
"The IDs of the records to delete": "De ID's van de te verwijderen records",
|
||||
"The ID of the record to do the action on.": "Het ID van het record waar u de actie aan wilt doen.",
|
||||
"The values to update. Leave empty to keep current value.": "De waarden om bij te werken. Laat leeg om de huidige waarde te behouden.",
|
||||
"Maximum number of records to return (default no limit).": "Maximum aantal records om terug te sturen (standaard geen limiet).",
|
||||
"Filter conditions to apply": "Filter voorwaarden toe te passen",
|
||||
"New Record Created": "Nieuw Record Gemaakt",
|
||||
"Record Updated": "Record bijgewerkt",
|
||||
"Record Deleted": "Record verwijderd",
|
||||
"Triggers when a new record is added to the selected table.": "Activeert wanneer een nieuwe record wordt toegevoegd aan de geselecteerde tabel.",
|
||||
"Triggers when a record is updated in the selected table.": "Activeert wanneer een record wordt bijgewerkt in de geselecteerde tabel.",
|
||||
"Triggers when a record is deleted from the selected table.": "Activeert wanneer een record wordt verwijderd uit de geselecteerde tabel."
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"Create Record(s)": "Criar Registro(s)",
|
||||
"Delete Record(s)": "Excluir Registro(s)",
|
||||
"Update Record": "Atualizar Registro",
|
||||
"Get Record": "Obter Registro",
|
||||
"Find Records": "Encontrar registros",
|
||||
"Insert one or more new records to a table.": "Inserir um ou mais registros em uma tabela.",
|
||||
"Delete record(s) from a table": "Excluir registro(s) de uma tabela",
|
||||
"Update values in an existing record": "Atualizar valores em um registro existente",
|
||||
"Get single record by its id.": "Obtenha um único registro por seu id.",
|
||||
"Find records in a table with filters.": "Encontrar registros em uma tabela com filtros.",
|
||||
"Table Name": "Nome da Tabela",
|
||||
"Records": "registros",
|
||||
"Records IDs": "IDs de registros",
|
||||
"Record ID": "ID do Registro",
|
||||
"Values": "Valores",
|
||||
"Limit": "Limitar",
|
||||
"Filters": "Filtros",
|
||||
"The records to create.": "Os registros a criar.",
|
||||
"The IDs of the records to delete": "Os IDs dos registros a serem excluídos",
|
||||
"The ID of the record to do the action on.": "A ID do registro para fazer a ação.",
|
||||
"The values to update. Leave empty to keep current value.": "Os valores a serem atualizados. Deixe em branco para manter o valor atual.",
|
||||
"Maximum number of records to return (default no limit).": "Número máximo de registros para retornar (padrão sem limite)",
|
||||
"Filter conditions to apply": "Condições de filtro a aplicar",
|
||||
"New Record Created": "Novo Registro Criado",
|
||||
"Record Updated": "Registro Atualizado",
|
||||
"Record Deleted": "Registro Excluído",
|
||||
"Triggers when a new record is added to the selected table.": "Dispara quando um novo registro é adicionado à tabela selecionada.",
|
||||
"Triggers when a record is updated in the selected table.": "Dispara quando um registro é atualizado na tabela selecionada.",
|
||||
"Triggers when a record is deleted from the selected table.": "Dispara quando um registro é excluído da tabela selecionada."
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"Tables": "Таблицы",
|
||||
"Create Record(s)": "Создать запись(и)",
|
||||
"Delete Record(s)": "Удалить запись(и)",
|
||||
"Update Record": "Обновить запись",
|
||||
"Get Record": "Получить запись",
|
||||
"Find Records": "Найти записи",
|
||||
"Insert one or more new records to a table.": "Вставьте одну или несколько новых записей в таблицу.",
|
||||
"Delete record(s) from a table": "Удалить записи из таблицы",
|
||||
"Update values in an existing record": "Обновить значения в существующей записи",
|
||||
"Get single record by its id.": "Получить одну запись по идентификатору.",
|
||||
"Find records in a table with filters.": "Найти записи в таблице с фильтрами.",
|
||||
"Table Name": "Название таблицы",
|
||||
"Records": "Отчеты",
|
||||
"Records IDs": "Идентификаторы записей",
|
||||
"Record ID": "ID записи",
|
||||
"Values": "Значения",
|
||||
"Limit": "Лимит",
|
||||
"Filters": "Фильтры",
|
||||
"The records to create.": "Записи для создания.",
|
||||
"The IDs of the records to delete": "ID удаляемых записей",
|
||||
"The ID of the record to do the action on.": "ID записи, на которую нужно выполнить действие.",
|
||||
"The values to update. Leave empty to keep current value.": "Значения для обновления. Оставьте пустым, чтобы сохранить текущее значение.",
|
||||
"Maximum number of records to return (default no limit).": "Максимальное количество возвращаемых записей (без ограничения по умолчанию).",
|
||||
"Filter conditions to apply": "Фильтр условий для применения",
|
||||
"New Record Created": "Создана новая запись",
|
||||
"Record Updated": "Запись обновлена",
|
||||
"Record Deleted": "Запись удалена",
|
||||
"Triggers when a new record is added to the selected table.": "Включает при добавлении новой записи в выбранную таблицу.",
|
||||
"Triggers when a record is updated in the selected table.": "Включает при обновлении записи в выбранной таблице.",
|
||||
"Triggers when a record is deleted from the selected table.": "Включает при удалении записи из выбранной таблицы."
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"Create Record(s)": "Create Record(s)",
|
||||
"Delete Record(s)": "Delete Record(s)",
|
||||
"Update Record": "Update Record",
|
||||
"Get Record": "Get Record",
|
||||
"Find Records": "Find Records",
|
||||
"Clear Table": "Clear Table",
|
||||
"Insert one or more new records to a table.": "Insert one or more new records to a table.",
|
||||
"Delete record(s) from a table": "Delete record(s) from a table",
|
||||
"Update values in an existing record": "Update values in an existing record",
|
||||
"Get single record by its id.": "Get single record by its id.",
|
||||
"Find records in a table with filters.": "Find records in a table with filters.",
|
||||
"Delete all records from a table": "Delete all records from a table",
|
||||
"Table Name": "Table Name",
|
||||
"Records": "Records",
|
||||
"Records IDs": "Records IDs",
|
||||
"Record ID": "Record ID",
|
||||
"Values": "Values",
|
||||
"Limit": "Limit",
|
||||
"Filters": "Filters",
|
||||
"The records to create.": "The records to create.",
|
||||
"The IDs of the records to delete": "The IDs of the records to delete",
|
||||
"The ID of the record to do the action on.": "The ID of the record to do the action on.",
|
||||
"The values to update. Leave empty to keep current value.": "The values to update. Leave empty to keep current value.",
|
||||
"Maximum number of records to return (default no limit).": "Maximum number of records to return (default no limit).",
|
||||
"Filter conditions to apply": "Filter conditions to apply",
|
||||
"New Record Created": "New Record Created",
|
||||
"Record Updated": "Record Updated",
|
||||
"Record Deleted": "Record Deleted",
|
||||
"Triggers when a new record is added to the selected table.": "Triggers when a new record is added to the selected table.",
|
||||
"Triggers when a record is updated in the selected table.": "Triggers when a record is updated in the selected table.",
|
||||
"Triggers when a record is deleted from the selected table.": "Triggers when a record is deleted from the selected table."
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"Tables": "Tables",
|
||||
"Create Record(s)": "Create Record(s)",
|
||||
"Delete Record(s)": "Delete Record(s)",
|
||||
"Update Record": "Update Record",
|
||||
"Get Record": "Get Record",
|
||||
"Find Records": "Find Records",
|
||||
"Insert one or more new records to a table.": "Insert one or more new records to a table.",
|
||||
"Delete record(s) from a table": "Delete record(s) from a table",
|
||||
"Update values in an existing record": "Update values in an existing record",
|
||||
"Get single record by its id.": "Get single record by its id.",
|
||||
"Find records in a table with filters.": "Find records in a table with filters.",
|
||||
"Table Name": "Table Name",
|
||||
"Records": "Records",
|
||||
"Records IDs": "Records IDs",
|
||||
"Record ID": "Record ID",
|
||||
"Values": "Values",
|
||||
"Limit": "Limit",
|
||||
"Filters": "Bộ lọc",
|
||||
"The records to create.": "The records to create.",
|
||||
"The IDs of the records to delete": "The IDs of the records to delete",
|
||||
"The ID of the record to do the action on.": "The ID of the record to do the action on.",
|
||||
"The values to update. Leave empty to keep current value.": "The values to update. Leave empty to keep current value.",
|
||||
"Maximum number of records to return (default no limit).": "Maximum number of records to return (default no limit).",
|
||||
"Filter conditions to apply": "Filter conditions to apply",
|
||||
"New Record Created": "New Record Created",
|
||||
"Record Updated": "Record Updated",
|
||||
"Record Deleted": "Record Deleted",
|
||||
"Triggers when a new record is added to the selected table.": "Triggers when a new record is added to the selected table.",
|
||||
"Triggers when a record is updated in the selected table.": "Triggers when a record is updated in the selected table.",
|
||||
"Triggers when a record is deleted from the selected table.": "Triggers when a record is deleted from the selected table."
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"Create Record(s)": "Create Record(s)",
|
||||
"Delete Record(s)": "Delete Record(s)",
|
||||
"Update Record": "Update Record",
|
||||
"Get Record": "Get Record",
|
||||
"Find Records": "Find Records",
|
||||
"Insert one or more new records to a table.": "Insert one or more new records to a table.",
|
||||
"Delete record(s) from a table": "Delete record(s) from a table",
|
||||
"Update values in an existing record": "Update values in an existing record",
|
||||
"Get single record by its id.": "Get single record by its id.",
|
||||
"Find records in a table with filters.": "Find records in a table with filters.",
|
||||
"Table Name": "Table Name",
|
||||
"Records": "Records",
|
||||
"Records IDs": "Records IDs",
|
||||
"Record ID": "Record ID",
|
||||
"Values": "值",
|
||||
"Limit": "Limit",
|
||||
"Filters": "篩選條件",
|
||||
"The records to create.": "The records to create.",
|
||||
"The IDs of the records to delete": "The IDs of the records to delete",
|
||||
"The ID of the record to do the action on.": "The ID of the record to do the action on.",
|
||||
"The values to update. Leave empty to keep current value.": "The values to update. Leave empty to keep current value.",
|
||||
"Maximum number of records to return (default no limit).": "Maximum number of records to return (default no limit).",
|
||||
"Filter conditions to apply": "Filter conditions to apply",
|
||||
"New Record Created": "New Record Created",
|
||||
"Record Updated": "Record Updated",
|
||||
"Record Deleted": "Record Deleted",
|
||||
"Triggers when a new record is added to the selected table.": "Triggers when a new record is added to the selected table.",
|
||||
"Triggers when a record is updated in the selected table.": "Triggers when a record is updated in the selected table.",
|
||||
"Triggers when a record is deleted from the selected table.": "Triggers when a record is deleted from the selected table."
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { createPiece, PieceAuth } from "@activepieces/pieces-framework";
|
||||
import { createRecords } from "./lib/actions/create-records";
|
||||
import { PieceCategory } from "@activepieces/shared";
|
||||
import { deleteRecord } from "./lib/actions/delete-record";
|
||||
import { updateRecord } from "./lib/actions/update-record";
|
||||
import { getRecord } from "./lib/actions/get-record";
|
||||
import { findRecords } from "./lib/actions/find-records";
|
||||
import { clearTable } from "./lib/actions/clear-table";
|
||||
import { newRecordTrigger } from "./lib/triggers/new-record";
|
||||
import { deletedRecordTrigger } from "./lib/triggers/deleted-record";
|
||||
import { updatedRecordTrigger } from "./lib/triggers/updated-record";
|
||||
|
||||
export const tables = createPiece({
|
||||
displayName: 'Tables',
|
||||
logoUrl: 'https://cdn.activepieces.com/pieces/tables_piece.svg',
|
||||
categories: [PieceCategory.CORE],
|
||||
minimumSupportedRelease: '0.71.5',
|
||||
authors: ['amrdb'],
|
||||
auth: PieceAuth.None(),
|
||||
actions: [createRecords, deleteRecord, updateRecord, getRecord, findRecords, clearTable],
|
||||
triggers: [newRecordTrigger, updatedRecordTrigger, deletedRecordTrigger],
|
||||
});
|
||||
@@ -0,0 +1,31 @@
|
||||
import { createAction, PieceAuth } from '@activepieces/pieces-framework';
|
||||
import { tablesCommon } from '../common';
|
||||
import { AuthenticationType, httpClient, HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
export const clearTable = createAction({
|
||||
name: 'tables-clear-table',
|
||||
displayName: 'Clear Table',
|
||||
description: 'Delete all records from a table',
|
||||
auth: PieceAuth.None(),
|
||||
props: {
|
||||
table_id: tablesCommon.table_id,
|
||||
},
|
||||
async run(context) {
|
||||
const { table_id: tableExternalId } = context.propsValue;
|
||||
const tableId = await tablesCommon.convertTableExternalIdToId(tableExternalId, context);
|
||||
|
||||
await httpClient.sendRequest({
|
||||
method: HttpMethod.POST,
|
||||
url: `${context.server.apiUrl}v1/tables/${tableId}/clear`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: context.server.token,
|
||||
},
|
||||
retries: 5,
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,78 @@
|
||||
import { createAction, PieceAuth, Property } from '@activepieces/pieces-framework';
|
||||
import { AuthenticationType, httpClient, HttpMethod, propsValidation } from '@activepieces/pieces-common';
|
||||
import { CreateRecordsRequest } from '@activepieces/shared';
|
||||
import { tablesCommon } from '../common';
|
||||
|
||||
export const createRecords = createAction({
|
||||
name: 'tables-create-records',
|
||||
displayName: 'Create Record(s)',
|
||||
description: 'Insert one or more new records to a table.',
|
||||
auth: PieceAuth.None(),
|
||||
props: {
|
||||
table_id: tablesCommon.table_id,
|
||||
values: Property.DynamicProperties({
|
||||
auth: PieceAuth.None(),
|
||||
displayName: 'Records',
|
||||
description: 'The records to create.',
|
||||
required: true,
|
||||
refreshers: ['table_id'],
|
||||
props: async ({ table_id }, context) => {
|
||||
const tableExternalId = table_id as unknown as string;
|
||||
if ((tableExternalId ?? '').toString().length === 0) {
|
||||
return {};
|
||||
}
|
||||
const tableId = await tablesCommon.convertTableExternalIdToId(tableExternalId, context);
|
||||
|
||||
const fields = await tablesCommon.createFieldProperties({ tableId, context });
|
||||
if ('markdown' in fields) {
|
||||
return fields;
|
||||
}
|
||||
|
||||
return {
|
||||
values: Property.Array({
|
||||
displayName: 'Records',
|
||||
description: 'Add one or more records to insert',
|
||||
required: true,
|
||||
properties: fields,
|
||||
}),
|
||||
};
|
||||
},
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { table_id: tableExternalId, values } = context.propsValue;
|
||||
const tableId = await tablesCommon.convertTableExternalIdToId(tableExternalId, context);
|
||||
const tableFields = await tablesCommon.getTableFields({ tableId, context });
|
||||
|
||||
const records: CreateRecordsRequest['records'] = values['values'].map((record: Record<string, unknown>) =>
|
||||
Object.entries(record)
|
||||
.filter(([_, value]) => value !== null && value !== undefined && value !== '')
|
||||
.map(([fieldExternalId, value]) => ({
|
||||
fieldId: tableFields.find((field) => field.externalId === fieldExternalId)?.id,
|
||||
value,
|
||||
})).filter((record) => record.fieldId !== undefined)
|
||||
)
|
||||
const fieldValidations = tablesCommon.createFieldValidations(tableFields);
|
||||
|
||||
for (const record of values['values']) {
|
||||
const cleanedRecord = Object.fromEntries(Object.entries(record).filter(([_, value]) => value !== null && value !== undefined && value !== ''));
|
||||
await propsValidation.validateZod(cleanedRecord, fieldValidations);
|
||||
}
|
||||
|
||||
const response = await httpClient.sendRequest({
|
||||
method: HttpMethod.POST,
|
||||
url: `${context.server.apiUrl}v1/records`,
|
||||
body: {
|
||||
records,
|
||||
tableId,
|
||||
},
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: context.server.token,
|
||||
},
|
||||
retries: 5,
|
||||
});
|
||||
|
||||
return response.body.map(tablesCommon.formatRecord);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,38 @@
|
||||
import { createAction, PieceAuth, Property } from '@activepieces/pieces-framework';
|
||||
import { tablesCommon } from '../common';
|
||||
import { AuthenticationType, httpClient, HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
export const deleteRecord = createAction({
|
||||
name: 'tables-delete-record',
|
||||
displayName: 'Delete Record(s)',
|
||||
description: 'Delete record(s) from a table',
|
||||
auth: PieceAuth.None(),
|
||||
props: {
|
||||
table_id: tablesCommon.table_id,
|
||||
records_ids: Property.Array({
|
||||
displayName: 'Records IDs',
|
||||
required: true,
|
||||
description: 'The IDs of the records to delete'
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { records_ids } = context.propsValue;
|
||||
|
||||
await httpClient.sendRequest({
|
||||
method: HttpMethod.DELETE,
|
||||
url: `${context.server.apiUrl}v1/records/`,
|
||||
body: {
|
||||
ids: records_ids,
|
||||
},
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: context.server.token,
|
||||
},
|
||||
retries: 5,
|
||||
});
|
||||
|
||||
return {
|
||||
success: true
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,153 @@
|
||||
import { createAction, DynamicPropsValue, PieceAuth, Property, PropertyContext } from '@activepieces/pieces-framework';
|
||||
import { tablesCommon } from '../common';
|
||||
import { AuthenticationType, httpClient, HttpMethod, propsValidation } from '@activepieces/pieces-common';
|
||||
import { FieldType, Filter, FilterOperator, ListRecordsRequest, PopulatedRecord, SeekPage } from '@activepieces/shared';
|
||||
import { z } from 'zod';
|
||||
import qs from 'qs';
|
||||
type FieldInfo = {
|
||||
id: string;
|
||||
type: FieldType;
|
||||
name: string;
|
||||
};
|
||||
|
||||
export const findRecords = createAction({
|
||||
name: 'tables-find-records',
|
||||
displayName: 'Find Records',
|
||||
description: 'Find records in a table with filters.',
|
||||
auth: PieceAuth.None(),
|
||||
props: {
|
||||
table_id: tablesCommon.table_id,
|
||||
limit: Property.Number({
|
||||
displayName: 'Limit',
|
||||
description: 'Maximum number of records to return (default no limit).',
|
||||
required: false,
|
||||
}),
|
||||
filters: Property.DynamicProperties({
|
||||
auth: PieceAuth.None(),
|
||||
displayName: 'Filters',
|
||||
description: 'Filter conditions to apply',
|
||||
required: false,
|
||||
refreshers: ['table_id'],
|
||||
props: async (propsValue, context) => {
|
||||
const table_id = propsValue['table_id'];
|
||||
if (!table_id || typeof table_id !== 'string') {
|
||||
return {
|
||||
filters: Property.Array({
|
||||
displayName: 'Filters',
|
||||
required: false,
|
||||
properties: {},
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
const convertedTableId = await tablesCommon.convertTableExternalIdToId(table_id, context);
|
||||
const fields = await tablesCommon.getTableFields({
|
||||
tableId: convertedTableId,
|
||||
context,
|
||||
});
|
||||
|
||||
return {
|
||||
filters: Property.Array({
|
||||
displayName: 'Filters',
|
||||
required: false,
|
||||
properties: {
|
||||
field: Property.StaticDropdown({
|
||||
displayName: 'Field',
|
||||
required: true,
|
||||
options: {
|
||||
options: fields.map((field) => ({
|
||||
label: field.name,
|
||||
value: { id: field.id, type: field.type, name: field.name } as FieldInfo,
|
||||
})),
|
||||
},
|
||||
}),
|
||||
operator: Property.StaticDropdown({
|
||||
displayName: 'Operator',
|
||||
required: true,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Equals', value: FilterOperator.EQ },
|
||||
{ label: 'Not Equals', value: FilterOperator.NEQ },
|
||||
{ label: 'Greater Than', value: FilterOperator.GT },
|
||||
{ label: 'Greater Than or Equal', value: FilterOperator.GTE },
|
||||
{ label: 'Less Than', value: FilterOperator.LT },
|
||||
{ label: 'Less Than or Equal', value: FilterOperator.LTE },
|
||||
{ label: 'Contains', value: FilterOperator.CO },
|
||||
],
|
||||
},
|
||||
}),
|
||||
value: Property.ShortText({
|
||||
displayName: 'Value',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
}),
|
||||
};
|
||||
},
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { table_id: tableExternalId, limit, filters } = context.propsValue;
|
||||
const tableId = await tablesCommon.convertTableExternalIdToId(tableExternalId, context);
|
||||
const filtersArray: { field: FieldInfo; operator: FilterOperator; value: unknown }[] = filters?.['filters'] ?? [];
|
||||
|
||||
for (const filter of filtersArray) {
|
||||
const value = filter.value;
|
||||
const fieldType = filter.field.type;
|
||||
|
||||
let schema: Record<string, z.ZodType>;
|
||||
switch (fieldType) {
|
||||
case FieldType.NUMBER:
|
||||
schema = {
|
||||
value: z.union([z.number(), z.string().transform(val => {
|
||||
const num = Number(val);
|
||||
if (isNaN(num)) throw new Error(`Invalid number for field "${filter.field.name}"`);
|
||||
return num;
|
||||
})]),
|
||||
};
|
||||
break;
|
||||
case FieldType.DATE:
|
||||
schema = {
|
||||
value: z.union([z.date(), z.string().transform(val => {
|
||||
const date = new Date(val);
|
||||
if (isNaN(date.getTime())) throw new Error(`Invalid date for field "${filter.field.name}"`);
|
||||
return date;
|
||||
})]),
|
||||
};
|
||||
break;
|
||||
default:
|
||||
schema = {
|
||||
value: z.string(),
|
||||
};
|
||||
}
|
||||
|
||||
await propsValidation.validateZod({ value }, schema);
|
||||
}
|
||||
|
||||
const parsedFilters: Filter[] = filtersArray.map((filter) => ({
|
||||
fieldId: filter.field.id,
|
||||
operator: filter.operator,
|
||||
value: filter.value as string,
|
||||
}));
|
||||
|
||||
const request: ListRecordsRequest = {
|
||||
tableId,
|
||||
limit: limit ?? 999999999,
|
||||
cursor: undefined,
|
||||
filters: parsedFilters,
|
||||
};
|
||||
|
||||
|
||||
const response = await httpClient.sendRequest<SeekPage<PopulatedRecord>>({
|
||||
method: HttpMethod.GET,
|
||||
url: `${context.server.apiUrl}v1/records?${qs.stringify(request)}`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: context.server.token,
|
||||
},
|
||||
retries: 5,
|
||||
});
|
||||
|
||||
return response.body.data.map(tablesCommon.formatRecord);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,30 @@
|
||||
import { createAction, PieceAuth, Property } from '@activepieces/pieces-framework';
|
||||
import { tablesCommon } from '../common';
|
||||
import { AuthenticationType, httpClient, HttpMethod } from '@activepieces/pieces-common';
|
||||
import { PopulatedRecord } from '@activepieces/shared';
|
||||
|
||||
export const getRecord = createAction({
|
||||
name: 'tables-get-record',
|
||||
displayName: 'Get Record',
|
||||
description: 'Get single record by its id.',
|
||||
auth: PieceAuth.None(),
|
||||
props: {
|
||||
table_id: tablesCommon.table_id,
|
||||
record_id: tablesCommon.record_id,
|
||||
},
|
||||
async run(context) {
|
||||
const { record_id } = context.propsValue;
|
||||
|
||||
const response = await httpClient.sendRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: `${context.server.apiUrl}v1/records/${record_id}`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: context.server.token,
|
||||
},
|
||||
retries: 5,
|
||||
});
|
||||
|
||||
return tablesCommon.formatRecord(response.body as PopulatedRecord);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,64 @@
|
||||
import { createAction, PieceAuth, Property } from '@activepieces/pieces-framework';
|
||||
import { tablesCommon } from '../common';
|
||||
import { AuthenticationType, httpClient, HttpMethod, propsValidation } from '@activepieces/pieces-common';
|
||||
import { PopulatedRecord, UpdateRecordRequest } from '@activepieces/shared';
|
||||
|
||||
export const updateRecord = createAction({
|
||||
name: 'tables-update-record',
|
||||
displayName: 'Update Record',
|
||||
description: 'Update values in an existing record',
|
||||
auth: PieceAuth.None(),
|
||||
props: {
|
||||
table_id: tablesCommon.table_id,
|
||||
record_id: tablesCommon.record_id,
|
||||
values: Property.DynamicProperties({
|
||||
auth: PieceAuth.None(),
|
||||
displayName: 'Values',
|
||||
description: 'The values to update. Leave empty to keep current value.',
|
||||
required: true,
|
||||
refreshers: ['table_id'],
|
||||
props: async ({ table_id }, context) => {
|
||||
const tableExternalId = table_id as unknown as string;
|
||||
const tableId = await tablesCommon.convertTableExternalIdToId(tableExternalId, context);
|
||||
if ((tableId ?? '').toString().length === 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return tablesCommon.createFieldProperties({ tableId, context });
|
||||
},
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { table_id: tableExternalId, record_id, values } = context.propsValue;
|
||||
const tableId = await tablesCommon.convertTableExternalIdToId(tableExternalId, context);
|
||||
|
||||
const tableFields = await tablesCommon.getTableFields({ tableId, context });
|
||||
const fieldValidations = tablesCommon.createFieldValidations(tableFields);
|
||||
await propsValidation.validateZod(values, fieldValidations);
|
||||
|
||||
const cells: UpdateRecordRequest['cells'] = Object.entries(values)
|
||||
.filter(([_, value]) => value !== null && value !== undefined && value !== '')
|
||||
.map(([fieldExternalId, value]) => ({
|
||||
fieldId: tableFields.find((field) => field.externalId === fieldExternalId)?.id ?? '',
|
||||
value,
|
||||
})).filter((cell) => cell.fieldId !== '');
|
||||
|
||||
const request: UpdateRecordRequest = {
|
||||
cells,
|
||||
tableId,
|
||||
};
|
||||
|
||||
const response = await httpClient.sendRequest({
|
||||
method: HttpMethod.POST,
|
||||
url: `${context.server.apiUrl}v1/records/${record_id}`,
|
||||
body: request,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: context.server.token,
|
||||
},
|
||||
retries: 5,
|
||||
});
|
||||
|
||||
return tablesCommon.formatRecord(response.body as PopulatedRecord);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,317 @@
|
||||
import { AuthenticationType, httpClient, HttpMethod } from "@activepieces/pieces-common";
|
||||
import { DynamicPropsValue, PieceAuth, Property } from "@activepieces/pieces-framework";
|
||||
import { assertNotNullOrUndefined, CreateTableWebhookRequest, Field, FieldType, MarkdownVariant, PopulatedRecord, SeekPage, StaticDropdownEmptyOption, Table, TableWebhookEventType, ListTablesRequest } from "@activepieces/shared";
|
||||
import { z } from 'zod';
|
||||
import qs from 'qs';
|
||||
|
||||
type FormattedRecord = {
|
||||
id: string;
|
||||
created: string;
|
||||
updated: string;
|
||||
cells: Record<string, {
|
||||
fieldName: string;
|
||||
updated: string;
|
||||
created: string;
|
||||
value: unknown;
|
||||
}>;
|
||||
}
|
||||
const getFieldTypeText = (fieldType: FieldType) => {
|
||||
switch (fieldType) {
|
||||
case FieldType.STATIC_DROPDOWN:
|
||||
return 'Single Select';
|
||||
case FieldType.DATE:
|
||||
return 'Date';
|
||||
case FieldType.NUMBER:
|
||||
return 'Number';
|
||||
case FieldType.TEXT:
|
||||
return 'Text';
|
||||
}
|
||||
}
|
||||
export const tablesCommon = {
|
||||
table_id: Property.Dropdown({
|
||||
auth: PieceAuth.None(),
|
||||
displayName: 'Table Name',
|
||||
required: true,
|
||||
refreshers: [],
|
||||
refreshOnSearch: true,
|
||||
options: async (_propsValue, context) => {
|
||||
try {
|
||||
const tables = await fetchAllTables(context);
|
||||
if (!Array.isArray(tables) || tables.length === 0) {
|
||||
return {
|
||||
options: [],
|
||||
disabled: true,
|
||||
placeholder: 'No tables found. Please create a table first.',
|
||||
};
|
||||
}
|
||||
return {
|
||||
options: tables.map((table: Table) => ({ label: table.name, value: table.externalId })),
|
||||
};
|
||||
} catch (e) {
|
||||
console.error('Error fetching tables:', e);
|
||||
return {
|
||||
options: [],
|
||||
disabled: true,
|
||||
placeholder: 'Error loading tables. Please try again.',
|
||||
};
|
||||
}
|
||||
},
|
||||
}),
|
||||
|
||||
record_id: Property.ShortText({
|
||||
displayName: 'Record ID',
|
||||
description: 'The ID of the record to do the action on.',
|
||||
required: true,
|
||||
}),
|
||||
|
||||
async getTableFields({ tableId, context }: { tableId: string, context: { server: { apiUrl: string, token: string } } }) {
|
||||
const fieldsResponse = await httpClient.sendRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: `${context.server.apiUrl}v1/fields`,
|
||||
queryParams: {
|
||||
tableId,
|
||||
},
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: context.server.token,
|
||||
},
|
||||
});
|
||||
|
||||
return fieldsResponse.body as Field[];
|
||||
},
|
||||
|
||||
createFieldValidations(tableFields: Field[]) {
|
||||
const fieldValidations: Record<string, z.ZodType> = {};
|
||||
tableFields.forEach(field => {
|
||||
switch (field.type) {
|
||||
case FieldType.NUMBER:
|
||||
fieldValidations[field.id] = z.union([z.number(), z.string().transform(val => {
|
||||
const num = Number(val);
|
||||
if (isNaN(num)) throw new Error(`Invalid number for field "${field.name}"`);
|
||||
return num;
|
||||
})]).optional();
|
||||
break;
|
||||
case FieldType.DATE:
|
||||
fieldValidations[field.id] = z.union([z.date(), z.string().transform(val => {
|
||||
const date = new Date(val);
|
||||
if (isNaN(date.getTime())) throw new Error(`Invalid date for field "${field.name}"`);
|
||||
return date;
|
||||
})]).optional();
|
||||
break;
|
||||
default:
|
||||
fieldValidations[field.id] = z.string().optional();
|
||||
}
|
||||
});
|
||||
return fieldValidations;
|
||||
},
|
||||
|
||||
async createFieldProperties({ tableId, context }: { tableId: string, context: { server: { apiUrl: string, token: string } } }): Promise<DynamicPropsValue> {
|
||||
const fields: DynamicPropsValue = {};
|
||||
|
||||
try {
|
||||
const tableFields = await this.getTableFields({ tableId, context });
|
||||
if (!Array.isArray(tableFields) || tableFields.length === 0) {
|
||||
fields['markdown'] = Property.MarkDown({
|
||||
value: `We couldn't find any fields in the selected table. Please add fields to the table first.`,
|
||||
variant: MarkdownVariant.INFO,
|
||||
});
|
||||
return fields;
|
||||
}
|
||||
|
||||
for (const field of tableFields) {
|
||||
const description = getFieldTypeText(field.type);
|
||||
|
||||
switch (field.type) {
|
||||
case FieldType.NUMBER:
|
||||
fields[field.externalId] = Property.Number({
|
||||
displayName: field.name,
|
||||
description,
|
||||
required: false,
|
||||
});
|
||||
break;
|
||||
case FieldType.DATE:
|
||||
fields[field.externalId] = Property.DateTime({
|
||||
displayName: field.name,
|
||||
description,
|
||||
required: false,
|
||||
});
|
||||
break;
|
||||
case FieldType.STATIC_DROPDOWN:
|
||||
fields[field.externalId] = Property.StaticDropdown({
|
||||
displayName: field.name,
|
||||
description,
|
||||
defaultValue:'',
|
||||
required: false,
|
||||
options: {
|
||||
options:[StaticDropdownEmptyOption,...field.data.options.map(option => ({ label: option.value, value: option.value }))],
|
||||
},
|
||||
});
|
||||
break;
|
||||
default:
|
||||
fields[field.externalId] = Property.ShortText({
|
||||
displayName: field.name,
|
||||
description,
|
||||
required: false,
|
||||
defaultValue: '',
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return fields;
|
||||
} catch (e) {
|
||||
console.error('Error fetching fields:', e);
|
||||
fields['markdown'] = Property.MarkDown({
|
||||
value: `We couldn't find any fields in the selected table. Please add fields to the table first.`,
|
||||
variant: MarkdownVariant.INFO,
|
||||
});
|
||||
|
||||
return fields;
|
||||
}
|
||||
},
|
||||
|
||||
async createWebhook({
|
||||
tableId,
|
||||
events,
|
||||
webhookUrl,
|
||||
flowId,
|
||||
server,
|
||||
}: {
|
||||
tableId: string;
|
||||
events: TableWebhookEventType[];
|
||||
webhookUrl: string;
|
||||
flowId: string;
|
||||
server: { apiUrl: string, token: string };
|
||||
}) {
|
||||
const request: CreateTableWebhookRequest = {
|
||||
events,
|
||||
webhookUrl,
|
||||
flowId,
|
||||
}
|
||||
const response = await httpClient.sendRequest({
|
||||
method: HttpMethod.POST,
|
||||
url: `${server.apiUrl}v1/tables/${tableId}/webhooks`,
|
||||
body: request,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: server.token,
|
||||
},
|
||||
});
|
||||
|
||||
return response.body;
|
||||
},
|
||||
|
||||
async deleteWebhook({
|
||||
tableId,
|
||||
webhookId,
|
||||
server,
|
||||
}: {
|
||||
tableId: string;
|
||||
webhookId: string;
|
||||
server: { apiUrl: string, token: string };
|
||||
}) {
|
||||
const response = await httpClient.sendRequest({
|
||||
method: HttpMethod.DELETE,
|
||||
url: `${server.apiUrl}v1/tables/${tableId}/webhooks/${webhookId}`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: server.token,
|
||||
},
|
||||
});
|
||||
|
||||
return response.body;
|
||||
},
|
||||
|
||||
async getRecentRecords({
|
||||
tableId,
|
||||
limit = 5,
|
||||
context
|
||||
}: {
|
||||
tableId: string,
|
||||
limit?: number,
|
||||
context: { server: { apiUrl: string, token: string } }
|
||||
}) {
|
||||
if ((tableId ?? '').toString().length === 0) {
|
||||
throw new Error(JSON.stringify({
|
||||
message: 'Please add some records to the table before testing this trigger'
|
||||
}))
|
||||
}
|
||||
|
||||
const response = await httpClient.sendRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: `${context.server.apiUrl}v1/records?tableId=${tableId}&limit=${limit}`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: context.server.token,
|
||||
},
|
||||
});
|
||||
|
||||
return response.body.data.map(this.formatRecord);
|
||||
|
||||
},
|
||||
formatRecord(record: PopulatedRecord | { record: PopulatedRecord }): FormattedRecord {
|
||||
const actualRecord = 'record' in record ? record.record : record;
|
||||
|
||||
return {
|
||||
id: actualRecord.id,
|
||||
created: actualRecord.created,
|
||||
updated: actualRecord.updated,
|
||||
cells: actualRecord.cells ? Object.fromEntries(Object.entries(actualRecord.cells).map(([fieldId, cell]) => {
|
||||
return [fieldId, {
|
||||
fieldName: cell.fieldName,
|
||||
updated: cell.updated,
|
||||
created: cell.created,
|
||||
value: cell.value
|
||||
}]
|
||||
})) : {},
|
||||
}
|
||||
},
|
||||
|
||||
async convertTableExternalIdToId(tableId: string, context: { server: { apiUrl: string, token: string } }) {
|
||||
const list: ListTablesRequest = {
|
||||
externalIds: [tableId],
|
||||
}
|
||||
const res = await httpClient.sendRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: `${context.server.apiUrl}v1/tables?${qs.stringify(list)}`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: context.server.token,
|
||||
},
|
||||
});
|
||||
const table = (res.body as SeekPage<Table>).data[0];
|
||||
assertNotNullOrUndefined(table, `Table with externalId ${tableId} not found`);
|
||||
return table.id;
|
||||
}
|
||||
}
|
||||
|
||||
const fetchAllTables = async (context: { server: { apiUrl: string, token: string } }): Promise<Table[]> => {
|
||||
const res = await httpClient.sendRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: `${context.server.apiUrl}v1/tables?limit=100`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: context.server.token,
|
||||
},
|
||||
});
|
||||
const resultBody = res.body as SeekPage<Table>
|
||||
const tables = [...resultBody.data];
|
||||
if (!Array.isArray(tables) || tables.length === 0) {
|
||||
return [];
|
||||
}
|
||||
let next = resultBody.next;
|
||||
while (next) {
|
||||
const nextPage = await httpClient.sendRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: `${context.server.apiUrl}v1/tables?cursor=${next}&limit=100`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: context.server.token,
|
||||
},
|
||||
});
|
||||
const nextPageBody = nextPage.body as SeekPage<Table>
|
||||
tables.push(...nextPageBody.data)
|
||||
next = nextPageBody.next
|
||||
}
|
||||
return tables;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
import { createTrigger, PieceAuth, TriggerStrategy } from '@activepieces/pieces-framework';
|
||||
import { tablesCommon } from '../common';
|
||||
import { PopulatedRecord, TableWebhookEventType } from '@activepieces/shared';
|
||||
|
||||
export const deletedRecordTrigger = createTrigger({
|
||||
name: 'deletedRecord',
|
||||
displayName: 'Record Deleted',
|
||||
description: 'Triggers when a record is deleted from the selected table.',
|
||||
auth: PieceAuth.None(),
|
||||
props: {
|
||||
table_id: tablesCommon.table_id,
|
||||
},
|
||||
sampleData: {},
|
||||
type: TriggerStrategy.WEBHOOK,
|
||||
async onEnable(context) {
|
||||
const tableExternalId = context.propsValue.table_id;
|
||||
if ((tableExternalId ?? '').toString().length === 0) {
|
||||
return;
|
||||
}
|
||||
const tableId = await tablesCommon.convertTableExternalIdToId(tableExternalId, context);
|
||||
|
||||
const { id: webhookId } = await tablesCommon.createWebhook({
|
||||
tableId,
|
||||
events: [TableWebhookEventType.RECORD_DELETED],
|
||||
webhookUrl: context.webhookUrl,
|
||||
flowId: context.flows.current.id,
|
||||
server: {
|
||||
apiUrl: context.server.apiUrl,
|
||||
token: context.server.token,
|
||||
},
|
||||
});
|
||||
|
||||
context.store.put('webhookId', webhookId);
|
||||
},
|
||||
async onDisable(context) {
|
||||
const tableExternalId = context.propsValue.table_id;
|
||||
if ((tableExternalId ?? '').toString().length === 0) {
|
||||
return;
|
||||
}
|
||||
const tableId = await tablesCommon.convertTableExternalIdToId(tableExternalId, context);
|
||||
|
||||
const webhookId = await context.store.get<string>('webhookId');
|
||||
if (!webhookId) {
|
||||
return;
|
||||
}
|
||||
|
||||
await tablesCommon.deleteWebhook({
|
||||
tableId,
|
||||
webhookId: webhookId,
|
||||
server: {
|
||||
apiUrl: context.server.apiUrl,
|
||||
token: context.server.token,
|
||||
},
|
||||
});
|
||||
},
|
||||
async run(context) {
|
||||
return [tablesCommon.formatRecord(context.payload.body as PopulatedRecord)]
|
||||
},
|
||||
async test(context) {
|
||||
const tableId = await tablesCommon.convertTableExternalIdToId(context.propsValue.table_id, context);
|
||||
return tablesCommon.getRecentRecords({
|
||||
tableId,
|
||||
context
|
||||
});
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,65 @@
|
||||
import { createTrigger, PieceAuth, TriggerStrategy } from '@activepieces/pieces-framework';
|
||||
import { tablesCommon } from '../common';
|
||||
import { PopulatedRecord, TableWebhookEventType } from '@activepieces/shared';
|
||||
|
||||
export const newRecordTrigger = createTrigger({
|
||||
name: 'newRecord',
|
||||
displayName: 'New Record Created',
|
||||
description: 'Triggers when a new record is added to the selected table.',
|
||||
auth: PieceAuth.None(),
|
||||
props: {
|
||||
table_id: tablesCommon.table_id,
|
||||
},
|
||||
sampleData: {},
|
||||
type: TriggerStrategy.WEBHOOK,
|
||||
async onEnable(context){
|
||||
const tableExternalId = context.propsValue.table_id;
|
||||
if ((tableExternalId ?? '').toString().length === 0) {
|
||||
return;
|
||||
}
|
||||
const tableId = await tablesCommon.convertTableExternalIdToId(tableExternalId, context);
|
||||
|
||||
const { id: webhookId } = await tablesCommon.createWebhook({
|
||||
tableId,
|
||||
events: [TableWebhookEventType.RECORD_CREATED],
|
||||
webhookUrl: context.webhookUrl,
|
||||
flowId: context.flows.current.id,
|
||||
server: {
|
||||
apiUrl: context.server.apiUrl,
|
||||
token: context.server.token,
|
||||
},
|
||||
});
|
||||
|
||||
context.store.put('webhookId', webhookId);
|
||||
},
|
||||
async onDisable(context){
|
||||
const tableExternalId = context.propsValue.table_id;
|
||||
if ((tableExternalId ?? '').toString().length === 0) {
|
||||
return;
|
||||
}
|
||||
const tableId = await tablesCommon.convertTableExternalIdToId(tableExternalId, context);
|
||||
const webhookId = await context.store.get<string>('webhookId');
|
||||
if (!webhookId) {
|
||||
return;
|
||||
}
|
||||
|
||||
await tablesCommon.deleteWebhook({
|
||||
tableId,
|
||||
webhookId: webhookId,
|
||||
server: {
|
||||
apiUrl: context.server.apiUrl,
|
||||
token: context.server.token,
|
||||
},
|
||||
});
|
||||
},
|
||||
async run(context){
|
||||
return [tablesCommon.formatRecord(context.payload.body as PopulatedRecord)]
|
||||
},
|
||||
async test(context) {
|
||||
const tableId = await tablesCommon.convertTableExternalIdToId(context.propsValue.table_id, context);
|
||||
return tablesCommon.getRecentRecords({
|
||||
tableId,
|
||||
context
|
||||
});
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,66 @@
|
||||
import { createTrigger, PieceAuth, TriggerStrategy } from '@activepieces/pieces-framework';
|
||||
import { tablesCommon } from '../common';
|
||||
import { PopulatedRecord, TableWebhookEventType } from '@activepieces/shared';
|
||||
|
||||
export const updatedRecordTrigger = createTrigger({
|
||||
name: 'updatedRecord',
|
||||
displayName: 'Record Updated',
|
||||
description: 'Triggers when a record is updated in the selected table.',
|
||||
auth: PieceAuth.None(),
|
||||
props: {
|
||||
table_id: tablesCommon.table_id,
|
||||
},
|
||||
sampleData: {},
|
||||
type: TriggerStrategy.WEBHOOK,
|
||||
async onEnable(context) {
|
||||
const tableExternalId = context.propsValue.table_id;
|
||||
if ((tableExternalId ?? '').toString().length === 0) {
|
||||
return;
|
||||
}
|
||||
const tableId = await tablesCommon.convertTableExternalIdToId(tableExternalId, context);
|
||||
|
||||
const { id: webhookId } = await tablesCommon.createWebhook({
|
||||
tableId,
|
||||
events: [TableWebhookEventType.RECORD_UPDATED],
|
||||
webhookUrl: context.webhookUrl,
|
||||
flowId: context.flows.current.id,
|
||||
server: {
|
||||
apiUrl: context.server.apiUrl,
|
||||
token: context.server.token,
|
||||
},
|
||||
});
|
||||
|
||||
context.store.put('webhookId', webhookId);
|
||||
},
|
||||
async onDisable(context) {
|
||||
const tableExternalId = context.propsValue.table_id;
|
||||
if ((tableExternalId ?? '').toString().length === 0) {
|
||||
return;
|
||||
}
|
||||
const tableId = await tablesCommon.convertTableExternalIdToId(tableExternalId, context);
|
||||
|
||||
const webhookId = await context.store.get<string>('webhookId');
|
||||
if (!webhookId) {
|
||||
return;
|
||||
}
|
||||
|
||||
await tablesCommon.deleteWebhook({
|
||||
tableId,
|
||||
webhookId: webhookId,
|
||||
server: {
|
||||
apiUrl: context.server.apiUrl,
|
||||
token: context.server.token,
|
||||
},
|
||||
});
|
||||
},
|
||||
async run(context) {
|
||||
return [tablesCommon.formatRecord(context.payload.body as PopulatedRecord)]
|
||||
},
|
||||
async test(context) {
|
||||
const tableId = await tablesCommon.convertTableExternalIdToId(context.propsValue.table_id, context);
|
||||
return tablesCommon.getRecentRecords({
|
||||
tableId,
|
||||
context
|
||||
});
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user