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,18 @@
|
||||
{
|
||||
"extends": ["../../../../.eslintrc.json"],
|
||||
"ignorePatterns": ["!**/*"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.ts", "*.tsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# pieces-supabase
|
||||
|
||||
This library was generated with [Nx](https://nx.dev).
|
||||
|
||||
## Building
|
||||
|
||||
Run `nx build pieces-supabase` to build the library.
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "@activepieces/piece-supabase",
|
||||
"version": "0.0.19",
|
||||
"dependencies": {
|
||||
"@supabase/supabase-js": "2.49.9"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"name": "pieces-supabase",
|
||||
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "packages/pieces/community/supabase/src",
|
||||
"projectType": "library",
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@nx/js:tsc",
|
||||
"outputs": [
|
||||
"{options.outputPath}"
|
||||
],
|
||||
"options": {
|
||||
"outputPath": "dist/packages/pieces/community/supabase",
|
||||
"tsConfig": "packages/pieces/community/supabase/tsconfig.lib.json",
|
||||
"packageJson": "packages/pieces/community/supabase/package.json",
|
||||
"main": "packages/pieces/community/supabase/src/index.ts",
|
||||
"assets": [
|
||||
"packages/pieces/community/supabase/*.md",
|
||||
{
|
||||
"input": "packages/pieces/community/supabase/src/i18n",
|
||||
"output": "./src/i18n",
|
||||
"glob": "**/!(i18n.json)"
|
||||
}
|
||||
],
|
||||
"buildableProjectDepsInPackageJsonType": "dependencies",
|
||||
"updateBuildableProjectDepsInPackageJson": true
|
||||
},
|
||||
"dependsOn": [
|
||||
"^build",
|
||||
"prebuild"
|
||||
]
|
||||
},
|
||||
"publish": {
|
||||
"command": "node tools/scripts/publish.mjs pieces-supabase {args.ver} {args.tag}",
|
||||
"dependsOn": [
|
||||
"build"
|
||||
]
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint",
|
||||
"outputs": [
|
||||
"{options.outputFile}"
|
||||
]
|
||||
},
|
||||
"prebuild": {
|
||||
"executor": "nx:run-commands",
|
||||
"options": {
|
||||
"cwd": "packages/pieces/community/supabase",
|
||||
"command": "bun install --no-save --silent"
|
||||
},
|
||||
"dependsOn": [
|
||||
"^build"
|
||||
]
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"Supabase": "Supabase",
|
||||
"The open-source Firebase alternative": "The open-source Firebase alternative",
|
||||
"URL": "URL",
|
||||
"API Key": "API Key",
|
||||
"\nCopy the **URL** and **Service API Key** from your Supabase project settings.\n": "\nCopy the **URL** and **Service API Key** from your Supabase project settings.\n",
|
||||
"Upload File": "Upload File",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Upload a file to Supabase Storage": "Upload a file to Supabase Storage",
|
||||
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
|
||||
"File path": "File path",
|
||||
"Bucket": "Bucket",
|
||||
"Base64 or URL": "Base64 or URL",
|
||||
"Method": "Method",
|
||||
"Headers": "Headers",
|
||||
"Query Parameters": "Query Parameters",
|
||||
"Body": "Body",
|
||||
"No Error on Failure": "No Error on Failure",
|
||||
"Timeout (in seconds)": "Timeout (in seconds)",
|
||||
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
|
||||
"GET": "GET",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "DELETE",
|
||||
"HEAD": "HEAD"
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
{
|
||||
"The open-source Firebase alternative": "Die Open-Source Firebase-Alternative",
|
||||
"Project URL": "Project URL",
|
||||
"API Key": "API-Schlüssel",
|
||||
"Your Supabase project URL (e.g., https://your-project-ref.supabase.co)": "Your Supabase project URL (e.g., https://your-project-ref.supabase.co)",
|
||||
"Service Role Key (for actions) or Anonymous Key (for basic triggers)": "Service Role Key (for actions) or Anonymous Key (for basic triggers)",
|
||||
"\n## Supabase Connection Setup\n\n### 1. Get Your Project URL\n- Go to your [Supabase Dashboard](https://supabase.com/dashboard)\n- Select your project\n- Go to **Settings** → **API**\n- Copy the **Project URL** (format: `https://your-project-ref.supabase.co`)\n\n### 2. Get Your API Key\nChoose the appropriate key based on your use case:\n\n**For Actions (Database Operations):**\n- Use **Service Role Key** (secret) for server-side operations\n- Has full access to bypass Row Level Security (RLS)\n\n**For Triggers (Webhooks)": "\n## Supabase Connection Setup\n\n### 1. Get Your Project URL\n- Go to your [Supabase Dashboard](https://supabase.com/dashboard)\n- Select your project\n- Go to **Settings** → **API**\n- Copy the **Project URL** (format: `https://your-project-ref.supabase.co`)\n\n### 2. Get Your API Key\nChoose the appropriate key based on your use case:\n\n**For Actions (Database Operations):**\n- Use **Service Role Key** (secret) for server-side operations\n- Has full access to bypass Row Level Security (RLS)\n\n**For Triggers (Webhooks):**\n- Use **Anonymous Key** (public) if your webhooks don't need elevated permissions\n- Use **Service Role Key** for elevated permissions\n\n**Security Note:** Keep your Service Role Key secret - it bypasses all RLS policies.\n\nFind your keys in **Settings** → **API** → **Project API keys**\n",
|
||||
"Upload File": "Datei hochladen",
|
||||
"Create Row": "Zeile erstellen",
|
||||
"Update Row": "Zeile aktualisieren",
|
||||
"Upsert Row": "Upsert-Zeile",
|
||||
"Delete Rows": "Delete Rows",
|
||||
"Search Rows": "Search Rows",
|
||||
"Custom API Call": "Eigener API-Aufruf",
|
||||
"Upload a file to Supabase Storage": "Datei zum Supabase-Speicher hochladen",
|
||||
"Create a new row in a table": "Create a new row in a table",
|
||||
"Update rows in a table based on filter criteria": "Update rows in a table based on filter criteria",
|
||||
"Insert or update a row in a table": "Insert or update a row in a table",
|
||||
"Remove rows matching filter criteria from a table": "Remove rows matching filter criteria from a table",
|
||||
"Search for rows in a table with filters and pagination": "Search for rows in a table with filters and pagination",
|
||||
"Make a custom API call to a specific endpoint": "Einen benutzerdefinierten API-Aufruf an einen bestimmten Endpunkt machen",
|
||||
"File path": "Dateipfad",
|
||||
"Bucket": "Eimer",
|
||||
"Base64 or URL": "Base64 oder URL",
|
||||
"Table Name": "Tabellenname",
|
||||
"Row Data": "Zeilendaten",
|
||||
"Return Created Row": "Return Created Row",
|
||||
"Filter Type": "Filter Type",
|
||||
"Filter Column": "Filter Column",
|
||||
"Filter Value": "Filter Value",
|
||||
"Filter Values": "Filter Values",
|
||||
"Update Data": "Update Data",
|
||||
"Count Updated Rows": "Count Updated Rows",
|
||||
"Return Updated Rows": "Return Updated Rows",
|
||||
"Conflict Column": "Conflict Column",
|
||||
"Count Upserted Rows": "Count Upserted Rows",
|
||||
"Return Upserted Rows": "Return Upserted Rows",
|
||||
"Count Deleted Rows": "Count Deleted Rows",
|
||||
"Return Deleted Rows": "Return Deleted Rows",
|
||||
"Columns": "Spalten",
|
||||
"Filters": "Filter",
|
||||
"Page": "Seite",
|
||||
"Page Size": "Einträge pro Seite",
|
||||
"Count Algorithm": "Count Algorithm",
|
||||
"Method": "Methode",
|
||||
"Headers": "Kopfzeilen",
|
||||
"Query Parameters": "Abfrageparameter",
|
||||
"Body": "Körper",
|
||||
"Response is Binary ?": "Antwort ist binär?",
|
||||
"No Error on Failure": "Kein Fehler bei Fehler",
|
||||
"Timeout (in seconds)": "Timeout (in Sekunden)",
|
||||
"Select a table from your database": "Select a table from your database",
|
||||
"Enter the data for each column": "Enter the data for each column",
|
||||
"Whether to return the created row": "Whether to return the created row",
|
||||
"How to identify rows to update": "How to identify rows to update",
|
||||
"Select the column to filter on": "Wählen Sie die zu filternde Spalte",
|
||||
"The value to match against (not used for \"in list\" filter)": "Der zu treffende Wert (nicht für den Filter in der Liste)",
|
||||
"List of values for \"in list\" filter type": "Liste der Werte für den Filtertyp \"in der Liste\"",
|
||||
"Select which columns to update (auto-generated fields excluded)": "Wählen Sie die zu aktualisierenden Spalten (automatisch generierte Felder ausgeschlossen)",
|
||||
"Whether to count the number of updated rows": "Ob die Anzahl der aktualisierten Zeilen gezählt werden soll",
|
||||
"Whether to return the updated rows data": "Gibt an, ob die aktualisierten Datensätze zurückgegeben werden sollen",
|
||||
"Select the unique column to determine duplicates (required for upsert to work)": "Wählen Sie die eindeutige Spalte, um Duplikate zu bestimmen (erforderlich für Upsert zum Arbeiten)",
|
||||
"Enter data for the row (conflict detection handled separately)": "Geben Sie Daten für die Zeile ein (Konflikterkennung wird separat behandelt)",
|
||||
"Whether to count the number of upserted rows": "Ob die Anzahl der hochgeladenen Zeilen gezählt werden soll",
|
||||
"Whether to return the upserted rows data": "Gibt an, ob die gespeicherten Datensätze zurückgegeben werden sollen",
|
||||
"How to filter rows for deletion": "Filtern von Zeilen zum Löschen",
|
||||
"The value to match against (not used for null checks)": "Der übereinstimmende Wert (nicht für Nullprüfungen verwendet)",
|
||||
"List of values for \"in\" filter type": "Liste der Werte für den Filtertyp \"in\"",
|
||||
"Whether to count the number of deleted rows": "Gibt an, ob die Anzahl der gelöschten Zeilen gezählt werden soll",
|
||||
"Whether to return the deleted rows data": "Gibt an, ob die gelöschten Datensätze zurückgegeben werden sollen",
|
||||
"Columns to return (comma-separated). Leave empty to return all columns.": "Spalten zurückgeben (kommasepariert). Leer lassen um alle Spalten zurückzugeben.",
|
||||
"List of filters to apply": "Liste der anzuwendenden Filter",
|
||||
"Page number for pagination (starts from 1)": "Seitenzahl für Seitenzahl (beginnt ab 1)",
|
||||
"Number of records per page (max 1000)": "Anzahl der Datensätze pro Seite (max. 1000)",
|
||||
"Algorithm to use for counting rows": "Algorithmus zum Zählen von Zeilen",
|
||||
"Authorization headers are injected automatically from your connection.": "Autorisierungs-Header werden automatisch von Ihrer Verbindung injiziert.",
|
||||
"Enable for files like PDFs, images, etc..": "Aktivieren für Dateien wie PDFs, Bilder, etc..",
|
||||
"Column equals value": "Spalte entspricht dem Wert",
|
||||
"Column is in list of values": "Spalte ist in der Liste der Werte",
|
||||
"Column is greater than value": "Spalte ist größer als Wert",
|
||||
"Column not equals value": "Spalte entspricht nicht dem Wert",
|
||||
"Column is in list": "Spalte ist in der Liste",
|
||||
"Column is greater than": "Spalte ist größer als",
|
||||
"Column is greater than or equal": "Spalte ist größer oder gleich",
|
||||
"Column is less than": "Spalte ist kleiner als",
|
||||
"Column is less than or equal": "Spalte ist kleiner oder gleich",
|
||||
"Column is null": "Spalte ist null",
|
||||
"Column is not null": "Spalte ist nicht null",
|
||||
"Column matches pattern (LIKE)": "Spaltentreffen-Muster (LIKE)",
|
||||
"Column matches pattern (case-insensitive)": "Spalte entspricht dem Muster (Groß- und Kleinschreibung)",
|
||||
"Exact": "Exakt",
|
||||
"Planned": "Geplant",
|
||||
"Estimated": "Geschätzt",
|
||||
"GET": "ERHALTEN",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "LÖSCHEN",
|
||||
"HEAD": "HEAD",
|
||||
"New Row": "Neue Zeile",
|
||||
"Fires when a new row is created in a table": "Feuert ab, wenn eine neue Zeile in einer Tabelle erstellt wird",
|
||||
"Markdown": "Markdown",
|
||||
"Schema": "Schema",
|
||||
"## Setup Instructions\n\n1. **Go to your Supabase Dashboard** → Database → Webhooks\n2. **Click \"Create a new hook\"**\n3. **Configure the webhook:**\n - **Name**: Give it a descriptive name (e.g., \"Activepieces New Row\")\n - **Table**: Select the table you want to monitor\n - **Events**: Check \"Insert\" \n - **Type**: HTTP Request\n - **Method**: POST\n - **URL**: Copy and paste the webhook URL below\n4. **Click \"Create webhook\"**\n\n**Webhook URL:** `{{webhookUrl}}`\n\n## Important Notes\n- The webhook will sen": "## Setup Instructions\n\n1. **Go to your Supabase Dashboard** → Database → Webhooks\n2. **Click \"Create a new hook\"**\n3. **Configure the webhook:**\n - **Name**: Give it a descriptive name (e.g., \"Activepieces New Row\")\n - **Table**: Select the table you want to monitor\n - **Events**: Check \"Insert\" \n - **Type**: HTTP Request\n - **Method**: POST\n - **URL**: Copy and paste the webhook URL below\n4. **Click \"Create webhook\"**\n\n**Webhook URL:** `{{webhookUrl}}`\n\n## Important Notes\n- The webhook will send a JSON payload with the new row data\n- Make sure your table has the necessary permissions\n- You can test the webhook by inserting a new row into your table\n\nFor more details, see [Supabase Database Webhooks documentation](https://supabase.com/docs/guides/database/webhooks).",
|
||||
"Database schema (default: public)": "Datenbankschema (Standard: öffentlich)"
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
{
|
||||
"The open-source Firebase alternative": "La alternativa de Firebase de código abierto",
|
||||
"Project URL": "Project URL",
|
||||
"API Key": "Clave API",
|
||||
"Your Supabase project URL (e.g., https://your-project-ref.supabase.co)": "Your Supabase project URL (e.g., https://your-project-ref.supabase.co)",
|
||||
"Service Role Key (for actions) or Anonymous Key (for basic triggers)": "Service Role Key (for actions) or Anonymous Key (for basic triggers)",
|
||||
"\n## Supabase Connection Setup\n\n### 1. Get Your Project URL\n- Go to your [Supabase Dashboard](https://supabase.com/dashboard)\n- Select your project\n- Go to **Settings** → **API**\n- Copy the **Project URL** (format: `https://your-project-ref.supabase.co`)\n\n### 2. Get Your API Key\nChoose the appropriate key based on your use case:\n\n**For Actions (Database Operations):**\n- Use **Service Role Key** (secret) for server-side operations\n- Has full access to bypass Row Level Security (RLS)\n\n**For Triggers (Webhooks)": "\n## Supabase Connection Setup\n\n### 1. Get Your Project URL\n- Go to your [Supabase Dashboard](https://supabase.com/dashboard)\n- Select your project\n- Go to **Settings** → **API**\n- Copy the **Project URL** (format: `https://your-project-ref.supabase.co`)\n\n### 2. Get Your API Key\nChoose the appropriate key based on your use case:\n\n**For Actions (Database Operations):**\n- Use **Service Role Key** (secret) for server-side operations\n- Has full access to bypass Row Level Security (RLS)\n\n**For Triggers (Webhooks):**\n- Use **Anonymous Key** (public) if your webhooks don't need elevated permissions\n- Use **Service Role Key** for elevated permissions\n\n**Security Note:** Keep your Service Role Key secret - it bypasses all RLS policies.\n\nFind your keys in **Settings** → **API** → **Project API keys**\n",
|
||||
"Upload File": "Subir archivo",
|
||||
"Create Row": "Crear fila",
|
||||
"Update Row": "Actualizar fila",
|
||||
"Upsert Row": "Subir fila",
|
||||
"Delete Rows": "Delete Rows",
|
||||
"Search Rows": "Search Rows",
|
||||
"Custom API Call": "Llamada API personalizada",
|
||||
"Upload a file to Supabase Storage": "Subir un archivo a Supabase Storage",
|
||||
"Create a new row in a table": "Create a new row in a table",
|
||||
"Update rows in a table based on filter criteria": "Update rows in a table based on filter criteria",
|
||||
"Insert or update a row in a table": "Insert or update a row in a table",
|
||||
"Remove rows matching filter criteria from a table": "Remove rows matching filter criteria from a table",
|
||||
"Search for rows in a table with filters and pagination": "Search for rows in a table with filters and pagination",
|
||||
"Make a custom API call to a specific endpoint": "Hacer una llamada API personalizada a un extremo específico",
|
||||
"File path": "Ruta del archivo",
|
||||
"Bucket": "Cubo",
|
||||
"Base64 or URL": "Base64 o URL",
|
||||
"Table Name": "Nombre de tabla",
|
||||
"Row Data": "Datos de fila",
|
||||
"Return Created Row": "Return Created Row",
|
||||
"Filter Type": "Filter Type",
|
||||
"Filter Column": "Filter Column",
|
||||
"Filter Value": "Filter Value",
|
||||
"Filter Values": "Filter Values",
|
||||
"Update Data": "Update Data",
|
||||
"Count Updated Rows": "Count Updated Rows",
|
||||
"Return Updated Rows": "Return Updated Rows",
|
||||
"Conflict Column": "Conflict Column",
|
||||
"Count Upserted Rows": "Count Upserted Rows",
|
||||
"Return Upserted Rows": "Return Upserted Rows",
|
||||
"Count Deleted Rows": "Count Deleted Rows",
|
||||
"Return Deleted Rows": "Return Deleted Rows",
|
||||
"Columns": "Columnas",
|
||||
"Filters": "Filtros",
|
||||
"Page": "Pgina",
|
||||
"Page Size": "Tamaño de página",
|
||||
"Count Algorithm": "Count Algorithm",
|
||||
"Method": "Método",
|
||||
"Headers": "Encabezados",
|
||||
"Query Parameters": "Parámetros de consulta",
|
||||
"Body": "Cuerpo",
|
||||
"Response is Binary ?": "¿Respuesta es binaria?",
|
||||
"No Error on Failure": "No hay ningún error en fallo",
|
||||
"Timeout (in seconds)": "Tiempo de espera (en segundos)",
|
||||
"Select a table from your database": "Select a table from your database",
|
||||
"Enter the data for each column": "Enter the data for each column",
|
||||
"Whether to return the created row": "Whether to return the created row",
|
||||
"How to identify rows to update": "How to identify rows to update",
|
||||
"Select the column to filter on": "Select the column to filter on",
|
||||
"The value to match against (not used for \"in list\" filter)": "The value to match against (not used for \"in list\" filter)",
|
||||
"List of values for \"in list\" filter type": "List of values for \"in list\" filter type",
|
||||
"Select which columns to update (auto-generated fields excluded)": "Select which columns to update (auto-generated fields excluded)",
|
||||
"Whether to count the number of updated rows": "Whether to count the number of updated rows",
|
||||
"Whether to return the updated rows data": "Whether to return the updated rows data",
|
||||
"Select the unique column to determine duplicates (required for upsert to work)": "Select the unique column to determine duplicates (required for upsert to work)",
|
||||
"Enter data for the row (conflict detection handled separately)": "Enter data for the row (conflict detection handled separately)",
|
||||
"Whether to count the number of upserted rows": "Whether to count the number of upserted rows",
|
||||
"Whether to return the upserted rows data": "Whether to return the upserted rows data",
|
||||
"How to filter rows for deletion": "How to filter rows for deletion",
|
||||
"The value to match against (not used for null checks)": "The value to match against (not used for null checks)",
|
||||
"List of values for \"in\" filter type": "List of values for \"in\" filter type",
|
||||
"Whether to count the number of deleted rows": "Whether to count the number of deleted rows",
|
||||
"Whether to return the deleted rows data": "Whether to return the deleted rows data",
|
||||
"Columns to return (comma-separated). Leave empty to return all columns.": "Columns to return (comma-separated). Leave empty to return all columns.",
|
||||
"List of filters to apply": "List of filters to apply",
|
||||
"Page number for pagination (starts from 1)": "Page number for pagination (starts from 1)",
|
||||
"Number of records per page (max 1000)": "Number of records per page (max 1000)",
|
||||
"Algorithm to use for counting rows": "Algorithm to use for counting rows",
|
||||
"Authorization headers are injected automatically from your connection.": "Las cabeceras de autorización se inyectan automáticamente desde tu conexión.",
|
||||
"Enable for files like PDFs, images, etc..": "Activar para archivos como PDFs, imágenes, etc.",
|
||||
"Column equals value": "Column equals value",
|
||||
"Column is in list of values": "Column is in list of values",
|
||||
"Column is greater than value": "Column is greater than value",
|
||||
"Column not equals value": "Column not equals value",
|
||||
"Column is in list": "Column is in list",
|
||||
"Column is greater than": "Column is greater than",
|
||||
"Column is greater than or equal": "Column is greater than or equal",
|
||||
"Column is less than": "Column is less than",
|
||||
"Column is less than or equal": "Column is less than or equal",
|
||||
"Column is null": "Column is null",
|
||||
"Column is not null": "Column is not null",
|
||||
"Column matches pattern (LIKE)": "Column matches pattern (LIKE)",
|
||||
"Column matches pattern (case-insensitive)": "La columna coincide con el patrón (mayúsculas y minúsculas)",
|
||||
"Exact": "Exacto",
|
||||
"Planned": "Planeado",
|
||||
"Estimated": "Estimado",
|
||||
"GET": "RECOGER",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "BORRAR",
|
||||
"HEAD": "LIMPIO",
|
||||
"New Row": "Nueva fila",
|
||||
"Fires when a new row is created in a table": "Dispara cuando se crea una nueva fila en una tabla",
|
||||
"Markdown": "Markdown",
|
||||
"Schema": "Esquema",
|
||||
"## Setup Instructions\n\n1. **Go to your Supabase Dashboard** → Database → Webhooks\n2. **Click \"Create a new hook\"**\n3. **Configure the webhook:**\n - **Name**: Give it a descriptive name (e.g., \"Activepieces New Row\")\n - **Table**: Select the table you want to monitor\n - **Events**: Check \"Insert\" \n - **Type**: HTTP Request\n - **Method**: POST\n - **URL**: Copy and paste the webhook URL below\n4. **Click \"Create webhook\"**\n\n**Webhook URL:** `{{webhookUrl}}`\n\n## Important Notes\n- The webhook will sen": "## Configurar Instrucciones\n\n1. **Ve a tu Tablero de Suaba** → Base de datos → Webhooks\n\n. **Haz clic en \"Crear un nuevo hook\"**\n3. **Configura el webhook:**\n - **Nombre**: Dale un nombre descriptivo (p.e. \"Activepieces New Row\")\n - **Tabla**: Selecciona la tabla que quieres monitorizar\n - **Eventos**: Comprueba \"Insertar\" \n - **Tipo**: HTTP Request\n - **Método**: POST\n - **URL**: Copia y pega la URL del webhook debajo de\n4. **Haz clic en \"Crear webhook\"**\n\n**Webhook URL:** `{{webhookUrl}}` \n\n ## Notas Importantes\n- El webhook enviará una carga JSON con los nuevos datos de fila\n- Asegúrate de que tu tabla tiene los permisos necesarios\n- Puedes probar el webhook insertando una nueva fila en tu tabla\n\nPara más detalles, vea [Suabase Database Webhooks documentation](https://supabase.com/docs/guides/database/webhooks).",
|
||||
"Database schema (default: public)": "Esquema de base de datos (por defecto: público)"
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
{
|
||||
"The open-source Firebase alternative": "L'alternative Firebase open-source",
|
||||
"Project URL": "URL du projet",
|
||||
"API Key": "Clé API",
|
||||
"Your Supabase project URL (e.g., https://your-project-ref.supabase.co)": "URL de votre projet Supabase (par exemple, https://votre-projet-ref.supabase.co)",
|
||||
"Service Role Key (for actions) or Anonymous Key (for basic triggers)": "Clé de rôle du service (pour les actions) ou clé anonyme (pour les déclencheurs de base)",
|
||||
"\n## Supabase Connection Setup\n\n### 1. Get Your Project URL\n- Go to your [Supabase Dashboard](https://supabase.com/dashboard)\n- Select your project\n- Go to **Settings** → **API**\n- Copy the **Project URL** (format: `https://your-project-ref.supabase.co`)\n\n### 2. Get Your API Key\nChoose the appropriate key based on your use case:\n\n**For Actions (Database Operations):**\n- Use **Service Role Key** (secret) for server-side operations\n- Has full access to bypass Row Level Security (RLS)\n\n**For Triggers (Webhooks)": "\n## Supabase Connection Setup\n\n### 1. Get Your Project URL\n- Go to your [Supabase Dashboard](https://supabase.com/dashboard)\n- Select your project\n- Go to **Settings** → **API**\n- Copy the **Project URL** (format: `https://your-project-ref.supabase.co`)\n\n### 2. Get Your API Key\nChoose the appropriate key based on your use case:\n\n**For Actions (Database Operations):**\n- Use **Service Role Key** (secret) for server-side operations\n- Has full access to bypass Row Level Security (RLS)\n\n**For Triggers (Webhooks):**\n- Use **Anonymous Key** (public) if your webhooks don't need elevated permissions\n- Use **Service Role Key** for elevated permissions\n\n**Security Note:** Keep your Service Role Key secret - it bypasses all RLS policies.\n\nFind your keys in **Settings** → **API** → **Project API keys**\n",
|
||||
"Upload File": "Charger un fichier",
|
||||
"Create Row": "Créer une ligne",
|
||||
"Update Row": "Mettre à jour la ligne",
|
||||
"Upsert Row": "Lignée supérieure",
|
||||
"Delete Rows": "Supprimer les lignes",
|
||||
"Search Rows": "Rechercher des lignes",
|
||||
"Custom API Call": "Appel d'API personnalisé",
|
||||
"Upload a file to Supabase Storage": "Télécharger un fichier sur Supabase Storage",
|
||||
"Create a new row in a table": "Créer une nouvelle ligne dans une table",
|
||||
"Update rows in a table based on filter criteria": "Mettre à jour les lignes dans une table en fonction des critères de filtre",
|
||||
"Insert or update a row in a table": "Insérer ou mettre à jour une ligne dans une table",
|
||||
"Remove rows matching filter criteria from a table": "Supprimer les lignes correspondant aux critères de filtre d'une table",
|
||||
"Search for rows in a table with filters and pagination": "Rechercher des lignes dans une table avec filtres et pagination",
|
||||
"Make a custom API call to a specific endpoint": "Passer un appel API personnalisé à un endpoint spécifique",
|
||||
"File path": "Chemin du fichier",
|
||||
"Bucket": "Seau",
|
||||
"Base64 or URL": "Base64 ou URL",
|
||||
"Table Name": "Nom de la table",
|
||||
"Row Data": "Données de la ligne",
|
||||
"Return Created Row": "Revenir à la ligne créée",
|
||||
"Filter Type": "Type de filtre",
|
||||
"Filter Column": "Filtrer la colonne",
|
||||
"Filter Value": "Valeur du filtre",
|
||||
"Filter Values": "Filtrer les valeurs",
|
||||
"Update Data": "Mettre à jour les données",
|
||||
"Count Updated Rows": "Nombre de lignes mises à jour",
|
||||
"Return Updated Rows": "Lignes de retour mises à jour",
|
||||
"Conflict Column": "Colonne de conflit",
|
||||
"Count Upserted Rows": "Compter les lignes montées",
|
||||
"Return Upserted Rows": "Retourner les lignes montées",
|
||||
"Count Deleted Rows": "Nombre de lignes supprimées",
|
||||
"Return Deleted Rows": "Retourner les lignes supprimées",
|
||||
"Columns": "Colonnes",
|
||||
"Filters": "Filtres",
|
||||
"Page": "Page",
|
||||
"Page Size": "Nombre d'élément",
|
||||
"Count Algorithm": "Algorithme de compte",
|
||||
"Method": "Méthode",
|
||||
"Headers": "En-têtes",
|
||||
"Query Parameters": "Paramètres de requête",
|
||||
"Body": "Corps",
|
||||
"Response is Binary ?": "La réponse est Binaire ?",
|
||||
"No Error on Failure": "Aucune erreur en cas d'échec",
|
||||
"Timeout (in seconds)": "Délai d'expiration (en secondes)",
|
||||
"Select a table from your database": "Sélectionnez une table dans votre base de données",
|
||||
"Enter the data for each column": "Entrez les données pour chaque colonne",
|
||||
"Whether to return the created row": "Retourner ou non la ligne créée",
|
||||
"How to identify rows to update": "Comment identifier les lignes à mettre à jour",
|
||||
"Select the column to filter on": "Sélectionnez la colonne sur laquelle filtrer",
|
||||
"The value to match against (not used for \"in list\" filter)": "La valeur à rechercher (pas utilisée pour le filtre \"dans la liste\")",
|
||||
"List of values for \"in list\" filter type": "Liste des valeurs pour le type de filtre \"dans la liste\"",
|
||||
"Select which columns to update (auto-generated fields excluded)": "Sélectionner les colonnes à mettre à jour (champs auto-générés exclus)",
|
||||
"Whether to count the number of updated rows": "S'il faut compter le nombre de lignes mises à jour",
|
||||
"Whether to return the updated rows data": "Retourner ou non les données des lignes mises à jour",
|
||||
"Select the unique column to determine duplicates (required for upsert to work)": "Sélectionnez la colonne unique pour déterminer les doublons (requis pour que la mise à jour fonctionne)",
|
||||
"Enter data for the row (conflict detection handled separately)": "Entrer les données de la ligne (détection de conflits gérée séparément)",
|
||||
"Whether to count the number of upserted rows": "S'il faut compter le nombre de lignes mises à jour",
|
||||
"Whether to return the upserted rows data": "Renvoie des données des lignes en amont",
|
||||
"How to filter rows for deletion": "Comment filtrer les lignes pour la suppression",
|
||||
"The value to match against (not used for null checks)": "La valeur à rechercher (pas utilisée pour les vérifications nulles)",
|
||||
"List of values for \"in\" filter type": "Liste des valeurs pour le type de filtre \"in\"",
|
||||
"Whether to count the number of deleted rows": "S'il faut compter le nombre de lignes supprimées",
|
||||
"Whether to return the deleted rows data": "Retourner ou non les données des lignes supprimées",
|
||||
"Columns to return (comma-separated). Leave empty to return all columns.": "Colonnes à retourner (séparées par des virgules). Laisser vide pour retourner toutes les colonnes.",
|
||||
"List of filters to apply": "Liste des filtres à appliquer",
|
||||
"Page number for pagination (starts from 1)": "Numéro de page pour la pagination (commence à 1)",
|
||||
"Number of records per page (max 1000)": "Nombre d'enregistrements par page (max 1000)",
|
||||
"Algorithm to use for counting rows": "Algorithme à utiliser pour compter les lignes",
|
||||
"Authorization headers are injected automatically from your connection.": "Les en-têtes d'autorisation sont injectés automatiquement à partir de votre connexion.",
|
||||
"Enable for files like PDFs, images, etc..": "Activer pour les fichiers comme les PDFs, les images, etc.",
|
||||
"Column equals value": "La colonne est égale à la valeur",
|
||||
"Column is in list of values": "La colonne est dans la liste des valeurs",
|
||||
"Column is greater than value": "La colonne est plus grande que la valeur",
|
||||
"Column not equals value": "La colonne n'est pas égale à la valeur",
|
||||
"Column is in list": "La colonne est dans la liste",
|
||||
"Column is greater than": "La colonne est supérieure à",
|
||||
"Column is greater than or equal": "La colonne est supérieure ou égale à",
|
||||
"Column is less than": "La colonne est inférieure à",
|
||||
"Column is less than or equal": "La colonne est inférieure ou égale à",
|
||||
"Column is null": "La colonne est nulle",
|
||||
"Column is not null": "La colonne n'est pas nulle",
|
||||
"Column matches pattern (LIKE)": "La colonne correspond au motif (LIKE)",
|
||||
"Column matches pattern (case-insensitive)": "La colonne correspond au motif (insensible à la casse)",
|
||||
"Exact": "Exactement",
|
||||
"Planned": "Planifié",
|
||||
"Estimated": "Estimé",
|
||||
"GET": "GET",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "DELETE",
|
||||
"HEAD": "HEAD",
|
||||
"New Row": "Nouvelle ligne",
|
||||
"Fires when a new row is created in a table": "Se déclenche lorsqu'une nouvelle ligne est créée dans une table",
|
||||
"Markdown": "Markdown",
|
||||
"Schema": "Schéma",
|
||||
"## Setup Instructions\n\n1. **Go to your Supabase Dashboard** → Database → Webhooks\n2. **Click \"Create a new hook\"**\n3. **Configure the webhook:**\n - **Name**: Give it a descriptive name (e.g., \"Activepieces New Row\")\n - **Table**: Select the table you want to monitor\n - **Events**: Check \"Insert\" \n - **Type**: HTTP Request\n - **Method**: POST\n - **URL**: Copy and paste the webhook URL below\n4. **Click \"Create webhook\"**\n\n**Webhook URL:** `{{webhookUrl}}`\n\n## Important Notes\n- The webhook will sen": "## Setup Instructions\n\n1. **Go to your Supabase Dashboard** → Database → Webhooks\n2. **Click \"Create a new hook\"**\n3. **Configure the webhook:**\n - **Name**: Give it a descriptive name (e.g., \"Activepieces New Row\")\n - **Table**: Select the table you want to monitor\n - **Events**: Check \"Insert\" \n - **Type**: HTTP Request\n - **Method**: POST\n - **URL**: Copy and paste the webhook URL below\n4. **Click \"Create webhook\"**\n\n**Webhook URL:** `{{webhookUrl}}`\n\n## Important Notes\n- The webhook will send a JSON payload with the new row data\n- Make sure your table has the necessary permissions\n- You can test the webhook by inserting a new row into your table\n\nFor more details, see [Supabase Database Webhooks documentation](https://supabase.com/docs/guides/database/webhooks).",
|
||||
"Database schema (default: public)": "Schéma de la base de données (par défaut: public)"
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"Supabase": "Supabase",
|
||||
"The open-source Firebase alternative": "The open-source Firebase alternative",
|
||||
"URL": "URL",
|
||||
"API Key": "API Key",
|
||||
"\nCopy the **URL** and **Service API Key** from your Supabase project settings.\n": "\nCopy the **URL** and **Service API Key** from your Supabase project settings.\n",
|
||||
"Upload File": "Upload File",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Upload a file to Supabase Storage": "Upload a file to Supabase Storage",
|
||||
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
|
||||
"File path": "File path",
|
||||
"Bucket": "Bucket",
|
||||
"Base64 or URL": "Base64 or URL",
|
||||
"Method": "Method",
|
||||
"Headers": "Headers",
|
||||
"Query Parameters": "Query Parameters",
|
||||
"Body": "Body",
|
||||
"No Error on Failure": "No Error on Failure",
|
||||
"Timeout (in seconds)": "Timeout (in seconds)",
|
||||
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
|
||||
"GET": "GET",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "DELETE",
|
||||
"HEAD": "HEAD"
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"Supabase": "Supabase",
|
||||
"The open-source Firebase alternative": "The open-source Firebase alternative",
|
||||
"URL": "URL",
|
||||
"API Key": "API Key",
|
||||
"\nCopy the **URL** and **Service API Key** from your Supabase project settings.\n": "\nCopy the **URL** and **Service API Key** from your Supabase project settings.\n",
|
||||
"Upload File": "Upload File",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Upload a file to Supabase Storage": "Upload a file to Supabase Storage",
|
||||
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
|
||||
"File path": "File path",
|
||||
"Bucket": "Bucket",
|
||||
"Base64 or URL": "Base64 or URL",
|
||||
"Method": "Method",
|
||||
"Headers": "Headers",
|
||||
"Query Parameters": "Query Parameters",
|
||||
"Body": "Body",
|
||||
"No Error on Failure": "No Error on Failure",
|
||||
"Timeout (in seconds)": "Timeout (in seconds)",
|
||||
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
|
||||
"GET": "GET",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "DELETE",
|
||||
"HEAD": "HEAD"
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
{
|
||||
"The open-source Firebase alternative": "オープンソースのFirebase代替品",
|
||||
"Project URL": "Project URL",
|
||||
"API Key": "API キー",
|
||||
"Your Supabase project URL (e.g., https://your-project-ref.supabase.co)": "Your Supabase project URL (e.g., https://your-project-ref.supabase.co)",
|
||||
"Service Role Key (for actions) or Anonymous Key (for basic triggers)": "Service Role Key (for actions) or Anonymous Key (for basic triggers)",
|
||||
"\n## Supabase Connection Setup\n\n### 1. Get Your Project URL\n- Go to your [Supabase Dashboard](https://supabase.com/dashboard)\n- Select your project\n- Go to **Settings** → **API**\n- Copy the **Project URL** (format: `https://your-project-ref.supabase.co`)\n\n### 2. Get Your API Key\nChoose the appropriate key based on your use case:\n\n**For Actions (Database Operations):**\n- Use **Service Role Key** (secret) for server-side operations\n- Has full access to bypass Row Level Security (RLS)\n\n**For Triggers (Webhooks)": "\n## Supabase Connection Setup\n\n### 1. Get Your Project URL\n- Go to your [Supabase Dashboard](https://supabase.com/dashboard)\n- Select your project\n- Go to **Settings** → **API**\n- Copy the **Project URL** (format: `https://your-project-ref.supabase.co`)\n\n### 2. Get Your API Key\nChoose the appropriate key based on your use case:\n\n**For Actions (Database Operations):**\n- Use **Service Role Key** (secret) for server-side operations\n- Has full access to bypass Row Level Security (RLS)\n\n**For Triggers (Webhooks):**\n- Use **Anonymous Key** (public) if your webhooks don't need elevated permissions\n- Use **Service Role Key** for elevated permissions\n\n**Security Note:** Keep your Service Role Key secret - it bypasses all RLS policies.\n\nFind your keys in **Settings** → **API** → **Project API keys**\n",
|
||||
"Upload File": "ファイルをアップロード",
|
||||
"Create Row": "行を作成",
|
||||
"Update Row": "行を更新",
|
||||
"Upsert Row": "Upsert Row",
|
||||
"Delete Rows": "Delete Rows",
|
||||
"Search Rows": "Search Rows",
|
||||
"Custom API Call": "カスタムAPI通話",
|
||||
"Upload a file to Supabase Storage": "Supabase Storageにファイルをアップロード",
|
||||
"Create a new row in a table": "Create a new row in a table",
|
||||
"Update rows in a table based on filter criteria": "Update rows in a table based on filter criteria",
|
||||
"Insert or update a row in a table": "Insert or update a row in a table",
|
||||
"Remove rows matching filter criteria from a table": "Remove rows matching filter criteria from a table",
|
||||
"Search for rows in a table with filters and pagination": "Search for rows in a table with filters and pagination",
|
||||
"Make a custom API call to a specific endpoint": "特定のエンドポイントへのカスタム API コールを実行します。",
|
||||
"File path": "ファイルパス",
|
||||
"Bucket": "バケツ入りバケツ",
|
||||
"Base64 or URL": "Base64 または URL",
|
||||
"Table Name": "テーブル名",
|
||||
"Row Data": "行データ",
|
||||
"Return Created Row": "Return Created Row",
|
||||
"Filter Type": "Filter Type",
|
||||
"Filter Column": "Filter Column",
|
||||
"Filter Value": "Filter Value",
|
||||
"Filter Values": "Filter Values",
|
||||
"Update Data": "Update Data",
|
||||
"Count Updated Rows": "Count Updated Rows",
|
||||
"Return Updated Rows": "Return Updated Rows",
|
||||
"Conflict Column": "Conflict Column",
|
||||
"Count Upserted Rows": "Count Upserted Rows",
|
||||
"Return Upserted Rows": "Return Upserted Rows",
|
||||
"Count Deleted Rows": "Count Deleted Rows",
|
||||
"Return Deleted Rows": "Return Deleted Rows",
|
||||
"Columns": "列",
|
||||
"Filters": "絞り込み",
|
||||
"Page": "ページ",
|
||||
"Page Size": "ページサイズ",
|
||||
"Count Algorithm": "Count Algorithm",
|
||||
"Method": "方法",
|
||||
"Headers": "ヘッダー",
|
||||
"Query Parameters": "クエリパラメータ",
|
||||
"Body": "本文",
|
||||
"Response is Binary ?": "応答はバイナリですか?",
|
||||
"No Error on Failure": "失敗時にエラーはありません",
|
||||
"Timeout (in seconds)": "タイムアウト(秒)",
|
||||
"Select a table from your database": "Select a table from your database",
|
||||
"Enter the data for each column": "Enter the data for each column",
|
||||
"Whether to return the created row": "Whether to return the created row",
|
||||
"How to identify rows to update": "How to identify rows to update",
|
||||
"Select the column to filter on": "フィルタリングする列を選択してください",
|
||||
"The value to match against (not used for \"in list\" filter)": "一致する値 (「リスト」フィルタでは使用されません)",
|
||||
"List of values for \"in list\" filter type": "\"リスト\"フィルタータイプの値のリスト",
|
||||
"Select which columns to update (auto-generated fields excluded)": "更新する列を選択してください(自動生成フィールドを除く)",
|
||||
"Whether to count the number of updated rows": "更新された行の数をカウントするか",
|
||||
"Whether to return the updated rows data": "更新された行データを返すかどうか",
|
||||
"Select the unique column to determine duplicates (required for upsert to work)": "重複を決定するために一意の列を選択します(アップセルを動作させるために必要)",
|
||||
"Enter data for the row (conflict detection handled separately)": "行のデータを入力してください(競合検出は別々に処理されます)",
|
||||
"Whether to count the number of upserted rows": "更新された行の数を数えるかどうか",
|
||||
"Whether to return the upserted rows data": "更新された行データを返すかどうか",
|
||||
"How to filter rows for deletion": "削除の行をフィルタリングする方法",
|
||||
"The value to match against (not used for null checks)": "一致する値 (null チェックでは使用されません)",
|
||||
"List of values for \"in\" filter type": "\"in\" フィルタータイプの値のリスト",
|
||||
"Whether to count the number of deleted rows": "削除された行の数をカウントするか",
|
||||
"Whether to return the deleted rows data": "削除された行データを返すかどうか",
|
||||
"Columns to return (comma-separated). Leave empty to return all columns.": "戻る列(カンマ区切り)。すべての列を返す場合は空のままにします。",
|
||||
"List of filters to apply": "適用するフィルターのリスト",
|
||||
"Page number for pagination (starts from 1)": "ページネーションのページ番号(1から始まる)",
|
||||
"Number of records per page (max 1000)": "Number of records per page (max 1000)",
|
||||
"Algorithm to use for counting rows": "行を数えるためのアルゴリズム",
|
||||
"Authorization headers are injected automatically from your connection.": "認証ヘッダは接続から自動的に注入されます。",
|
||||
"Enable for files like PDFs, images, etc..": "PDF、画像などのファイルを有効にします。",
|
||||
"Column equals value": "列の等しい値",
|
||||
"Column is in list of values": "列は値のリストにあります",
|
||||
"Column is greater than value": "列が値より大きいです",
|
||||
"Column not equals value": "列の値が等しくありません",
|
||||
"Column is in list": "列がリストにあります",
|
||||
"Column is greater than": "列より大きい",
|
||||
"Column is greater than or equal": "列が等しいかそれ以上です",
|
||||
"Column is less than": "列より小さい",
|
||||
"Column is less than or equal": "列が同じかそれ以下です",
|
||||
"Column is null": "列が null です",
|
||||
"Column is not null": "列がnullではありません",
|
||||
"Column matches pattern (LIKE)": "列一致パターン (LIKE)",
|
||||
"Column matches pattern (case-insensitive)": "列一致パターン(大文字と小文字を区別しません)",
|
||||
"Exact": "正確な",
|
||||
"Planned": "計画済み",
|
||||
"Estimated": "推定値",
|
||||
"GET": "取得",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "削除",
|
||||
"HEAD": "頭",
|
||||
"New Row": "新しい行",
|
||||
"Fires when a new row is created in a table": "テーブルに新しい行が作成されたときに発行されます。",
|
||||
"Markdown": "Markdown",
|
||||
"Schema": "スキーマ",
|
||||
"## Setup Instructions\n\n1. **Go to your Supabase Dashboard** → Database → Webhooks\n2. **Click \"Create a new hook\"**\n3. **Configure the webhook:**\n - **Name**: Give it a descriptive name (e.g., \"Activepieces New Row\")\n - **Table**: Select the table you want to monitor\n - **Events**: Check \"Insert\" \n - **Type**: HTTP Request\n - **Method**: POST\n - **URL**: Copy and paste the webhook URL below\n4. **Click \"Create webhook\"**\n\n**Webhook URL:** `{{webhookUrl}}`\n\n## Important Notes\n- The webhook will sen": "## Setup Instructions\n\n1. **Go to your Supabase Dashboard** → Database → Webhooks\n2. **Click \"Create a new hook\"**\n3. **Configure the webhook:**\n - **Name**: Give it a descriptive name (e.g., \"Activepieces New Row\")\n - **Table**: Select the table you want to monitor\n - **Events**: Check \"Insert\" \n - **Type**: HTTP Request\n - **Method**: POST\n - **URL**: Copy and paste the webhook URL below\n4. **Click \"Create webhook\"**\n\n**Webhook URL:** `{{webhookUrl}}`\n\n## Important Notes\n- The webhook will send a JSON payload with the new row data\n- Make sure your table has the necessary permissions\n- You can test the webhook by inserting a new row into your table\n\nFor more details, see [Supabase Database Webhooks documentation](https://supabase.com/docs/guides/database/webhooks).",
|
||||
"Database schema (default: public)": "データベース スキーマ(デフォルト: public)"
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
{
|
||||
"The open-source Firebase alternative": "Het open-source vuurbasis alternatief",
|
||||
"Project URL": "Project URL",
|
||||
"API Key": "API Sleutel",
|
||||
"Your Supabase project URL (e.g., https://your-project-ref.supabase.co)": "Uw Supabase project URL (bijv. https://your-project-ref.supabase.co)",
|
||||
"Service Role Key (for actions) or Anonymous Key (for basic triggers)": "Service Rol Key (voor acties) of Anonieme Key (voor basis triggers)",
|
||||
"\n## Supabase Connection Setup\n\n### 1. Get Your Project URL\n- Go to your [Supabase Dashboard](https://supabase.com/dashboard)\n- Select your project\n- Go to **Settings** → **API**\n- Copy the **Project URL** (format: `https://your-project-ref.supabase.co`)\n\n### 2. Get Your API Key\nChoose the appropriate key based on your use case:\n\n**For Actions (Database Operations):**\n- Use **Service Role Key** (secret) for server-side operations\n- Has full access to bypass Row Level Security (RLS)\n\n**For Triggers (Webhooks)": "\n## Supabase Connectie Setup\n\n### 1. Krijg uw project-URL\n- Ga naar uw [Supabase Dashboard](https://supabase.com/dashboard)\n- Selecteer uw project\n- Ga naar **instellingen** → **API**\n- kopieer de **project-URL** (formaat: `https://your-project-ref. upabase.co`)\n\n### 2. Krijg uw API-sleutel\nKies de juiste sleutel op basis van uw gebruiksdoel:\n\n**For Acties (Database Operations):**\n- Gebruik **Service Role Key** (secret) voor server-side operaties\n- Heeft volledige toegang om Row Level Security (RLS) te omzeilen (RLS)\n\n**Voor Triggers (Webhooks):**\n- Gebruik **Anonieme Key** (publiek) als uw webhooks geen verheven rechten nodig heeft\n- Gebruik **Service Role Key** voor verhoogde permissies\n\n**Security Note:** Houd uw Service Role Key - Al het beleid.\n\nVind je sleutels in **Instellingen** → **API** → **ProjectAPI-sleutels**\n",
|
||||
"Upload File": "Bestand uploaden",
|
||||
"Create Row": "Rij maken",
|
||||
"Update Row": "Rij bijwerken",
|
||||
"Upsert Row": "In de woestijn rij",
|
||||
"Delete Rows": "Rijen verwijderen",
|
||||
"Search Rows": "Zoek Rijen",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Upload a file to Supabase Storage": "Upload een bestand naar Supabase Opslag",
|
||||
"Create a new row in a table": "Maak een nieuwe rij in een tabel",
|
||||
"Update rows in a table based on filter criteria": "Update rijen in een tabel gebaseerd op filtercriteria",
|
||||
"Insert or update a row in a table": "Rij in een tabel invoegen of bijwerken",
|
||||
"Remove rows matching filter criteria from a table": "Verwijder rijen met filter criteria uit een tabel",
|
||||
"Search for rows in a table with filters and pagination": "Zoek naar rijen in een tabel met filters en paginering",
|
||||
"Make a custom API call to a specific endpoint": "Maak een aangepaste API call naar een specifiek eindpunt",
|
||||
"File path": "Bestand pad",
|
||||
"Bucket": "Emmer",
|
||||
"Base64 or URL": "Base64 of URL",
|
||||
"Table Name": "Tafel naam",
|
||||
"Row Data": "Rij gegevens",
|
||||
"Return Created Row": "Retour gemaakte rij",
|
||||
"Filter Type": "Filter type",
|
||||
"Filter Column": "Kolom filteren",
|
||||
"Filter Value": "Waarde filteren",
|
||||
"Filter Values": "Waarden filteren",
|
||||
"Update Data": "Gegevens bijwerken",
|
||||
"Count Updated Rows": "Aantal bijgewerkte rijen",
|
||||
"Return Updated Rows": "Retour bijgewerkte rijen",
|
||||
"Conflict Column": "Conflict kolom",
|
||||
"Count Upserted Rows": "Aantal toegevoegde rijen",
|
||||
"Return Upserted Rows": "Retour geüpdatet rijen",
|
||||
"Count Deleted Rows": "Verwijderde rijen tellen",
|
||||
"Return Deleted Rows": "Verwijderde rijen terugsturen",
|
||||
"Columns": "Kolommen",
|
||||
"Filters": "Filters",
|
||||
"Page": "Pagina",
|
||||
"Page Size": "Paginagrootte",
|
||||
"Count Algorithm": "Tel Algoritme",
|
||||
"Method": "Methode",
|
||||
"Headers": "Kopteksten",
|
||||
"Query Parameters": "Query parameters",
|
||||
"Body": "Lichaam",
|
||||
"Response is Binary ?": "Antwoord is binair?",
|
||||
"No Error on Failure": "Geen fout bij fout",
|
||||
"Timeout (in seconds)": "Time-out (in seconden)",
|
||||
"Select a table from your database": "Selecteer een tabel uit uw database",
|
||||
"Enter the data for each column": "Voer de gegevens in voor elke kolom",
|
||||
"Whether to return the created row": "Of de gemaakte rij terug te geven",
|
||||
"How to identify rows to update": "Hoe de rijen te updaten",
|
||||
"Select the column to filter on": "Selecteer de kolom waarop u wilt filteren",
|
||||
"The value to match against (not used for \"in list\" filter)": "De waarde waarmee overeen moet komen (niet gebruikt voor \"in lijst\" filter)",
|
||||
"List of values for \"in list\" filter type": "Lijst van waardes voor \"in lijst\" filtertype",
|
||||
"Select which columns to update (auto-generated fields excluded)": "Selecteer welke kolommen bij te werken (auto-gegenereerde velden uitgesloten)",
|
||||
"Whether to count the number of updated rows": "Of het aantal bijgewerkte rijen te tellen",
|
||||
"Whether to return the updated rows data": "Of de bijgewerkte rijgegevens moeten worden geretourneerd",
|
||||
"Select the unique column to determine duplicates (required for upsert to work)": "Selecteer de unieke kolom om duplicaten te bepalen (vereist voor de upsert om te werken)",
|
||||
"Enter data for the row (conflict detection handled separately)": "Voer gegevens in voor de rij (conflictdetectie afzonderlijk behandeld)",
|
||||
"Whether to count the number of upserted rows": "Of je het aantal upserted rijen wilt tellen",
|
||||
"Whether to return the upserted rows data": "Of de ondergevoegde rijgegevens moeten worden geretourneerd",
|
||||
"How to filter rows for deletion": "Hoe rijen filteren voor verwijdering",
|
||||
"The value to match against (not used for null checks)": "De waarde waaraan moet worden voldaan (niet gebruikt voor null controles)",
|
||||
"List of values for \"in\" filter type": "Lijst van waarden voor \"in\" filtertype",
|
||||
"Whether to count the number of deleted rows": "Of het aantal verwijderde rijen telt",
|
||||
"Whether to return the deleted rows data": "Of de verwijderde rijen gegevens moeten worden teruggestuurd",
|
||||
"Columns to return (comma-separated). Leave empty to return all columns.": "Kolommen om terug te keren (komma gescheiden). Laat leeg om alle kolommen terug te geven.",
|
||||
"List of filters to apply": "Lijst met toe te passen filters",
|
||||
"Page number for pagination (starts from 1)": "Paginanummer voor paginering (begint vanaf 1)",
|
||||
"Number of records per page (max 1000)": "Aantal records per pagina (max 1000)",
|
||||
"Algorithm to use for counting rows": "Algoritme om te gebruiken voor het tellen van rijen",
|
||||
"Authorization headers are injected automatically from your connection.": "Autorisatie headers worden automatisch geïnjecteerd vanuit uw verbinding.",
|
||||
"Enable for files like PDFs, images, etc..": "Inschakelen voor bestanden zoals PDF's, afbeeldingen etc..",
|
||||
"Column equals value": "Kolom is gelijk aan waarde",
|
||||
"Column is in list of values": "Kolom is in de lijst met waarden",
|
||||
"Column is greater than value": "Kolom is groter dan de waarde",
|
||||
"Column not equals value": "Kolom is niet gelijk aan waarde",
|
||||
"Column is in list": "Kolom staat in de lijst",
|
||||
"Column is greater than": "Kolom is groter dan",
|
||||
"Column is greater than or equal": "Kolom is groter dan of gelijk aan",
|
||||
"Column is less than": "Kolom is minder dan",
|
||||
"Column is less than or equal": "Kolom is kleiner dan of gelijk aan",
|
||||
"Column is null": "Kolom is null",
|
||||
"Column is not null": "Kolom is niet null",
|
||||
"Column matches pattern (LIKE)": "Kolom komt overeen met patroon (LIKE)",
|
||||
"Column matches pattern (case-insensitive)": "Kolom komt overeen met patroon (hoofdlettergevoelig)",
|
||||
"Exact": "Exacte",
|
||||
"Planned": "Gepland",
|
||||
"Estimated": "Geschat",
|
||||
"GET": "KRIJG",
|
||||
"POST": "POSTE",
|
||||
"PATCH": "BEKIJK",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "VERWIJDEREN",
|
||||
"HEAD": "HOOFD",
|
||||
"New Row": "Nieuwe rij",
|
||||
"Fires when a new row is created in a table": "Vuurt wanneer een nieuwe rij wordt gemaakt in een tabel",
|
||||
"Markdown": "Markdown",
|
||||
"Schema": "Schema",
|
||||
"## Setup Instructions\n\n1. **Go to your Supabase Dashboard** → Database → Webhooks\n2. **Click \"Create a new hook\"**\n3. **Configure the webhook:**\n - **Name**: Give it a descriptive name (e.g., \"Activepieces New Row\")\n - **Table**: Select the table you want to monitor\n - **Events**: Check \"Insert\" \n - **Type**: HTTP Request\n - **Method**: POST\n - **URL**: Copy and paste the webhook URL below\n4. **Click \"Create webhook\"**\n\n**Webhook URL:** `{{webhookUrl}}`\n\n## Important Notes\n- The webhook will sen": "## Instructies instellen\n\n1. **Ga naar je Supabase Dashboard** → Database → Webhooks\n\n. **Klik op \"Maak een nieuwe hook\"**\n3. **Configureer de webhook:**\n - **Naam**: Geef het een beschrijvende naam (bijv. \"Activepieces New Row\")\n - **Tabel**: Selecteer de tabel die u wilt monitoren\n - **Gebeurtenissen**: Controleer \"Insert\" \n - **Type**: HTTP Request\n - **Method**: POST\n - **URL**: Kopieer en plak de webhook URL onder\n4. **Klik op \"Maak webhook\"**\n\n**Webhook URL:** `{{webhookUrl}}` \n\n ## Belangrijke notities\n- De webhook stuurt een JSON payload met de nieuwe rij gegevens\n- Zorg ervoor dat de tabel de benodigde rechten heeft\n- Je kunt de webhook testen door een nieuwe rij in te voegen in je tabel\n\nvoor meer informatie. zie [Supabase Database Webhooks documentatie](https://supabase.com/docs/guides/database/webhooks).",
|
||||
"Database schema (default: public)": "Databaseschema (standaard: openbaar)"
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
{
|
||||
"The open-source Firebase alternative": "A alternativa open-source Firebase",
|
||||
"Project URL": "Project URL",
|
||||
"API Key": "Chave de API",
|
||||
"Your Supabase project URL (e.g., https://your-project-ref.supabase.co)": "Your Supabase project URL (e.g., https://your-project-ref.supabase.co)",
|
||||
"Service Role Key (for actions) or Anonymous Key (for basic triggers)": "Service Role Key (for actions) or Anonymous Key (for basic triggers)",
|
||||
"\n## Supabase Connection Setup\n\n### 1. Get Your Project URL\n- Go to your [Supabase Dashboard](https://supabase.com/dashboard)\n- Select your project\n- Go to **Settings** → **API**\n- Copy the **Project URL** (format: `https://your-project-ref.supabase.co`)\n\n### 2. Get Your API Key\nChoose the appropriate key based on your use case:\n\n**For Actions (Database Operations):**\n- Use **Service Role Key** (secret) for server-side operations\n- Has full access to bypass Row Level Security (RLS)\n\n**For Triggers (Webhooks)": "\n## Supabase Connection Setup\n\n### 1. Get Your Project URL\n- Go to your [Supabase Dashboard](https://supabase.com/dashboard)\n- Select your project\n- Go to **Settings** → **API**\n- Copy the **Project URL** (format: `https://your-project-ref.supabase.co`)\n\n### 2. Get Your API Key\nChoose the appropriate key based on your use case:\n\n**For Actions (Database Operations):**\n- Use **Service Role Key** (secret) for server-side operations\n- Has full access to bypass Row Level Security (RLS)\n\n**For Triggers (Webhooks):**\n- Use **Anonymous Key** (public) if your webhooks don't need elevated permissions\n- Use **Service Role Key** for elevated permissions\n\n**Security Note:** Keep your Service Role Key secret - it bypasses all RLS policies.\n\nFind your keys in **Settings** → **API** → **Project API keys**\n",
|
||||
"Upload File": "Enviar Arquivo",
|
||||
"Create Row": "Criar Linha",
|
||||
"Update Row": "Atualizar linha",
|
||||
"Upsert Row": "Linha Recorrente",
|
||||
"Delete Rows": "Delete Rows",
|
||||
"Search Rows": "Search Rows",
|
||||
"Custom API Call": "Chamada de API personalizada",
|
||||
"Upload a file to Supabase Storage": "Enviar um arquivo para suavizar o armazenamento",
|
||||
"Create a new row in a table": "Create a new row in a table",
|
||||
"Update rows in a table based on filter criteria": "Update rows in a table based on filter criteria",
|
||||
"Insert or update a row in a table": "Insert or update a row in a table",
|
||||
"Remove rows matching filter criteria from a table": "Remove rows matching filter criteria from a table",
|
||||
"Search for rows in a table with filters and pagination": "Search for rows in a table with filters and pagination",
|
||||
"Make a custom API call to a specific endpoint": "Faça uma chamada de API personalizada para um ponto de extremidade específico",
|
||||
"File path": "Caminho do arquivo",
|
||||
"Bucket": "Balde",
|
||||
"Base64 or URL": "URL ou Base64",
|
||||
"Table Name": "Nome da Tabela",
|
||||
"Row Data": "Dados da Linha",
|
||||
"Return Created Row": "Return Created Row",
|
||||
"Filter Type": "Filter Type",
|
||||
"Filter Column": "Filter Column",
|
||||
"Filter Value": "Filter Value",
|
||||
"Filter Values": "Filter Values",
|
||||
"Update Data": "Update Data",
|
||||
"Count Updated Rows": "Count Updated Rows",
|
||||
"Return Updated Rows": "Return Updated Rows",
|
||||
"Conflict Column": "Conflict Column",
|
||||
"Count Upserted Rows": "Count Upserted Rows",
|
||||
"Return Upserted Rows": "Return Upserted Rows",
|
||||
"Count Deleted Rows": "Count Deleted Rows",
|
||||
"Return Deleted Rows": "Return Deleted Rows",
|
||||
"Columns": "Colunas",
|
||||
"Filters": "Filtros",
|
||||
"Page": "Página",
|
||||
"Page Size": "Tamanho da página",
|
||||
"Count Algorithm": "Count Algorithm",
|
||||
"Method": "Método",
|
||||
"Headers": "Cabeçalhos",
|
||||
"Query Parameters": "Parâmetros da consulta",
|
||||
"Body": "Conteúdo",
|
||||
"Response is Binary ?": "A resposta é binária ?",
|
||||
"No Error on Failure": "Nenhum erro no Failure",
|
||||
"Timeout (in seconds)": "Tempo limite (em segundos)",
|
||||
"Select a table from your database": "Select a table from your database",
|
||||
"Enter the data for each column": "Enter the data for each column",
|
||||
"Whether to return the created row": "Whether to return the created row",
|
||||
"How to identify rows to update": "How to identify rows to update",
|
||||
"Select the column to filter on": "Selecione a coluna para filtrar",
|
||||
"The value to match against (not used for \"in list\" filter)": "O valor a corresponder (não é usado para o filtro \"na lista\")",
|
||||
"List of values for \"in list\" filter type": "Lista de valores para o tipo de filtro \"na lista\"",
|
||||
"Select which columns to update (auto-generated fields excluded)": "Seleciona quais colunas atualizar (campos gerados automaticamente excluídos)",
|
||||
"Whether to count the number of updated rows": "Se deseja contar o número de linhas atualizadas",
|
||||
"Whether to return the updated rows data": "Se deseja devolver os dados atualizados das linhas",
|
||||
"Select the unique column to determine duplicates (required for upsert to work)": "Selecione a coluna exclusiva para determinar as duplicatas (necessário para que o upsert funcione)",
|
||||
"Enter data for the row (conflict detection handled separately)": "Digite os dados da linha (detecção de conflitos processada separadamente)",
|
||||
"Whether to count the number of upserted rows": "Se deseja contar o número de linhas upseradas",
|
||||
"Whether to return the upserted rows data": "Se retorna os dados das linhas upserted",
|
||||
"How to filter rows for deletion": "Como filtrar linhas para exclusão",
|
||||
"The value to match against (not used for null checks)": "O valor a ser igual (não é usado para verificações nulas)",
|
||||
"List of values for \"in\" filter type": "Lista de valores para o tipo de filtro \"in\"",
|
||||
"Whether to count the number of deleted rows": "Se deseja contar o número de linhas excluídas",
|
||||
"Whether to return the deleted rows data": "Se deseja devolver os dados das linhas excluídas",
|
||||
"Columns to return (comma-separated). Leave empty to return all columns.": "Colunas para retornar (separadas por vírgula). Deixe em branco para retornar todas as colunas.",
|
||||
"List of filters to apply": "Lista de filtros a aplicar",
|
||||
"Page number for pagination (starts from 1)": "Número da página para paginação (começa de 1)",
|
||||
"Number of records per page (max 1000)": "Número de registros por página (máx. 1000)",
|
||||
"Algorithm to use for counting rows": "Algoritmo utilizado para contagem de linhas",
|
||||
"Authorization headers are injected automatically from your connection.": "Os cabeçalhos de autorização são inseridos automaticamente a partir da sua conexão.",
|
||||
"Enable for files like PDFs, images, etc..": "Habilitar para arquivos como PDFs, imagens, etc..",
|
||||
"Column equals value": "Coluna igual a valor",
|
||||
"Column is in list of values": "A coluna está na lista de valores",
|
||||
"Column is greater than value": "A coluna é maior que o valor",
|
||||
"Column not equals value": "Coluna não é igual ao valor",
|
||||
"Column is in list": "A coluna está na lista",
|
||||
"Column is greater than": "A coluna é maior que",
|
||||
"Column is greater than or equal": "A coluna é maior ou igual",
|
||||
"Column is less than": "A coluna é menor que",
|
||||
"Column is less than or equal": "A coluna é menor ou igual",
|
||||
"Column is null": "Coluna é nula",
|
||||
"Column is not null": "A coluna não é nula",
|
||||
"Column matches pattern (LIKE)": "Correspondência de coluna padrão (LIKE)",
|
||||
"Column matches pattern (case-insensitive)": "Padrão de correspondências de coluna (maiúsculas e minúsculas)",
|
||||
"Exact": "Exato",
|
||||
"Planned": "Planejado",
|
||||
"Estimated": "Estimado",
|
||||
"GET": "OBTER",
|
||||
"POST": "POSTAR",
|
||||
"PATCH": "COMPRAR",
|
||||
"PUT": "COLOCAR",
|
||||
"DELETE": "EXCLUIR",
|
||||
"HEAD": "CABEÇA",
|
||||
"New Row": "Nova linha",
|
||||
"Fires when a new row is created in a table": "Atira quando uma nova linha é criada em uma tabela",
|
||||
"Markdown": "Markdown",
|
||||
"Schema": "Esquema",
|
||||
"## Setup Instructions\n\n1. **Go to your Supabase Dashboard** → Database → Webhooks\n2. **Click \"Create a new hook\"**\n3. **Configure the webhook:**\n - **Name**: Give it a descriptive name (e.g., \"Activepieces New Row\")\n - **Table**: Select the table you want to monitor\n - **Events**: Check \"Insert\" \n - **Type**: HTTP Request\n - **Method**: POST\n - **URL**: Copy and paste the webhook URL below\n4. **Click \"Create webhook\"**\n\n**Webhook URL:** `{{webhookUrl}}`\n\n## Important Notes\n- The webhook will sen": "## Instruções de configuração\n\n1. **Vá para seu painel de suporte** → Banco de dados → Webhooks\n\n. **Clique em \"Create a new hook\"**\n3. **Configure o webhook:**\n - **Nome**: Dê um nome descritivo (por exemplo, \"Activepieces New Row\")\n - **Tabela**: Selecione a tabela que você quer monitorar\n - **Eventos**: Verifique \"Insert\" \n - **Tipo**: HTTP Request\n - **Método**: POST\n - **URL**: copie e cole o URL do webhook abaixo\n4. **Clique em \"Create webhook\"**\n\n**Webhook URL:** `{{webhookUrl}}` \n\n ## Notas Importantes\n- O webhook vai enviar uma carga JSON com os novos dados de linha\n- Certifique-se de que sua tabela tem as permissões necessárias\n- Você pode testar o webhook inserindo uma nova linha na sua tabela\n\nPara mais detalhes veja [Supabase Database Webhooks documentation](https://supabase.com/docs/guides/database/webhooks).",
|
||||
"Database schema (default: public)": "Esquema do banco de dados (padrão: público)"
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
{
|
||||
"Supabase": "Supabase",
|
||||
"The open-source Firebase alternative": "Вариант Firebase с открытым исходным кодом",
|
||||
"Project URL": "Project URL",
|
||||
"API Key": "Ключ API",
|
||||
"Your Supabase project URL (e.g., https://your-project-ref.supabase.co)": "Your Supabase project URL (e.g., https://your-project-ref.supabase.co)",
|
||||
"Service Role Key (for actions) or Anonymous Key (for basic triggers)": "Service Role Key (for actions) or Anonymous Key (for basic triggers)",
|
||||
"\n## Supabase Connection Setup\n\n### 1. Get Your Project URL\n- Go to your [Supabase Dashboard](https://supabase.com/dashboard)\n- Select your project\n- Go to **Settings** → **API**\n- Copy the **Project URL** (format: `https://your-project-ref.supabase.co`)\n\n### 2. Get Your API Key\nChoose the appropriate key based on your use case:\n\n**For Actions (Database Operations):**\n- Use **Service Role Key** (secret) for server-side operations\n- Has full access to bypass Row Level Security (RLS)\n\n**For Triggers (Webhooks)": "\n## Supabase Connection Setup\n\n### 1. Get Your Project URL\n- Go to your [Supabase Dashboard](https://supabase.com/dashboard)\n- Select your project\n- Go to **Settings** → **API**\n- Copy the **Project URL** (format: `https://your-project-ref.supabase.co`)\n\n### 2. Get Your API Key\nChoose the appropriate key based on your use case:\n\n**For Actions (Database Operations):**\n- Use **Service Role Key** (secret) for server-side operations\n- Has full access to bypass Row Level Security (RLS)\n\n**For Triggers (Webhooks):**\n- Use **Anonymous Key** (public) if your webhooks don't need elevated permissions\n- Use **Service Role Key** for elevated permissions\n\n**Security Note:** Keep your Service Role Key secret - it bypasses all RLS policies.\n\nFind your keys in **Settings** → **API** → **Project API keys**\n",
|
||||
"Upload File": "Загрузить файл",
|
||||
"Create Row": "Создать строку",
|
||||
"Update Row": "Обновить строку",
|
||||
"Upsert Row": "Верхняя строка",
|
||||
"Delete Rows": "Delete Rows",
|
||||
"Search Rows": "Search Rows",
|
||||
"Custom API Call": "Пользовательский вызов API",
|
||||
"Upload a file to Supabase Storage": "Загрузить файл для поддержки хранилища",
|
||||
"Create a new row in a table": "Create a new row in a table",
|
||||
"Update rows in a table based on filter criteria": "Update rows in a table based on filter criteria",
|
||||
"Insert or update a row in a table": "Insert or update a row in a table",
|
||||
"Remove rows matching filter criteria from a table": "Remove rows matching filter criteria from a table",
|
||||
"Search for rows in a table with filters and pagination": "Search for rows in a table with filters and pagination",
|
||||
"Make a custom API call to a specific endpoint": "Сделать пользовательский API вызов к определенной конечной точке",
|
||||
"File path": "Путь к файлу",
|
||||
"Bucket": "Ведро",
|
||||
"Base64 or URL": "Base64 или URL",
|
||||
"Table Name": "Название таблицы",
|
||||
"Row Data": "Данные строк",
|
||||
"Return Created Row": "Return Created Row",
|
||||
"Filter Type": "Filter Type",
|
||||
"Filter Column": "Filter Column",
|
||||
"Filter Value": "Filter Value",
|
||||
"Filter Values": "Filter Values",
|
||||
"Update Data": "Update Data",
|
||||
"Count Updated Rows": "Count Updated Rows",
|
||||
"Return Updated Rows": "Return Updated Rows",
|
||||
"Conflict Column": "Conflict Column",
|
||||
"Count Upserted Rows": "Count Upserted Rows",
|
||||
"Return Upserted Rows": "Return Upserted Rows",
|
||||
"Count Deleted Rows": "Count Deleted Rows",
|
||||
"Return Deleted Rows": "Return Deleted Rows",
|
||||
"Columns": "Столбцы",
|
||||
"Filters": "Фильтры",
|
||||
"Page": "Страница",
|
||||
"Page Size": "Размер страницы",
|
||||
"Count Algorithm": "Count Algorithm",
|
||||
"Method": "Метод",
|
||||
"Headers": "Заголовки",
|
||||
"Query Parameters": "Параметры запроса",
|
||||
"Body": "Тело",
|
||||
"No Error on Failure": "Нет ошибок при ошибке",
|
||||
"Timeout (in seconds)": "Таймаут (в секундах)",
|
||||
"Select a table from your database": "Select a table from your database",
|
||||
"Enter the data for each column": "Enter the data for each column",
|
||||
"Whether to return the created row": "Whether to return the created row",
|
||||
"How to identify rows to update": "How to identify rows to update",
|
||||
"Select the column to filter on": "Select the column to filter on",
|
||||
"The value to match against (not used for \"in list\" filter)": "The value to match against (not used for \"in list\" filter)",
|
||||
"List of values for \"in list\" filter type": "List of values for \"in list\" filter type",
|
||||
"Select which columns to update (auto-generated fields excluded)": "Select which columns to update (auto-generated fields excluded)",
|
||||
"Whether to count the number of updated rows": "Whether to count the number of updated rows",
|
||||
"Whether to return the updated rows data": "Whether to return the updated rows data",
|
||||
"Select the unique column to determine duplicates (required for upsert to work)": "Select the unique column to determine duplicates (required for upsert to work)",
|
||||
"Enter data for the row (conflict detection handled separately)": "Enter data for the row (conflict detection handled separately)",
|
||||
"Whether to count the number of upserted rows": "Whether to count the number of upserted rows",
|
||||
"Whether to return the upserted rows data": "Whether to return the upserted rows data",
|
||||
"How to filter rows for deletion": "How to filter rows for deletion",
|
||||
"The value to match against (not used for null checks)": "The value to match against (not used for null checks)",
|
||||
"List of values for \"in\" filter type": "List of values for \"in\" filter type",
|
||||
"Whether to count the number of deleted rows": "Whether to count the number of deleted rows",
|
||||
"Whether to return the deleted rows data": "Whether to return the deleted rows data",
|
||||
"Columns to return (comma-separated). Leave empty to return all columns.": "Columns to return (comma-separated). Leave empty to return all columns.",
|
||||
"List of filters to apply": "List of filters to apply",
|
||||
"Page number for pagination (starts from 1)": "Page number for pagination (starts from 1)",
|
||||
"Number of records per page (max 1000)": "Number of records per page (max 1000)",
|
||||
"Algorithm to use for counting rows": "Algorithm to use for counting rows",
|
||||
"Authorization headers are injected automatically from your connection.": "Заголовки авторизации включаются автоматически из вашего соединения.",
|
||||
"Column equals value": "Column equals value",
|
||||
"Column is in list of values": "Column is in list of values",
|
||||
"Column is greater than value": "Column is greater than value",
|
||||
"Column not equals value": "Column not equals value",
|
||||
"Column is in list": "Column is in list",
|
||||
"Column is greater than": "Column is greater than",
|
||||
"Column is greater than or equal": "Column is greater than or equal",
|
||||
"Column is less than": "Column is less than",
|
||||
"Column is less than or equal": "Column is less than or equal",
|
||||
"Column is null": "Column is null",
|
||||
"Column is not null": "Column is not null",
|
||||
"Column matches pattern (LIKE)": "Column matches pattern (LIKE)",
|
||||
"Column matches pattern (case-insensitive)": "Column matches pattern (case-insensitive)",
|
||||
"Exact": "Exact",
|
||||
"Planned": "Запланировано",
|
||||
"Estimated": "Приблизительно",
|
||||
"GET": "ПОЛУЧИТЬ",
|
||||
"POST": "ПОСТ",
|
||||
"PATCH": "ПАТЧ",
|
||||
"PUT": "ПОКУПИТЬ",
|
||||
"DELETE": "УДАЛИТЬ",
|
||||
"HEAD": "HEAD",
|
||||
"New Row": "Новая строка",
|
||||
"Fires when a new row is created in a table": "Fires when a new row is created in a table",
|
||||
"Markdown": "Markdown",
|
||||
"Schema": "Схема",
|
||||
"## Setup Instructions\n\n1. **Go to your Supabase Dashboard** → Database → Webhooks\n2. **Click \"Create a new hook\"**\n3. **Configure the webhook:**\n - **Name**: Give it a descriptive name (e.g., \"Activepieces New Row\")\n - **Table**: Select the table you want to monitor\n - **Events**: Check \"Insert\" \n - **Type**: HTTP Request\n - **Method**: POST\n - **URL**: Copy and paste the webhook URL below\n4. **Click \"Create webhook\"**\n\n**Webhook URL:** `{{webhookUrl}}`\n\n## Important Notes\n- The webhook will sen": "## Setup Instructions\n\n1. **Go to your Supabase Dashboard** → Database → Webhooks\n2. **Click \"Create a new hook\"**\n3. **Configure the webhook:**\n - **Name**: Give it a descriptive name (e.g., \"Activepieces New Row\")\n - **Table**: Select the table you want to monitor\n - **Events**: Check \"Insert\" \n - **Type**: HTTP Request\n - **Method**: POST\n - **URL**: Copy and paste the webhook URL below\n4. **Click \"Create webhook\"**\n\n**Webhook URL:** `{{webhookUrl}}`\n\n## Important Notes\n- The webhook will send a JSON payload with the new row data\n- Make sure your table has the necessary permissions\n- You can test the webhook by inserting a new row into your table\n\nFor more details, see [Supabase Database Webhooks documentation](https://supabase.com/docs/guides/database/webhooks).",
|
||||
"Database schema (default: public)": "Database schema (default: public)"
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
{
|
||||
"The open-source Firebase alternative": "The open-source Firebase alternative",
|
||||
"Project URL": "Project URL",
|
||||
"API Key": "API Key",
|
||||
"Your Supabase project URL (e.g., https://your-project-ref.supabase.co)": "Your Supabase project URL (e.g., https://your-project-ref.supabase.co)",
|
||||
"Service Role Key (for actions) or Anonymous Key (for basic triggers)": "Service Role Key (for actions) or Anonymous Key (for basic triggers)",
|
||||
"\n## Supabase Connection Setup\n\n### 1. Get Your Project URL\n- Go to your [Supabase Dashboard](https://supabase.com/dashboard)\n- Select your project\n- Go to **Settings** → **API**\n- Copy the **Project URL** (format: `https://your-project-ref.supabase.co`)\n\n### 2. Get Your API Key\nChoose the appropriate key based on your use case:\n\n**For Actions (Database Operations):**\n- Use **Service Role Key** (secret) for server-side operations\n- Has full access to bypass Row Level Security (RLS)\n\n**For Triggers (Webhooks)": "\n## Supabase Connection Setup\n\n### 1. Get Your Project URL\n- Go to your [Supabase Dashboard](https://supabase.com/dashboard)\n- Select your project\n- Go to **Settings** → **API**\n- Copy the **Project URL** (format: `https://your-project-ref.supabase.co`)\n\n### 2. Get Your API Key\nChoose the appropriate key based on your use case:\n\n**For Actions (Database Operations):**\n- Use **Service Role Key** (secret) for server-side operations\n- Has full access to bypass Row Level Security (RLS)\n\n**For Triggers (Webhooks):**\n- Use **Anonymous Key** (public) if your webhooks don't need elevated permissions\n- Use **Service Role Key** for elevated permissions\n\n**Security Note:** Keep your Service Role Key secret - it bypasses all RLS policies.\n\nFind your keys in **Settings** → **API** → **Project API keys**\n",
|
||||
"Upload File": "Upload File",
|
||||
"Create Row": "Create Row",
|
||||
"Update Row": "Update Row",
|
||||
"Upsert Row": "Upsert Row",
|
||||
"Delete Rows": "Delete Rows",
|
||||
"Search Rows": "Search Rows",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Upload a file to Supabase Storage": "Upload a file to Supabase Storage",
|
||||
"Create a new row in a table": "Create a new row in a table",
|
||||
"Update rows in a table based on filter criteria": "Update rows in a table based on filter criteria",
|
||||
"Insert or update a row in a table": "Insert or update a row in a table",
|
||||
"Remove rows matching filter criteria from a table": "Remove rows matching filter criteria from a table",
|
||||
"Search for rows in a table with filters and pagination": "Search for rows in a table with filters and pagination",
|
||||
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
|
||||
"File path": "File path",
|
||||
"Bucket": "Bucket",
|
||||
"Base64 or URL": "Base64 or URL",
|
||||
"Table Name": "Table Name",
|
||||
"Row Data": "Row Data",
|
||||
"Return Created Row": "Return Created Row",
|
||||
"Filter Type": "Filter Type",
|
||||
"Filter Column": "Filter Column",
|
||||
"Filter Value": "Filter Value",
|
||||
"Filter Values": "Filter Values",
|
||||
"Update Data": "Update Data",
|
||||
"Count Updated Rows": "Count Updated Rows",
|
||||
"Return Updated Rows": "Return Updated Rows",
|
||||
"Conflict Column": "Conflict Column",
|
||||
"Count Upserted Rows": "Count Upserted Rows",
|
||||
"Return Upserted Rows": "Return Upserted Rows",
|
||||
"Count Deleted Rows": "Count Deleted Rows",
|
||||
"Return Deleted Rows": "Return Deleted Rows",
|
||||
"Columns": "Columns",
|
||||
"Filters": "Filters",
|
||||
"Page": "Page",
|
||||
"Page Size": "Page Size",
|
||||
"Count Algorithm": "Count Algorithm",
|
||||
"Method": "Method",
|
||||
"Headers": "Headers",
|
||||
"Query Parameters": "Query Parameters",
|
||||
"Body": "Body",
|
||||
"Response is Binary ?": "Response is Binary ?",
|
||||
"No Error on Failure": "No Error on Failure",
|
||||
"Timeout (in seconds)": "Timeout (in seconds)",
|
||||
"Select a table from your database": "Select a table from your database",
|
||||
"Enter the data for each column": "Enter the data for each column",
|
||||
"Whether to return the created row": "Whether to return the created row",
|
||||
"How to identify rows to update": "How to identify rows to update",
|
||||
"Select the column to filter on": "Select the column to filter on",
|
||||
"The value to match against (not used for \"in list\" filter)": "The value to match against (not used for \"in list\" filter)",
|
||||
"List of values for \"in list\" filter type": "List of values for \"in list\" filter type",
|
||||
"Select which columns to update (auto-generated fields excluded)": "Select which columns to update (auto-generated fields excluded)",
|
||||
"Whether to count the number of updated rows": "Whether to count the number of updated rows",
|
||||
"Whether to return the updated rows data": "Whether to return the updated rows data",
|
||||
"Select the unique column to determine duplicates (required for upsert to work)": "Select the unique column to determine duplicates (required for upsert to work)",
|
||||
"Enter data for the row (conflict detection handled separately)": "Enter data for the row (conflict detection handled separately)",
|
||||
"Whether to count the number of upserted rows": "Whether to count the number of upserted rows",
|
||||
"Whether to return the upserted rows data": "Whether to return the upserted rows data",
|
||||
"How to filter rows for deletion": "How to filter rows for deletion",
|
||||
"The value to match against (not used for null checks)": "The value to match against (not used for null checks)",
|
||||
"List of values for \"in\" filter type": "List of values for \"in\" filter type",
|
||||
"Whether to count the number of deleted rows": "Whether to count the number of deleted rows",
|
||||
"Whether to return the deleted rows data": "Whether to return the deleted rows data",
|
||||
"Columns to return (comma-separated). Leave empty to return all columns.": "Columns to return (comma-separated). Leave empty to return all columns.",
|
||||
"List of filters to apply": "List of filters to apply",
|
||||
"Page number for pagination (starts from 1)": "Page number for pagination (starts from 1)",
|
||||
"Number of records per page (max 1000)": "Number of records per page (max 1000)",
|
||||
"Algorithm to use for counting rows": "Algorithm to use for counting rows",
|
||||
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
|
||||
"Enable for files like PDFs, images, etc..": "Enable for files like PDFs, images, etc..",
|
||||
"Column equals value": "Column equals value",
|
||||
"Column is in list of values": "Column is in list of values",
|
||||
"Column is greater than value": "Column is greater than value",
|
||||
"Column not equals value": "Column not equals value",
|
||||
"Column is in list": "Column is in list",
|
||||
"Column is greater than": "Column is greater than",
|
||||
"Column is greater than or equal": "Column is greater than or equal",
|
||||
"Column is less than": "Column is less than",
|
||||
"Column is less than or equal": "Column is less than or equal",
|
||||
"Column is null": "Column is null",
|
||||
"Column is not null": "Column is not null",
|
||||
"Column matches pattern (LIKE)": "Column matches pattern (LIKE)",
|
||||
"Column matches pattern (case-insensitive)": "Column matches pattern (case-insensitive)",
|
||||
"Exact": "Exact",
|
||||
"Planned": "Planned",
|
||||
"Estimated": "Estimated",
|
||||
"GET": "GET",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "DELETE",
|
||||
"HEAD": "HEAD",
|
||||
"New Row": "New Row",
|
||||
"Fires when a new row is created in a table": "Fires when a new row is created in a table",
|
||||
"Markdown": "Markdown",
|
||||
"Schema": "Schema",
|
||||
"## Setup Instructions\n\n1. **Go to your Supabase Dashboard** → Database → Webhooks\n2. **Click \"Create a new hook\"**\n3. **Configure the webhook:**\n - **Name**: Give it a descriptive name (e.g., \"Activepieces New Row\")\n - **Table**: Select the table you want to monitor\n - **Events**: Check \"Insert\" \n - **Type**: HTTP Request\n - **Method**: POST\n - **URL**: Copy and paste the webhook URL below\n4. **Click \"Create webhook\"**\n\n**Webhook URL:** `{{webhookUrl}}`\n\n## Important Notes\n- The webhook will sen": "## Setup Instructions\n\n1. **Go to your Supabase Dashboard** → Database → Webhooks\n2. **Click \"Create a new hook\"**\n3. **Configure the webhook:**\n - **Name**: Give it a descriptive name (e.g., \"Activepieces New Row\")\n - **Table**: Select the table you want to monitor\n - **Events**: Check \"Insert\" \n - **Type**: HTTP Request\n - **Method**: POST\n - **URL**: Copy and paste the webhook URL below\n4. **Click \"Create webhook\"**\n\n**Webhook URL:** `{{webhookUrl}}`\n\n## Important Notes\n- The webhook will send a JSON payload with the new row data\n- Make sure your table has the necessary permissions\n- You can test the webhook by inserting a new row into your table\n\nFor more details, see [Supabase Database Webhooks documentation](https://supabase.com/docs/guides/database/webhooks).",
|
||||
"Database schema (default: public)": "Database schema (default: public)"
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
{
|
||||
"Supabase": "Supabase",
|
||||
"The open-source Firebase alternative": "The open-source Firebase alternative",
|
||||
"Project URL": "Project URL",
|
||||
"API Key": "API Key",
|
||||
"Your Supabase project URL (e.g., https://your-project-ref.supabase.co)": "Your Supabase project URL (e.g., https://your-project-ref.supabase.co)",
|
||||
"Service Role Key (for actions) or Anonymous Key (for basic triggers)": "Service Role Key (for actions) or Anonymous Key (for basic triggers)",
|
||||
"\n## Supabase Connection Setup\n\n### 1. Get Your Project URL\n- Go to your [Supabase Dashboard](https://supabase.com/dashboard)\n- Select your project\n- Go to **Settings** → **API**\n- Copy the **Project URL** (format: `https://your-project-ref.supabase.co`)\n\n### 2. Get Your API Key\nChoose the appropriate key based on your use case:\n\n**For Actions (Database Operations):**\n- Use **Service Role Key** (secret) for server-side operations\n- Has full access to bypass Row Level Security (RLS)\n\n**For Triggers (Webhooks)": "\n## Supabase Connection Setup\n\n### 1. Get Your Project URL\n- Go to your [Supabase Dashboard](https://supabase.com/dashboard)\n- Select your project\n- Go to **Settings** → **API**\n- Copy the **Project URL** (format: `https://your-project-ref.supabase.co`)\n\n### 2. Get Your API Key\nChoose the appropriate key based on your use case:\n\n**For Actions (Database Operations):**\n- Use **Service Role Key** (secret) for server-side operations\n- Has full access to bypass Row Level Security (RLS)\n\n**For Triggers (Webhooks):**\n- Use **Anonymous Key** (public) if your webhooks don't need elevated permissions\n- Use **Service Role Key** for elevated permissions\n\n**Security Note:** Keep your Service Role Key secret - it bypasses all RLS policies.\n\nFind your keys in **Settings** → **API** → **Project API keys**\n",
|
||||
"Upload File": "Upload File",
|
||||
"Create Row": "Create Row",
|
||||
"Update Row": "Update Row",
|
||||
"Upsert Row": "Upsert Row",
|
||||
"Delete Rows": "Delete Rows",
|
||||
"Search Rows": "Search Rows",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Upload a file to Supabase Storage": "Upload a file to Supabase Storage",
|
||||
"Create a new row in a table": "Create a new row in a table",
|
||||
"Update rows in a table based on filter criteria": "Update rows in a table based on filter criteria",
|
||||
"Insert or update a row in a table": "Insert or update a row in a table",
|
||||
"Remove rows matching filter criteria from a table": "Remove rows matching filter criteria from a table",
|
||||
"Search for rows in a table with filters and pagination": "Search for rows in a table with filters and pagination",
|
||||
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
|
||||
"File path": "File path",
|
||||
"Bucket": "Bucket",
|
||||
"Base64 or URL": "Base64 or URL",
|
||||
"Table Name": "Table Name",
|
||||
"Row Data": "Row Data",
|
||||
"Return Created Row": "Return Created Row",
|
||||
"Filter Type": "Filter Type",
|
||||
"Filter Column": "Filter Column",
|
||||
"Filter Value": "Filter Value",
|
||||
"Filter Values": "Filter Values",
|
||||
"Update Data": "Update Data",
|
||||
"Count Updated Rows": "Count Updated Rows",
|
||||
"Return Updated Rows": "Return Updated Rows",
|
||||
"Conflict Column": "Conflict Column",
|
||||
"Count Upserted Rows": "Count Upserted Rows",
|
||||
"Return Upserted Rows": "Return Upserted Rows",
|
||||
"Count Deleted Rows": "Count Deleted Rows",
|
||||
"Return Deleted Rows": "Return Deleted Rows",
|
||||
"Columns": "Columns",
|
||||
"Filters": "Bộ lọc",
|
||||
"Page": "Page",
|
||||
"Page Size": "Phân trang",
|
||||
"Count Algorithm": "Count Algorithm",
|
||||
"Method": "Method",
|
||||
"Headers": "Headers",
|
||||
"Query Parameters": "Query Parameters",
|
||||
"Body": "Body",
|
||||
"No Error on Failure": "No Error on Failure",
|
||||
"Timeout (in seconds)": "Timeout (in seconds)",
|
||||
"Select a table from your database": "Select a table from your database",
|
||||
"Enter the data for each column": "Enter the data for each column",
|
||||
"Whether to return the created row": "Whether to return the created row",
|
||||
"How to identify rows to update": "How to identify rows to update",
|
||||
"Select the column to filter on": "Select the column to filter on",
|
||||
"The value to match against (not used for \"in list\" filter)": "The value to match against (not used for \"in list\" filter)",
|
||||
"List of values for \"in list\" filter type": "List of values for \"in list\" filter type",
|
||||
"Select which columns to update (auto-generated fields excluded)": "Select which columns to update (auto-generated fields excluded)",
|
||||
"Whether to count the number of updated rows": "Whether to count the number of updated rows",
|
||||
"Whether to return the updated rows data": "Whether to return the updated rows data",
|
||||
"Select the unique column to determine duplicates (required for upsert to work)": "Select the unique column to determine duplicates (required for upsert to work)",
|
||||
"Enter data for the row (conflict detection handled separately)": "Enter data for the row (conflict detection handled separately)",
|
||||
"Whether to count the number of upserted rows": "Whether to count the number of upserted rows",
|
||||
"Whether to return the upserted rows data": "Whether to return the upserted rows data",
|
||||
"How to filter rows for deletion": "How to filter rows for deletion",
|
||||
"The value to match against (not used for null checks)": "The value to match against (not used for null checks)",
|
||||
"List of values for \"in\" filter type": "List of values for \"in\" filter type",
|
||||
"Whether to count the number of deleted rows": "Whether to count the number of deleted rows",
|
||||
"Whether to return the deleted rows data": "Whether to return the deleted rows data",
|
||||
"Columns to return (comma-separated). Leave empty to return all columns.": "Columns to return (comma-separated). Leave empty to return all columns.",
|
||||
"List of filters to apply": "List of filters to apply",
|
||||
"Page number for pagination (starts from 1)": "Page number for pagination (starts from 1)",
|
||||
"Number of records per page (max 1000)": "Number of records per page (max 1000)",
|
||||
"Algorithm to use for counting rows": "Algorithm to use for counting rows",
|
||||
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
|
||||
"Column equals value": "Column equals value",
|
||||
"Column is in list of values": "Column is in list of values",
|
||||
"Column is greater than value": "Column is greater than value",
|
||||
"Column not equals value": "Column not equals value",
|
||||
"Column is in list": "Column is in list",
|
||||
"Column is greater than": "Column is greater than",
|
||||
"Column is greater than or equal": "Column is greater than or equal",
|
||||
"Column is less than": "Column is less than",
|
||||
"Column is less than or equal": "Column is less than or equal",
|
||||
"Column is null": "Column is null",
|
||||
"Column is not null": "Column is not null",
|
||||
"Column matches pattern (LIKE)": "Column matches pattern (LIKE)",
|
||||
"Column matches pattern (case-insensitive)": "Column matches pattern (case-insensitive)",
|
||||
"Exact": "Exact",
|
||||
"Planned": "Planned",
|
||||
"Estimated": "Estimated",
|
||||
"GET": "GET",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "DELETE",
|
||||
"HEAD": "HEAD",
|
||||
"New Row": "New Row",
|
||||
"Fires when a new row is created in a table": "Fires when a new row is created in a table",
|
||||
"Markdown": "Markdown",
|
||||
"Schema": "Schema",
|
||||
"## Setup Instructions\n\n1. **Go to your Supabase Dashboard** → Database → Webhooks\n2. **Click \"Create a new hook\"**\n3. **Configure the webhook:**\n - **Name**: Give it a descriptive name (e.g., \"Activepieces New Row\")\n - **Table**: Select the table you want to monitor\n - **Events**: Check \"Insert\" \n - **Type**: HTTP Request\n - **Method**: POST\n - **URL**: Copy and paste the webhook URL below\n4. **Click \"Create webhook\"**\n\n**Webhook URL:** `{{webhookUrl}}`\n\n## Important Notes\n- The webhook will sen": "## Setup Instructions\n\n1. **Go to your Supabase Dashboard** → Database → Webhooks\n2. **Click \"Create a new hook\"**\n3. **Configure the webhook:**\n - **Name**: Give it a descriptive name (e.g., \"Activepieces New Row\")\n - **Table**: Select the table you want to monitor\n - **Events**: Check \"Insert\" \n - **Type**: HTTP Request\n - **Method**: POST\n - **URL**: Copy and paste the webhook URL below\n4. **Click \"Create webhook\"**\n\n**Webhook URL:** `{{webhookUrl}}`\n\n## Important Notes\n- The webhook will send a JSON payload with the new row data\n- Make sure your table has the necessary permissions\n- You can test the webhook by inserting a new row into your table\n\nFor more details, see [Supabase Database Webhooks documentation](https://supabase.com/docs/guides/database/webhooks).",
|
||||
"Database schema (default: public)": "Database schema (default: public)"
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
{
|
||||
"The open-source Firebase alternative": "The open-source Firebase alternative",
|
||||
"Project URL": "Project URL",
|
||||
"API Key": "API 密钥",
|
||||
"Your Supabase project URL (e.g., https://your-project-ref.supabase.co)": "Your Supabase project URL (e.g., https://your-project-ref.supabase.co)",
|
||||
"Service Role Key (for actions) or Anonymous Key (for basic triggers)": "Service Role Key (for actions) or Anonymous Key (for basic triggers)",
|
||||
"\n## Supabase Connection Setup\n\n### 1. Get Your Project URL\n- Go to your [Supabase Dashboard](https://supabase.com/dashboard)\n- Select your project\n- Go to **Settings** → **API**\n- Copy the **Project URL** (format: `https://your-project-ref.supabase.co`)\n\n### 2. Get Your API Key\nChoose the appropriate key based on your use case:\n\n**For Actions (Database Operations):**\n- Use **Service Role Key** (secret) for server-side operations\n- Has full access to bypass Row Level Security (RLS)\n\n**For Triggers (Webhooks)": "\n## Supabase Connection Setup\n\n### 1. Get Your Project URL\n- Go to your [Supabase Dashboard](https://supabase.com/dashboard)\n- Select your project\n- Go to **Settings** → **API**\n- Copy the **Project URL** (format: `https://your-project-ref.supabase.co`)\n\n### 2. Get Your API Key\nChoose the appropriate key based on your use case:\n\n**For Actions (Database Operations):**\n- Use **Service Role Key** (secret) for server-side operations\n- Has full access to bypass Row Level Security (RLS)\n\n**For Triggers (Webhooks):**\n- Use **Anonymous Key** (public) if your webhooks don't need elevated permissions\n- Use **Service Role Key** for elevated permissions\n\n**Security Note:** Keep your Service Role Key secret - it bypasses all RLS policies.\n\nFind your keys in **Settings** → **API** → **Project API keys**\n",
|
||||
"Upload File": "Upload File",
|
||||
"Create Row": "Create Row",
|
||||
"Update Row": "更新行",
|
||||
"Upsert Row": "Upsert Row",
|
||||
"Delete Rows": "Delete Rows",
|
||||
"Search Rows": "Search Rows",
|
||||
"Custom API Call": "自定义 API 呼叫",
|
||||
"Upload a file to Supabase Storage": "Upload a file to Supabase Storage",
|
||||
"Create a new row in a table": "Create a new row in a table",
|
||||
"Update rows in a table based on filter criteria": "Update rows in a table based on filter criteria",
|
||||
"Insert or update a row in a table": "Insert or update a row in a table",
|
||||
"Remove rows matching filter criteria from a table": "Remove rows matching filter criteria from a table",
|
||||
"Search for rows in a table with filters and pagination": "Search for rows in a table with filters and pagination",
|
||||
"Make a custom API call to a specific endpoint": "将一个自定义 API 调用到一个特定的终点",
|
||||
"File path": "File path",
|
||||
"Bucket": "Bucket",
|
||||
"Base64 or URL": "Base64 or URL",
|
||||
"Table Name": "Table Name",
|
||||
"Row Data": "Row Data",
|
||||
"Return Created Row": "Return Created Row",
|
||||
"Filter Type": "Filter Type",
|
||||
"Filter Column": "Filter Column",
|
||||
"Filter Value": "Filter Value",
|
||||
"Filter Values": "Filter Values",
|
||||
"Update Data": "Update Data",
|
||||
"Count Updated Rows": "Count Updated Rows",
|
||||
"Return Updated Rows": "Return Updated Rows",
|
||||
"Conflict Column": "Conflict Column",
|
||||
"Count Upserted Rows": "Count Upserted Rows",
|
||||
"Return Upserted Rows": "Return Upserted Rows",
|
||||
"Count Deleted Rows": "Count Deleted Rows",
|
||||
"Return Deleted Rows": "Return Deleted Rows",
|
||||
"Columns": "Columns",
|
||||
"Filters": "篩選條件",
|
||||
"Page": "Page",
|
||||
"Page Size": "Page Size",
|
||||
"Count Algorithm": "Count Algorithm",
|
||||
"Method": "方法",
|
||||
"Headers": "信头",
|
||||
"Query Parameters": "查询参数",
|
||||
"Body": "正文内容",
|
||||
"Response is Binary ?": "Response is Binary ?",
|
||||
"No Error on Failure": "失败时没有错误",
|
||||
"Timeout (in seconds)": "超时(秒)",
|
||||
"Select a table from your database": "Select a table from your database",
|
||||
"Enter the data for each column": "Enter the data for each column",
|
||||
"Whether to return the created row": "Whether to return the created row",
|
||||
"How to identify rows to update": "How to identify rows to update",
|
||||
"Select the column to filter on": "Select the column to filter on",
|
||||
"The value to match against (not used for \"in list\" filter)": "The value to match against (not used for \"in list\" filter)",
|
||||
"List of values for \"in list\" filter type": "List of values for \"in list\" filter type",
|
||||
"Select which columns to update (auto-generated fields excluded)": "Select which columns to update (auto-generated fields excluded)",
|
||||
"Whether to count the number of updated rows": "Whether to count the number of updated rows",
|
||||
"Whether to return the updated rows data": "Whether to return the updated rows data",
|
||||
"Select the unique column to determine duplicates (required for upsert to work)": "Select the unique column to determine duplicates (required for upsert to work)",
|
||||
"Enter data for the row (conflict detection handled separately)": "Enter data for the row (conflict detection handled separately)",
|
||||
"Whether to count the number of upserted rows": "Whether to count the number of upserted rows",
|
||||
"Whether to return the upserted rows data": "Whether to return the upserted rows data",
|
||||
"How to filter rows for deletion": "How to filter rows for deletion",
|
||||
"The value to match against (not used for null checks)": "The value to match against (not used for null checks)",
|
||||
"List of values for \"in\" filter type": "List of values for \"in\" filter type",
|
||||
"Whether to count the number of deleted rows": "Whether to count the number of deleted rows",
|
||||
"Whether to return the deleted rows data": "Whether to return the deleted rows data",
|
||||
"Columns to return (comma-separated). Leave empty to return all columns.": "Columns to return (comma-separated). Leave empty to return all columns.",
|
||||
"List of filters to apply": "List of filters to apply",
|
||||
"Page number for pagination (starts from 1)": "Page number for pagination (starts from 1)",
|
||||
"Number of records per page (max 1000)": "Number of records per page (max 1000)",
|
||||
"Algorithm to use for counting rows": "Algorithm to use for counting rows",
|
||||
"Authorization headers are injected automatically from your connection.": "授权头自动从您的连接中注入。",
|
||||
"Enable for files like PDFs, images, etc..": "Enable for files like PDFs, images, etc..",
|
||||
"Column equals value": "Column equals value",
|
||||
"Column is in list of values": "Column is in list of values",
|
||||
"Column is greater than value": "Column is greater than value",
|
||||
"Column not equals value": "Column not equals value",
|
||||
"Column is in list": "Column is in list",
|
||||
"Column is greater than": "Column is greater than",
|
||||
"Column is greater than or equal": "Column is greater than or equal",
|
||||
"Column is less than": "Column is less than",
|
||||
"Column is less than or equal": "Column is less than or equal",
|
||||
"Column is null": "Column is null",
|
||||
"Column is not null": "Column is not null",
|
||||
"Column matches pattern (LIKE)": "Column matches pattern (LIKE)",
|
||||
"Column matches pattern (case-insensitive)": "Column matches pattern (case-insensitive)",
|
||||
"Exact": "Exact",
|
||||
"Planned": "Planned",
|
||||
"Estimated": "Estimated",
|
||||
"GET": "获取",
|
||||
"POST": "帖子",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "弹出",
|
||||
"DELETE": "删除",
|
||||
"HEAD": "黑色",
|
||||
"New Row": "New Row",
|
||||
"Fires when a new row is created in a table": "Fires when a new row is created in a table",
|
||||
"Markdown": "Markdown",
|
||||
"Schema": "Schema",
|
||||
"## Setup Instructions\n\n1. **Go to your Supabase Dashboard** → Database → Webhooks\n2. **Click \"Create a new hook\"**\n3. **Configure the webhook:**\n - **Name**: Give it a descriptive name (e.g., \"Activepieces New Row\")\n - **Table**: Select the table you want to monitor\n - **Events**: Check \"Insert\" \n - **Type**: HTTP Request\n - **Method**: POST\n - **URL**: Copy and paste the webhook URL below\n4. **Click \"Create webhook\"**\n\n**Webhook URL:** `{{webhookUrl}}`\n\n## Important Notes\n- The webhook will sen": "## Setup Instructions\n\n1. **Go to your Supabase Dashboard** → Database → Webhooks\n2. **Click \"Create a new hook\"**\n3. **Configure the webhook:**\n - **Name**: Give it a descriptive name (e.g., \"Activepieces New Row\")\n - **Table**: Select the table you want to monitor\n - **Events**: Check \"Insert\" \n - **Type**: HTTP Request\n - **Method**: POST\n - **URL**: Copy and paste the webhook URL below\n4. **Click \"Create webhook\"**\n\n**Webhook URL:** `{{webhookUrl}}`\n\n## Important Notes\n- The webhook will send a JSON payload with the new row data\n- Make sure your table has the necessary permissions\n- You can test the webhook by inserting a new row into your table\n\nFor more details, see [Supabase Database Webhooks documentation](https://supabase.com/docs/guides/database/webhooks).",
|
||||
"Database schema (default: public)": "Database schema (default: public)"
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
import { createCustomApiCallAction } from '@activepieces/pieces-common';
|
||||
import {
|
||||
createPiece,
|
||||
PieceAuth,
|
||||
Property,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { createClient } from '@supabase/supabase-js';
|
||||
import { PieceCategory } from '@activepieces/shared';
|
||||
import { uploadFile } from './lib/actions/upload-file';
|
||||
import { createRow } from './lib/actions/create-row';
|
||||
import { deleteRows } from './lib/actions/delete-rows';
|
||||
import { updateRow } from './lib/actions/update-row';
|
||||
import { upsertRow } from './lib/actions/upsert-row';
|
||||
import { searchRows } from './lib/actions/search-rows';
|
||||
import { newRow } from './lib/triggers/new-row';
|
||||
|
||||
const markdown = `
|
||||
## Supabase Connection Setup
|
||||
|
||||
### 1. Get Your Project URL
|
||||
- Go to your [Supabase Dashboard](https://supabase.com/dashboard)
|
||||
- Select your project
|
||||
- Go to **Settings** → **API**
|
||||
- Copy the **Project URL** (format: \`https://your-project-ref.supabase.co\`)
|
||||
|
||||
### 2. Get Your API Key
|
||||
Choose the appropriate key based on your use case:
|
||||
|
||||
**For Actions (Database Operations):**
|
||||
- Use **Service Role Key** (secret) for server-side operations
|
||||
- Has full access to bypass Row Level Security (RLS)
|
||||
|
||||
**For Triggers (Webhooks):**
|
||||
- Use **Anonymous Key** (public) if your webhooks don't need elevated permissions
|
||||
- Use **Service Role Key** for elevated permissions
|
||||
|
||||
**Security Note:** Keep your Service Role Key secret - it bypasses all RLS policies.
|
||||
|
||||
Find your keys in **Settings** → **API** → **Project API keys**
|
||||
`;
|
||||
|
||||
export const supabaseAuth = PieceAuth.CustomAuth({
|
||||
required: true,
|
||||
description: markdown,
|
||||
props: {
|
||||
url: Property.ShortText({
|
||||
displayName: 'Project URL',
|
||||
description: 'Your Supabase project URL (e.g., https://your-project-ref.supabase.co)',
|
||||
required: true,
|
||||
}),
|
||||
apiKey: PieceAuth.SecretText({
|
||||
displayName: 'API Key',
|
||||
description: 'Service Role Key (for actions) or Anonymous Key (for basic triggers)',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
validate: async ({ auth }) => {
|
||||
try {
|
||||
const { url, apiKey } = auth;
|
||||
|
||||
try {
|
||||
const parsedUrl = new URL(url);
|
||||
if (!parsedUrl.hostname.endsWith('.supabase.co')) {
|
||||
return {
|
||||
valid: false,
|
||||
error: 'URL must be a valid Supabase project URL (e.g., https://your-project-ref.supabase.co)'
|
||||
};
|
||||
}
|
||||
if (parsedUrl.protocol !== 'https:') {
|
||||
return {
|
||||
valid: false,
|
||||
error: 'URL must use HTTPS protocol'
|
||||
};
|
||||
}
|
||||
} catch {
|
||||
return {
|
||||
valid: false,
|
||||
error: 'Please enter a valid URL'
|
||||
};
|
||||
}
|
||||
|
||||
if (!apiKey.startsWith('eyJ') && !apiKey.startsWith('sbp_')) {
|
||||
return {
|
||||
valid: false,
|
||||
error: 'Invalid API key format. Use either the Service Role Key or Anonymous Key from your Supabase project settings'
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`${url}/rest/v1/`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'apikey': apiKey,
|
||||
'Authorization': `Bearer ${apiKey}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
if (response.status >= 200 && response.status < 300) {
|
||||
return { valid: true };
|
||||
}
|
||||
|
||||
if (response.status === 401 || response.status === 403) {
|
||||
return { valid: true };
|
||||
}
|
||||
|
||||
const errorText = await response.text();
|
||||
return {
|
||||
valid: false,
|
||||
error: `HTTP ${response.status}: ${errorText}. Please verify your URL and API key.`
|
||||
};
|
||||
|
||||
} catch (networkError) {
|
||||
return {
|
||||
valid: false,
|
||||
error: `Network error: ${networkError instanceof Error ? networkError.message : 'Could not connect to Supabase'}. Please check your URL.`
|
||||
};
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
return {
|
||||
valid: false,
|
||||
error: `Failed to connect to Supabase: ${error instanceof Error ? error.message : 'Unknown error'}. Please check your URL and API key.`
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
export const supabase = createPiece({
|
||||
displayName: 'Supabase',
|
||||
description: 'The open-source Firebase alternative',
|
||||
auth: supabaseAuth,
|
||||
minimumSupportedRelease: '0.30.0',
|
||||
logoUrl: 'https://cdn.activepieces.com/pieces/supabase.png',
|
||||
categories: [PieceCategory.DEVELOPER_TOOLS],
|
||||
authors: ["kishanprmr","MoShizzle","abuaboud","fortunamide"],
|
||||
actions: [
|
||||
uploadFile,
|
||||
createRow,
|
||||
updateRow,
|
||||
upsertRow,
|
||||
deleteRows,
|
||||
searchRows,
|
||||
createCustomApiCallAction({
|
||||
baseUrl: (auth) => auth?.props?.url || '',
|
||||
auth: supabaseAuth,
|
||||
authMapping: async (auth) => ({
|
||||
Authorization: `Bearer ${auth.props.apiKey}`,
|
||||
}),
|
||||
}),
|
||||
],
|
||||
triggers: [
|
||||
newRow,
|
||||
],
|
||||
});
|
||||
@@ -0,0 +1,55 @@
|
||||
import { createAction, Property } from "@activepieces/pieces-framework";
|
||||
import { supabaseAuth } from "../../index";
|
||||
import { createClient } from "@supabase/supabase-js";
|
||||
import { supabaseCommon } from "../common/props";
|
||||
|
||||
export const createRow = createAction({
|
||||
name: 'create_row',
|
||||
displayName: 'Create Row',
|
||||
description: 'Create a new row in a table',
|
||||
auth: supabaseAuth,
|
||||
props: {
|
||||
table_name: supabaseCommon.table_name,
|
||||
row_data: supabaseCommon.table_columns,
|
||||
return_row: Property.Checkbox({
|
||||
displayName: 'Return Created Row',
|
||||
description: 'Whether to return the created row',
|
||||
required: false,
|
||||
defaultValue: true,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { table_name, row_data, return_row } = context.propsValue;
|
||||
const { url, apiKey } = context.auth.props;
|
||||
|
||||
const supabase = createClient(url, apiKey);
|
||||
|
||||
const baseQuery = supabase.from(table_name as string).insert(row_data);
|
||||
|
||||
const { data, error } = return_row
|
||||
? await baseQuery.select()
|
||||
: await baseQuery;
|
||||
|
||||
if (error) {
|
||||
let errorMessage = error.message || 'Unknown error occurred';
|
||||
|
||||
if (error.code === '23505') {
|
||||
errorMessage = `Duplicate value: ${error.message}`;
|
||||
} else if (error.code === '23503') {
|
||||
errorMessage = `Foreign key constraint violation: ${error.message}`;
|
||||
} else if (error.code === '23502') {
|
||||
errorMessage = `Required field missing: ${error.message}`;
|
||||
} else if (error.code === '42703') {
|
||||
errorMessage = `Column does not exist: ${error.message}`;
|
||||
} else if (error.code === '42P01') {
|
||||
errorMessage = `Table does not exist: ${error.message}`;
|
||||
}
|
||||
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return data;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,227 @@
|
||||
import { createAction, Property } from "@activepieces/pieces-framework";
|
||||
import { supabaseAuth } from "../../index";
|
||||
import { createClient } from "@supabase/supabase-js";
|
||||
import { supabaseCommon } from "../common/props";
|
||||
|
||||
export const deleteRows = createAction({
|
||||
name: 'delete_rows',
|
||||
displayName: 'Delete Rows',
|
||||
description: 'Remove rows matching filter criteria from a table',
|
||||
auth: supabaseAuth,
|
||||
props: {
|
||||
table_name: supabaseCommon.table_name,
|
||||
filter_type: Property.StaticDropdown({
|
||||
displayName: 'Filter Type',
|
||||
description: 'How to filter rows for deletion',
|
||||
required: true,
|
||||
defaultValue: 'in',
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Column equals value', value: 'eq' },
|
||||
{ label: 'Column not equals value', value: 'neq' },
|
||||
{ label: 'Column is in list', value: 'in' },
|
||||
{ label: 'Column is greater than', value: 'gt' },
|
||||
{ label: 'Column is greater than or equal', value: 'gte' },
|
||||
{ label: 'Column is less than', value: 'lt' },
|
||||
{ label: 'Column is less than or equal', value: 'lte' },
|
||||
{ label: 'Column is null', value: 'is_null' },
|
||||
{ label: 'Column is not null', value: 'is_not_null' },
|
||||
{ label: 'Column matches pattern (LIKE)', value: 'like' },
|
||||
{ label: 'Column matches pattern (case-insensitive)', value: 'ilike' }
|
||||
]
|
||||
}
|
||||
}),
|
||||
filter_column: Property.Dropdown({
|
||||
auth: supabaseAuth,
|
||||
displayName: 'Filter Column',
|
||||
description: 'Select the column to filter on',
|
||||
required: true,
|
||||
refreshers: ['table_name'],
|
||||
options: async ({ auth, table_name }) => {
|
||||
if (!auth || !table_name) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Please select a table first'
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const { url, apiKey } = auth.props;
|
||||
const supabase = createClient(url, apiKey);
|
||||
|
||||
try {
|
||||
const { data: columns, error } = await supabase.rpc('get_table_columns', {
|
||||
p_table_name: table_name as unknown as string
|
||||
});
|
||||
|
||||
if (!error && columns && columns.length > 0) {
|
||||
return {
|
||||
disabled: false,
|
||||
options: columns.map((col: any) => ({
|
||||
label: `${col.column_name} (${col.data_type})`,
|
||||
value: col.column_name
|
||||
}))
|
||||
};
|
||||
}
|
||||
} catch (rpcError) {
|
||||
// Continue to OpenAPI fallback
|
||||
}
|
||||
|
||||
const response = await fetch(`${url}/rest/v1/`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'apikey': apiKey,
|
||||
'Authorization': `Bearer ${apiKey}`,
|
||||
'Accept': 'application/openapi+json'
|
||||
}
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const openApiSpec = await response.json();
|
||||
const definitions = openApiSpec.definitions || openApiSpec.components?.schemas || {};
|
||||
const tableDefinition = definitions[table_name as unknown as string];
|
||||
|
||||
if (tableDefinition && tableDefinition.properties) {
|
||||
const options = Object.entries(tableDefinition.properties).map(([columnName, columnDef]: [string, any]) => {
|
||||
const type = columnDef.type || 'unknown';
|
||||
return {
|
||||
label: `${columnName} (${type})`,
|
||||
value: columnName
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Could not load columns'
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Error loading columns'
|
||||
};
|
||||
}
|
||||
}
|
||||
}),
|
||||
filter_value: Property.ShortText({
|
||||
displayName: 'Filter Value',
|
||||
description: 'The value to match against (not used for null checks)',
|
||||
required: false,
|
||||
}),
|
||||
filter_values: Property.Array({
|
||||
displayName: 'Filter Values',
|
||||
description: 'List of values for "in" filter type',
|
||||
required: false,
|
||||
}),
|
||||
count_deleted: Property.Checkbox({
|
||||
displayName: 'Count Deleted Rows',
|
||||
description: 'Whether to count the number of deleted rows',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
return_deleted: Property.Checkbox({
|
||||
displayName: 'Return Deleted Rows',
|
||||
description: 'Whether to return the deleted rows data',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
})
|
||||
},
|
||||
async run(context) {
|
||||
const {
|
||||
table_name,
|
||||
filter_type,
|
||||
filter_column,
|
||||
filter_value,
|
||||
filter_values,
|
||||
count_deleted,
|
||||
return_deleted
|
||||
} = context.propsValue;
|
||||
const { url, apiKey } = context.auth.props;
|
||||
|
||||
const supabase = createClient(url, apiKey);
|
||||
|
||||
let deleteQuery = supabase
|
||||
.from(table_name as string)
|
||||
.delete({
|
||||
count: count_deleted ? 'exact' : undefined
|
||||
});
|
||||
|
||||
const columnName = filter_column as string;
|
||||
switch (filter_type) {
|
||||
case 'eq':
|
||||
if (!filter_value) throw new Error('Filter value is required for equality check');
|
||||
deleteQuery = deleteQuery.eq(columnName, filter_value);
|
||||
break;
|
||||
case 'neq':
|
||||
if (!filter_value) throw new Error('Filter value is required for not-equals check');
|
||||
deleteQuery = deleteQuery.neq(columnName, filter_value);
|
||||
break;
|
||||
case 'in':
|
||||
if (!filter_values || filter_values.length === 0) {
|
||||
throw new Error('Filter values are required for "in" filter type');
|
||||
}
|
||||
deleteQuery = deleteQuery.in(columnName, filter_values);
|
||||
break;
|
||||
case 'gt':
|
||||
if (!filter_value) throw new Error('Filter value is required for greater-than check');
|
||||
deleteQuery = deleteQuery.gt(columnName, filter_value);
|
||||
break;
|
||||
case 'gte':
|
||||
if (!filter_value) throw new Error('Filter value is required for greater-than-or-equal check');
|
||||
deleteQuery = deleteQuery.gte(columnName, filter_value);
|
||||
break;
|
||||
case 'lt':
|
||||
if (!filter_value) throw new Error('Filter value is required for less-than check');
|
||||
deleteQuery = deleteQuery.lt(columnName, filter_value);
|
||||
break;
|
||||
case 'lte':
|
||||
if (!filter_value) throw new Error('Filter value is required for less-than-or-equal check');
|
||||
deleteQuery = deleteQuery.lte(columnName, filter_value);
|
||||
break;
|
||||
case 'is_null':
|
||||
deleteQuery = deleteQuery.is(columnName, null);
|
||||
break;
|
||||
case 'is_not_null':
|
||||
deleteQuery = deleteQuery.not(columnName, 'is', null);
|
||||
break;
|
||||
case 'like':
|
||||
if (!filter_value) throw new Error('Filter value is required for like pattern matching');
|
||||
deleteQuery = deleteQuery.like(columnName, filter_value);
|
||||
break;
|
||||
case 'ilike':
|
||||
if (!filter_value) throw new Error('Filter value is required for case-insensitive like pattern matching');
|
||||
deleteQuery = deleteQuery.ilike(columnName, filter_value);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unsupported filter type: ${filter_type}`);
|
||||
}
|
||||
|
||||
const { data, error, count } = return_deleted
|
||||
? await deleteQuery.select()
|
||||
: await deleteQuery;
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
const result: any = {
|
||||
success: true,
|
||||
deleted_rows: return_deleted ? data : undefined,
|
||||
};
|
||||
|
||||
if (count_deleted) {
|
||||
result.deleted_count = count;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,197 @@
|
||||
import { createAction, Property } from "@activepieces/pieces-framework";
|
||||
import { supabaseAuth } from "../../index";
|
||||
import { createClient } from "@supabase/supabase-js";
|
||||
import { supabaseCommon } from "../common/props";
|
||||
|
||||
type FilterOperator = 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'like' | 'ilike' | 'is' | 'in' | 'contains' | 'containedBy';
|
||||
|
||||
interface Filter {
|
||||
field: string;
|
||||
operator: FilterOperator;
|
||||
value: string | number | boolean | null;
|
||||
}
|
||||
|
||||
export const searchRows = createAction({
|
||||
name: 'search_rows',
|
||||
displayName: 'Search Rows',
|
||||
description: 'Search for rows in a table with filters and pagination',
|
||||
auth: supabaseAuth,
|
||||
props: {
|
||||
table_name: supabaseCommon.table_name,
|
||||
columns: Property.ShortText({
|
||||
displayName: 'Columns',
|
||||
description: 'Columns to return (comma-separated). Leave empty to return all columns.',
|
||||
required: false,
|
||||
}),
|
||||
filters: Property.Array({
|
||||
displayName: 'Filters',
|
||||
description: 'List of filters to apply',
|
||||
required: false,
|
||||
properties: {
|
||||
field: Property.ShortText({
|
||||
displayName: 'Field',
|
||||
description: 'Field name to filter on (use -> for JSON fields, e.g. address->postcode)',
|
||||
required: true,
|
||||
}),
|
||||
operator: Property.StaticDropdown({
|
||||
displayName: 'Operator',
|
||||
description: 'Comparison operator',
|
||||
required: true,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Equals', value: 'eq' },
|
||||
{ label: 'Not Equals', value: 'neq' },
|
||||
{ label: 'Greater Than', value: 'gt' },
|
||||
{ label: 'Greater Than or Equal', value: 'gte' },
|
||||
{ label: 'Less Than', value: 'lt' },
|
||||
{ label: 'Less Than or Equal', value: 'lte' },
|
||||
{ label: 'Like', value: 'like' },
|
||||
{ label: 'ILike (Case Insensitive)', value: 'ilike' },
|
||||
{ label: 'Is', value: 'is' },
|
||||
{ label: 'In', value: 'in' },
|
||||
{ label: 'Contains', value: 'contains' },
|
||||
{ label: 'Contained By', value: 'containedBy' },
|
||||
]
|
||||
}
|
||||
}),
|
||||
value: Property.ShortText({
|
||||
displayName: 'Value',
|
||||
description: 'Value to compare against',
|
||||
required: true,
|
||||
}),
|
||||
}
|
||||
}),
|
||||
page: Property.Number({
|
||||
displayName: 'Page',
|
||||
description: 'Page number for pagination (starts from 1)',
|
||||
required: false,
|
||||
defaultValue: 1,
|
||||
}),
|
||||
pageSize: Property.Number({
|
||||
displayName: 'Page Size',
|
||||
description: 'Number of records per page (max 1000)',
|
||||
required: false,
|
||||
defaultValue: 20,
|
||||
}),
|
||||
countOption: Property.StaticDropdown({
|
||||
displayName: 'Count Algorithm',
|
||||
description: 'Algorithm to use for counting rows',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Exact', value: 'exact' },
|
||||
{ label: 'Planned', value: 'planned' },
|
||||
{ label: 'Estimated', value: 'estimated' },
|
||||
]
|
||||
}
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { table_name, columns, filters, page, pageSize, countOption } = context.propsValue;
|
||||
const { url, apiKey } = context.auth.props;
|
||||
|
||||
const currentPage = Math.max(1, page || 1);
|
||||
const currentPageSize = Math.min(1000, Math.max(1, pageSize || 20));
|
||||
|
||||
if (columns && !/^[a-zA-Z0-9_,.\s\->"*]+$/.test(columns)) {
|
||||
throw new Error('Invalid column specification. Only alphanumeric characters, underscores, commas, dots, arrows, quotes, and asterisks are allowed.');
|
||||
}
|
||||
|
||||
const supabase = createClient(url, apiKey);
|
||||
|
||||
let query = supabase.from(table_name as string).select(
|
||||
columns || '*',
|
||||
{ count: countOption as 'exact' | 'planned' | 'estimated' | undefined }
|
||||
);
|
||||
|
||||
if (filters && Array.isArray(filters) && filters.length > 0) {
|
||||
for (const filter of filters as Filter[]) {
|
||||
if (!filter.field || !filter.operator) {
|
||||
throw new Error('Filter must have both field and operator specified');
|
||||
}
|
||||
|
||||
if (!/^[a-zA-Z0-9_.\->"]+$/.test(filter.field)) {
|
||||
throw new Error(`Invalid field name: ${filter.field}. Only alphanumeric characters, underscores, dots, and arrows are allowed.`);
|
||||
}
|
||||
|
||||
try {
|
||||
switch (filter.operator) {
|
||||
case 'eq':
|
||||
query = query.eq(filter.field, filter.value);
|
||||
break;
|
||||
case 'neq':
|
||||
query = query.neq(filter.field, filter.value);
|
||||
break;
|
||||
case 'gt':
|
||||
query = query.gt(filter.field, filter.value);
|
||||
break;
|
||||
case 'gte':
|
||||
query = query.gte(filter.field, filter.value);
|
||||
break;
|
||||
case 'lt':
|
||||
query = query.lt(filter.field, filter.value);
|
||||
break;
|
||||
case 'lte':
|
||||
query = query.lte(filter.field, filter.value);
|
||||
break;
|
||||
case 'like':
|
||||
query = query.like(filter.field, String(filter.value));
|
||||
break;
|
||||
case 'ilike':
|
||||
query = query.ilike(filter.field, String(filter.value));
|
||||
break;
|
||||
case 'is':
|
||||
query = query.is(filter.field, filter.value);
|
||||
break;
|
||||
case 'in': {
|
||||
const inValues = Array.isArray(filter.value) ? filter.value : String(filter.value).split(',');
|
||||
query = query.in(filter.field, inValues);
|
||||
break;
|
||||
}
|
||||
case 'contains':
|
||||
if (typeof filter.value === 'string' || Array.isArray(filter.value) || (filter.value && typeof filter.value === 'object')) {
|
||||
query = query.contains(filter.field, filter.value);
|
||||
} else {
|
||||
throw new Error('Contains operator requires string, array, or object value');
|
||||
}
|
||||
break;
|
||||
case 'containedBy':
|
||||
if (typeof filter.value === 'string' || Array.isArray(filter.value) || (filter.value && typeof filter.value === 'object')) {
|
||||
query = query.containedBy(filter.field, filter.value);
|
||||
} else {
|
||||
throw new Error('ContainedBy operator requires string, array, or object value');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unsupported filter operator: ${filter.operator}`);
|
||||
}
|
||||
} catch (filterError) {
|
||||
throw new Error(`Failed to apply filter on field '${filter.field}' with operator '${filter.operator}': ${filterError instanceof Error ? filterError.message : 'Unknown error'}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const from = (currentPage - 1) * currentPageSize;
|
||||
const to = from + currentPageSize - 1;
|
||||
query = query.range(from, to);
|
||||
|
||||
const { data, error, count } = await query;
|
||||
|
||||
if (error) {
|
||||
throw new Error(`Database query failed: ${error.message}`);
|
||||
}
|
||||
|
||||
return {
|
||||
data: data || [],
|
||||
count: count || 0,
|
||||
page: currentPage,
|
||||
pageSize: currentPageSize,
|
||||
total_pages: count ? Math.ceil(count / currentPageSize) : 0,
|
||||
range: {
|
||||
from,
|
||||
to,
|
||||
returned: data?.length || 0
|
||||
}
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,203 @@
|
||||
import { createAction, Property, DynamicPropsValue } from "@activepieces/pieces-framework";
|
||||
import { supabaseAuth } from "../../index";
|
||||
import { createClient } from "@supabase/supabase-js";
|
||||
import { supabaseCommon } from "../common/props";
|
||||
|
||||
export const updateRow = createAction({
|
||||
name: 'update_row',
|
||||
displayName: 'Update Row',
|
||||
description: 'Update rows in a table based on filter criteria',
|
||||
auth: supabaseAuth,
|
||||
props: {
|
||||
table_name: supabaseCommon.table_name,
|
||||
filter_type: Property.StaticDropdown({
|
||||
displayName: 'Filter Type',
|
||||
description: 'How to identify rows to update',
|
||||
required: true,
|
||||
defaultValue: 'eq',
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Column equals value', value: 'eq' },
|
||||
{ label: 'Column is in list of values', value: 'in' },
|
||||
{ label: 'Column is greater than value', value: 'gt' }
|
||||
]
|
||||
}
|
||||
}),
|
||||
filter_column: Property.Dropdown({
|
||||
auth: supabaseAuth,
|
||||
displayName: 'Filter Column',
|
||||
description: 'Select the column to filter on',
|
||||
required: true,
|
||||
refreshers: ['table_name'],
|
||||
options: async ({ auth, table_name }) => {
|
||||
if (!auth || !table_name) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Please select a table first'
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const { url, apiKey } = auth.props;
|
||||
const supabase = createClient(url, apiKey);
|
||||
|
||||
try {
|
||||
const { data: columns, error } = await supabase.rpc('get_table_columns', {
|
||||
p_table_name: table_name as unknown as string
|
||||
});
|
||||
|
||||
if (!error && columns && columns.length > 0) {
|
||||
return {
|
||||
disabled: false,
|
||||
options: columns.map((col: any) => ({
|
||||
label: `${col.column_name} (${col.data_type})`,
|
||||
value: col.column_name
|
||||
}))
|
||||
};
|
||||
}
|
||||
} catch (rpcError) {
|
||||
// Continue to OpenAPI fallback
|
||||
}
|
||||
|
||||
const response = await fetch(`${url}/rest/v1/`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'apikey': apiKey,
|
||||
'Authorization': `Bearer ${apiKey}`,
|
||||
'Accept': 'application/openapi+json'
|
||||
}
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const openApiSpec = await response.json();
|
||||
const definitions = openApiSpec.definitions || openApiSpec.components?.schemas || {};
|
||||
const tableDefinition = definitions[table_name as unknown as string];
|
||||
|
||||
if (tableDefinition && tableDefinition.properties) {
|
||||
const options = Object.entries(tableDefinition.properties).map(([columnName, columnDef]: [string, any]) => {
|
||||
const type = columnDef.type || 'unknown';
|
||||
return {
|
||||
label: `${columnName} (${type})`,
|
||||
value: columnName
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Could not load columns'
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Error loading columns'
|
||||
};
|
||||
}
|
||||
}
|
||||
}),
|
||||
filter_value: Property.ShortText({
|
||||
displayName: 'Filter Value',
|
||||
description: 'The value to match against (not used for "in list" filter)',
|
||||
required: false,
|
||||
}),
|
||||
filter_values: Property.Array({
|
||||
displayName: 'Filter Values',
|
||||
description: 'List of values for "in list" filter type',
|
||||
required: false,
|
||||
}),
|
||||
update_data: supabaseCommon.update_fields,
|
||||
count_updated: Property.Checkbox({
|
||||
displayName: 'Count Updated Rows',
|
||||
description: 'Whether to count the number of updated rows',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
return_updated: Property.Checkbox({
|
||||
displayName: 'Return Updated Rows',
|
||||
description: 'Whether to return the updated rows data',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
})
|
||||
},
|
||||
async run(context) {
|
||||
const {
|
||||
table_name,
|
||||
filter_type,
|
||||
filter_column,
|
||||
filter_value,
|
||||
filter_values,
|
||||
update_data,
|
||||
count_updated,
|
||||
return_updated
|
||||
} = context.propsValue;
|
||||
const { url, apiKey } = context.auth.props;
|
||||
|
||||
const supabase = createClient(url, apiKey);
|
||||
|
||||
let updateQuery = supabase
|
||||
.from(table_name as string)
|
||||
.update(update_data, {
|
||||
count: count_updated ? 'exact' : undefined
|
||||
});
|
||||
|
||||
const columnName = filter_column as string;
|
||||
switch (filter_type) {
|
||||
case 'eq':
|
||||
if (!filter_value) throw new Error('Filter value is required for equality check');
|
||||
updateQuery = updateQuery.eq(columnName, filter_value);
|
||||
break;
|
||||
case 'in':
|
||||
if (!filter_values || filter_values.length === 0) {
|
||||
throw new Error('Filter values are required for "in list" filter type');
|
||||
}
|
||||
updateQuery = updateQuery.in(columnName, filter_values);
|
||||
break;
|
||||
case 'gt':
|
||||
if (!filter_value) throw new Error('Filter value is required for greater-than check');
|
||||
updateQuery = updateQuery.gt(columnName, filter_value);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unsupported filter type: ${filter_type}`);
|
||||
}
|
||||
|
||||
const { data, error, count } = return_updated
|
||||
? await updateQuery.select()
|
||||
: await updateQuery;
|
||||
|
||||
if (error) {
|
||||
let errorMessage = error.message || 'Unknown error occurred';
|
||||
|
||||
if (error.code === '23505') {
|
||||
errorMessage = `Duplicate value: ${error.message}`;
|
||||
} else if (error.code === '23503') {
|
||||
errorMessage = `Foreign key constraint violation: ${error.message}`;
|
||||
} else if (error.code === '42703') {
|
||||
errorMessage = `Column does not exist: ${error.message}`;
|
||||
} else if (error.code === '42P01') {
|
||||
errorMessage = `Table does not exist: ${error.message}`;
|
||||
}
|
||||
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
|
||||
const result: any = {
|
||||
success: true,
|
||||
updated_rows: return_updated ? data : undefined,
|
||||
};
|
||||
|
||||
if (count_updated) {
|
||||
result.updated_count = count;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,44 @@
|
||||
import { supabaseAuth } from '../../index';
|
||||
import { Property, createAction } from '@activepieces/pieces-framework';
|
||||
import { createClient } from '@supabase/supabase-js';
|
||||
|
||||
export const uploadFile = createAction({
|
||||
auth: supabaseAuth,
|
||||
name: 'upload-file',
|
||||
displayName: 'Upload File',
|
||||
description: 'Upload a file to Supabase Storage',
|
||||
props: {
|
||||
filePath: Property.ShortText({
|
||||
displayName: 'File path',
|
||||
required: true,
|
||||
}),
|
||||
bucket: Property.ShortText({
|
||||
displayName: 'Bucket',
|
||||
required: true,
|
||||
}),
|
||||
file: Property.File({
|
||||
displayName: 'Base64 or URL',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { url, apiKey } = context.auth.props;
|
||||
const { file, filePath, bucket } = context.propsValue;
|
||||
const base64 = file.base64;
|
||||
// Convert base64 to array buffer
|
||||
const arrayBuffer = Uint8Array.from(atob(base64), (c) => c.charCodeAt(0));
|
||||
const supabase = createClient(url, apiKey);
|
||||
const { data, error } = await supabase.storage
|
||||
.from(bucket)
|
||||
.upload(filePath, arrayBuffer);
|
||||
if (error) {
|
||||
throw new Error(error.message);
|
||||
}
|
||||
const { data: pbData } = supabase.storage
|
||||
.from(bucket)
|
||||
.getPublicUrl(filePath);
|
||||
return {
|
||||
publicUrl: pbData.publicUrl,
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,182 @@
|
||||
import { createAction, Property } from "@activepieces/pieces-framework";
|
||||
import { supabaseAuth } from "../../index";
|
||||
import { createClient } from "@supabase/supabase-js";
|
||||
import { supabaseCommon } from "../common/props";
|
||||
|
||||
export const upsertRow = createAction({
|
||||
name: 'upsert_row',
|
||||
displayName: 'Upsert Row',
|
||||
description: 'Insert or update a row in a table',
|
||||
auth: supabaseAuth,
|
||||
props: {
|
||||
table_name: supabaseCommon.table_name,
|
||||
on_conflict: Property.Dropdown({
|
||||
auth: supabaseAuth,
|
||||
displayName: 'Conflict Column',
|
||||
description: 'Select the unique column to determine duplicates (required for upsert to work)',
|
||||
required: true,
|
||||
refreshers: ['table_name'],
|
||||
options: async ({ auth, table_name }) => {
|
||||
if (!auth || !table_name) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Please select a table first'
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const { url, apiKey } = auth.props;
|
||||
const supabase = createClient(url, apiKey);
|
||||
|
||||
try {
|
||||
const { data: columns, error } = await supabase.rpc('get_table_columns', {
|
||||
p_table_name: table_name as unknown as string
|
||||
});
|
||||
|
||||
if (!error && columns && columns.length > 0) {
|
||||
const options = columns.map((col: any) => ({
|
||||
label: `${col.column_name} (${col.data_type})`,
|
||||
value: col.column_name
|
||||
}));
|
||||
|
||||
options.sort((a: any, b: any) => {
|
||||
if (a.value === 'id') return -1;
|
||||
if (b.value === 'id') return 1;
|
||||
if (a.value.includes('_id')) return -1;
|
||||
if (b.value.includes('_id')) return 1;
|
||||
if (a.value === 'email') return -1;
|
||||
if (b.value === 'email') return 1;
|
||||
return 0;
|
||||
});
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options
|
||||
};
|
||||
}
|
||||
} catch (rpcError) {
|
||||
// Continue to OpenAPI fallback
|
||||
}
|
||||
|
||||
const response = await fetch(`${url}/rest/v1/`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'apikey': apiKey,
|
||||
'Authorization': `Bearer ${apiKey}`,
|
||||
'Accept': 'application/openapi+json'
|
||||
}
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const openApiSpec = await response.json();
|
||||
const definitions = openApiSpec.definitions || openApiSpec.components?.schemas || {};
|
||||
const tableDefinition = definitions[table_name as unknown as string];
|
||||
|
||||
if (tableDefinition && tableDefinition.properties) {
|
||||
const options = Object.entries(tableDefinition.properties).map(([columnName, columnDef]: [string, any]) => {
|
||||
const type = columnDef.type || 'unknown';
|
||||
return {
|
||||
label: `${columnName} (${type})`,
|
||||
value: columnName
|
||||
};
|
||||
});
|
||||
|
||||
options.sort((a: any, b: any) => {
|
||||
if (a.value === 'id') return -1;
|
||||
if (b.value === 'id') return 1;
|
||||
if (a.value.includes('_id')) return -1;
|
||||
if (b.value.includes('_id')) return 1;
|
||||
if (a.value === 'email') return -1;
|
||||
if (b.value === 'email') return 1;
|
||||
return 0;
|
||||
});
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Could not load columns'
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Error loading columns'
|
||||
};
|
||||
}
|
||||
}
|
||||
}),
|
||||
row_data: supabaseCommon.upsert_fields,
|
||||
count_upserted: Property.Checkbox({
|
||||
displayName: 'Count Upserted Rows',
|
||||
description: 'Whether to count the number of upserted rows',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
return_upserted: Property.Checkbox({
|
||||
displayName: 'Return Upserted Rows',
|
||||
description: 'Whether to return the upserted rows data',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
})
|
||||
},
|
||||
async run(context) {
|
||||
const {
|
||||
table_name,
|
||||
row_data,
|
||||
on_conflict,
|
||||
count_upserted,
|
||||
return_upserted
|
||||
} = context.propsValue;
|
||||
const { url, apiKey } = context.auth.props;
|
||||
|
||||
const supabase = createClient(url, apiKey);
|
||||
|
||||
const upsertOptions: any = {
|
||||
onConflict: on_conflict,
|
||||
count: count_upserted ? 'exact' : undefined
|
||||
};
|
||||
|
||||
const upsertQuery = supabase
|
||||
.from(table_name as string)
|
||||
.upsert(row_data, upsertOptions);
|
||||
|
||||
const { data, error, count } = return_upserted
|
||||
? await upsertQuery.select()
|
||||
: await upsertQuery;
|
||||
|
||||
if (error) {
|
||||
let errorMessage = error.message || 'Unknown error occurred';
|
||||
|
||||
if (error.code === '23505') {
|
||||
errorMessage = `Duplicate value: ${error.message}`;
|
||||
} else if (error.code === '23503') {
|
||||
errorMessage = `Foreign key constraint violation: ${error.message}`;
|
||||
} else if (error.code === '42703') {
|
||||
errorMessage = `Column does not exist: ${error.message}`;
|
||||
} else if (error.code === '42P01') {
|
||||
errorMessage = `Table does not exist: ${error.message}`;
|
||||
}
|
||||
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
|
||||
const result: any = {
|
||||
success: true,
|
||||
upserted_rows: return_upserted ? data : undefined,
|
||||
};
|
||||
|
||||
if (count_upserted) {
|
||||
result.upserted_count = count;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,657 @@
|
||||
import { Property, DynamicPropsValue } from "@activepieces/pieces-framework";
|
||||
import { createClient } from "@supabase/supabase-js";
|
||||
import { supabaseAuth } from "../..";
|
||||
|
||||
async function getColumnOptions(auth: any, table_name: string) {
|
||||
try {
|
||||
const { url, apiKey } =auth.props
|
||||
const supabase = createClient(url, apiKey);
|
||||
|
||||
try {
|
||||
const { data: columns, error } = await supabase.rpc('get_table_columns', {
|
||||
p_table_name: table_name
|
||||
});
|
||||
|
||||
if (!error && columns && columns.length > 0) {
|
||||
return columns.map((col: any) => ({
|
||||
label: `${col.column_name} (${col.data_type})`,
|
||||
value: col.column_name
|
||||
}));
|
||||
}
|
||||
} catch (rpcError) {
|
||||
// Continue to OpenAPI fallback
|
||||
}
|
||||
|
||||
const response = await fetch(`${url}/rest/v1/`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'apikey': apiKey,
|
||||
'Authorization': `Bearer ${apiKey}`,
|
||||
'Accept': 'application/openapi+json'
|
||||
}
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const openApiSpec = await response.json();
|
||||
const definitions = openApiSpec.definitions || openApiSpec.components?.schemas || {};
|
||||
const tableDefinition = definitions[table_name];
|
||||
|
||||
if (tableDefinition && tableDefinition.properties) {
|
||||
return Object.entries(tableDefinition.properties).map(([columnName, columnDef]: [string, any]) => {
|
||||
const type = columnDef.type || 'unknown';
|
||||
return {
|
||||
label: `${columnName} (${type})`,
|
||||
value: columnName
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
} catch (error) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
export const supabaseCommon = {
|
||||
table_name: Property.Dropdown({
|
||||
auth: supabaseAuth,
|
||||
|
||||
displayName: 'Table Name',
|
||||
description: 'Select a table from your database',
|
||||
required: true,
|
||||
refreshers: [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Please connect your Supabase account first.'
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const { url, apiKey } = auth.props;
|
||||
const supabase = createClient(url, apiKey);
|
||||
|
||||
try {
|
||||
const { data: tables, error } = await supabase.rpc('get_public_tables');
|
||||
if (!error && tables) {
|
||||
const tableOptions = tables.map((table: any) => ({
|
||||
label: table.table_name || table.name || table,
|
||||
value: table.table_name || table.name || table
|
||||
}));
|
||||
return {
|
||||
disabled: false,
|
||||
options: tableOptions
|
||||
};
|
||||
} else if (error) {
|
||||
console.log('RPC get_public_tables error:', error);
|
||||
}
|
||||
} catch (rpcError) {
|
||||
console.log('RPC function not available, using OpenAPI spec');
|
||||
}
|
||||
|
||||
let openApiSpec: any;
|
||||
try {
|
||||
const response = await fetch(`${url}/rest/v1/`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'apikey': apiKey,
|
||||
'Authorization': `Bearer ${apiKey}`,
|
||||
'Accept': 'application/openapi+json'
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Error loading tables. Please check your connection and permissions.'
|
||||
};
|
||||
}
|
||||
openApiSpec = await response.json();
|
||||
} catch (fetchError) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Network error. Please check your connection.'
|
||||
};
|
||||
}
|
||||
const paths = openApiSpec.paths || {};
|
||||
|
||||
const tableNames = Object.keys(paths)
|
||||
.filter(path => path.startsWith('/') && !path.includes('{') && path !== '/rpc')
|
||||
.map(path => path.substring(1))
|
||||
.filter(name => name && !name.includes('/'))
|
||||
.sort();
|
||||
|
||||
if (tableNames.length === 0) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'No tables found in your database.'
|
||||
};
|
||||
}
|
||||
|
||||
const tableOptions = tableNames.map(name => ({
|
||||
label: name,
|
||||
value: name
|
||||
}));
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options: tableOptions
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Error loading tables. Please check your connection.'
|
||||
};
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
table_columns: Property.DynamicProperties({
|
||||
auth: supabaseAuth,
|
||||
displayName: 'Row Data',
|
||||
description: 'Enter the data for each column',
|
||||
required: true,
|
||||
refreshers: ['table_name'],
|
||||
props: async (propsValue) => {
|
||||
const { auth, table_name } = propsValue;
|
||||
const properties: DynamicPropsValue = {};
|
||||
|
||||
if (!auth || !table_name) {
|
||||
return properties;
|
||||
}
|
||||
|
||||
try {
|
||||
const { url, apiKey } =auth.props
|
||||
const supabase = createClient(url, apiKey);
|
||||
|
||||
let columns: any[] = [];
|
||||
|
||||
try {
|
||||
const { data: rpcColumns, error } = await supabase.rpc('get_table_columns', {
|
||||
p_table_name: table_name as unknown as string
|
||||
});
|
||||
|
||||
if (!error && rpcColumns && rpcColumns.length > 0) {
|
||||
columns = rpcColumns;
|
||||
} else if (error) {
|
||||
console.log('RPC get_table_columns error:', error);
|
||||
}
|
||||
} catch (rpcError) {
|
||||
console.log('RPC function not available for columns');
|
||||
}
|
||||
|
||||
if (columns.length === 0) {
|
||||
let openApiSpec: any;
|
||||
try {
|
||||
const response = await fetch(`${url}/rest/v1/`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'apikey': apiKey,
|
||||
'Authorization': `Bearer ${apiKey}`,
|
||||
'Accept': 'application/openapi+json'
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
properties['error'] = Property.MarkDown({
|
||||
value: `Error loading columns for table "${table_name}". Please check your connection and permissions.`
|
||||
});
|
||||
return properties;
|
||||
}
|
||||
openApiSpec = await response.json();
|
||||
} catch (fetchError) {
|
||||
properties['error'] = Property.MarkDown({
|
||||
value: `Network error loading columns for table "${table_name}". Please check your connection.`
|
||||
});
|
||||
return properties;
|
||||
}
|
||||
const definitions = openApiSpec.definitions || openApiSpec.components?.schemas || {};
|
||||
|
||||
const tableDefinition = definitions[table_name as unknown as string];
|
||||
if (!tableDefinition || !tableDefinition.properties) {
|
||||
properties['info'] = Property.MarkDown({
|
||||
value: `No columns found for table "${table_name}". Please check if the table exists.`
|
||||
});
|
||||
return properties;
|
||||
}
|
||||
|
||||
columns = Object.entries(tableDefinition.properties).map(([columnName, columnDef]: [string, any]) => {
|
||||
let dataType = 'text';
|
||||
|
||||
if (columnDef.type) {
|
||||
dataType = columnDef.type;
|
||||
|
||||
if (columnDef.type === 'array') {
|
||||
dataType = 'array';
|
||||
}
|
||||
else if (columnDef.format) {
|
||||
if (columnDef.format === 'date-time' || columnDef.format === 'timestamp') {
|
||||
dataType = 'timestamp';
|
||||
} else if (columnDef.format === 'date') {
|
||||
dataType = 'date';
|
||||
} else if (columnDef.format === 'uuid') {
|
||||
dataType = 'uuid';
|
||||
} else if (columnDef.format === 'bigint') {
|
||||
dataType = 'bigint';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
column_name: columnName,
|
||||
data_type: dataType,
|
||||
is_nullable: !tableDefinition.required?.includes(columnName) ? 'YES' : 'NO',
|
||||
column_default: columnDef.default || null
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
for (const column of columns) {
|
||||
if (!column.data_type) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const isRequired = column.is_nullable === 'NO' && column.column_default === null;
|
||||
const description = `Type: ${column.data_type}${isRequired ? ' (required)' : ''}`;
|
||||
|
||||
switch (column.data_type.toLowerCase()) {
|
||||
case 'integer':
|
||||
case 'bigint':
|
||||
case 'smallint':
|
||||
case 'numeric':
|
||||
case 'decimal':
|
||||
case 'real':
|
||||
case 'double precision':
|
||||
properties[column.column_name] = Property.Number({
|
||||
displayName: column.column_name,
|
||||
description,
|
||||
required: false
|
||||
});
|
||||
break;
|
||||
|
||||
case 'boolean':
|
||||
properties[column.column_name] = Property.Checkbox({
|
||||
displayName: column.column_name,
|
||||
description,
|
||||
required: false
|
||||
});
|
||||
break;
|
||||
|
||||
case 'date':
|
||||
case 'timestamp':
|
||||
case 'timestamp with time zone':
|
||||
case 'timestamp without time zone':
|
||||
// Handle auto-timestamps (created_at, updated_at) differently
|
||||
if (column.column_name.includes('created_at') || column.column_name.includes('updated_at')) {
|
||||
properties[column.column_name] = Property.ShortText({
|
||||
displayName: `${column.column_name} (auto-generated)`,
|
||||
description: `${description} - Leave empty for auto-generation`,
|
||||
required: false
|
||||
});
|
||||
} else {
|
||||
properties[column.column_name] = Property.DateTime({
|
||||
displayName: column.column_name,
|
||||
description,
|
||||
required: false
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case 'json':
|
||||
case 'jsonb':
|
||||
case 'object':
|
||||
properties[column.column_name] = Property.Json({
|
||||
displayName: column.column_name,
|
||||
description,
|
||||
required: false
|
||||
});
|
||||
break;
|
||||
|
||||
case 'array':
|
||||
case '_text':
|
||||
case 'text[]':
|
||||
properties[column.column_name] = Property.Array({
|
||||
displayName: column.column_name,
|
||||
description: `${description} - Enter each item separately`,
|
||||
required: false
|
||||
});
|
||||
break;
|
||||
|
||||
case 'uuid':
|
||||
// UUID fields - offer auto-generation option
|
||||
if (column.column_name === 'id' || column.column_name.endsWith('_id')) {
|
||||
properties[column.column_name] = Property.ShortText({
|
||||
displayName: `${column.column_name} (auto-generated)`,
|
||||
description: `${description} - Leave empty for auto-generation`,
|
||||
required: false
|
||||
});
|
||||
} else {
|
||||
properties[column.column_name] = Property.ShortText({
|
||||
displayName: column.column_name,
|
||||
description,
|
||||
required: false
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case 'string':
|
||||
case 'text':
|
||||
case 'varchar':
|
||||
case 'character varying':
|
||||
case 'char':
|
||||
case 'character':
|
||||
default:
|
||||
if (column.column_name.toLowerCase().includes('email')) {
|
||||
properties[column.column_name] = Property.ShortText({
|
||||
displayName: column.column_name,
|
||||
description: `${description} - Enter email address`,
|
||||
required: false
|
||||
});
|
||||
} else if (column.column_name.toLowerCase().includes('id')) {
|
||||
properties[column.column_name] = Property.ShortText({
|
||||
displayName: `${column.column_name} (auto-generated)`,
|
||||
description: `${description} - Leave empty for auto-generation`,
|
||||
required: false
|
||||
});
|
||||
} else {
|
||||
properties[column.column_name] = Property.LongText({
|
||||
displayName: column.column_name,
|
||||
description,
|
||||
required: false
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return properties;
|
||||
} catch (error) {
|
||||
properties['error'] = Property.MarkDown({
|
||||
value: `Error loading columns for table "${table_name}". Please check your connection and permissions.`
|
||||
});
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
update_fields: Property.DynamicProperties({
|
||||
auth: supabaseAuth,
|
||||
displayName: 'Update Data',
|
||||
description: 'Select which columns to update (auto-generated fields excluded)',
|
||||
required: true,
|
||||
refreshers: ['table_name'],
|
||||
props: async (propsValue) => {
|
||||
const { auth, table_name } = propsValue;
|
||||
const properties: DynamicPropsValue = {};
|
||||
|
||||
if (!auth || !table_name) {
|
||||
return properties;
|
||||
}
|
||||
|
||||
try {
|
||||
const { url, apiKey } =auth.props
|
||||
const supabase = createClient(url, apiKey);
|
||||
|
||||
let columns: any[] = [];
|
||||
|
||||
try {
|
||||
const { data: rpcColumns, error } = await supabase.rpc('get_table_columns', {
|
||||
p_table_name: table_name as unknown as string
|
||||
});
|
||||
|
||||
if (!error && rpcColumns && rpcColumns.length > 0) {
|
||||
columns = rpcColumns;
|
||||
}
|
||||
} catch (rpcError) {
|
||||
// RPC function doesn't exist, continue to OpenAPI fallback
|
||||
}
|
||||
|
||||
if (columns.length === 0) {
|
||||
let openApiSpec: any;
|
||||
try {
|
||||
const response = await fetch(`${url}/rest/v1/`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'apikey': apiKey,
|
||||
'Authorization': `Bearer ${apiKey}`,
|
||||
'Accept': 'application/openapi+json'
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
properties['error'] = Property.MarkDown({
|
||||
value: `Error loading columns for table "${table_name}". Please check your connection and permissions.`
|
||||
});
|
||||
return properties;
|
||||
}
|
||||
openApiSpec = await response.json();
|
||||
} catch (fetchError) {
|
||||
properties['error'] = Property.MarkDown({
|
||||
value: `Network error loading columns for table "${table_name}". Please check your connection.`
|
||||
});
|
||||
return properties;
|
||||
}
|
||||
const definitions = openApiSpec.definitions || openApiSpec.components?.schemas || {};
|
||||
|
||||
const tableDefinition = definitions[table_name as unknown as string];
|
||||
if (!tableDefinition || !tableDefinition.properties) {
|
||||
properties['info'] = Property.MarkDown({
|
||||
value: `No columns found for table "${table_name}". Please check if the table exists.`
|
||||
});
|
||||
return properties;
|
||||
}
|
||||
|
||||
columns = Object.entries(tableDefinition.properties).map(([columnName, columnDef]: [string, any]) => {
|
||||
let dataType = 'text';
|
||||
if (columnDef.type) {
|
||||
dataType = columnDef.type;
|
||||
if (columnDef.type === 'array') {
|
||||
dataType = 'array';
|
||||
} else if (columnDef.format) {
|
||||
if (columnDef.format === 'date-time' || columnDef.format === 'timestamp') {
|
||||
dataType = 'timestamp';
|
||||
} else if (columnDef.format === 'date') {
|
||||
dataType = 'date';
|
||||
} else if (columnDef.format === 'uuid') {
|
||||
dataType = 'uuid';
|
||||
} else if (columnDef.format === 'bigint') {
|
||||
dataType = 'bigint';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
column_name: columnName,
|
||||
data_type: dataType,
|
||||
is_nullable: !tableDefinition.required?.includes(columnName) ? 'YES' : 'NO',
|
||||
column_default: columnDef.default || null
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
for (const column of columns) {
|
||||
if (!column.data_type) continue;
|
||||
|
||||
if (
|
||||
column.column_name === 'id' ||
|
||||
column.column_name.includes('created_at') ||
|
||||
column.column_name.includes('updated_at') ||
|
||||
(column.data_type === 'uuid' && column.column_name.endsWith('_id'))
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const description = `Type: ${column.data_type} - Update this field`;
|
||||
|
||||
switch (column.data_type.toLowerCase()) {
|
||||
case 'integer':
|
||||
case 'bigint':
|
||||
case 'smallint':
|
||||
case 'numeric':
|
||||
case 'decimal':
|
||||
case 'real':
|
||||
case 'double precision':
|
||||
properties[column.column_name] = Property.Number({
|
||||
displayName: column.column_name,
|
||||
description,
|
||||
required: false
|
||||
});
|
||||
break;
|
||||
|
||||
case 'boolean':
|
||||
properties[column.column_name] = Property.Checkbox({
|
||||
displayName: column.column_name,
|
||||
description,
|
||||
required: false
|
||||
});
|
||||
break;
|
||||
|
||||
case 'date':
|
||||
case 'timestamp':
|
||||
case 'timestamp with time zone':
|
||||
case 'timestamp without time zone':
|
||||
properties[column.column_name] = Property.DateTime({
|
||||
displayName: column.column_name,
|
||||
description,
|
||||
required: false
|
||||
});
|
||||
break;
|
||||
|
||||
case 'json':
|
||||
case 'jsonb':
|
||||
case 'object':
|
||||
properties[column.column_name] = Property.Json({
|
||||
displayName: column.column_name,
|
||||
description,
|
||||
required: false
|
||||
});
|
||||
break;
|
||||
|
||||
case 'array':
|
||||
case '_text':
|
||||
case 'text[]':
|
||||
properties[column.column_name] = Property.Array({
|
||||
displayName: column.column_name,
|
||||
description: `${description} - Enter each item separately`,
|
||||
required: false
|
||||
});
|
||||
break;
|
||||
|
||||
default:
|
||||
if (column.column_name.toLowerCase().includes('email')) {
|
||||
properties[column.column_name] = Property.ShortText({
|
||||
displayName: column.column_name,
|
||||
description: `${description} - Enter email address`,
|
||||
required: false
|
||||
});
|
||||
} else {
|
||||
properties[column.column_name] = Property.LongText({
|
||||
displayName: column.column_name,
|
||||
description,
|
||||
required: false
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return properties;
|
||||
} catch (error) {
|
||||
properties['error'] = Property.MarkDown({
|
||||
value: `Error loading columns for table "${table_name}". Please check your connection and permissions.`
|
||||
});
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
upsert_fields: Property.DynamicProperties({
|
||||
auth: supabaseAuth,
|
||||
displayName: 'Row Data',
|
||||
description: 'Enter data for the row (conflict detection handled separately)',
|
||||
required: true,
|
||||
refreshers: ['table_name', 'on_conflict'],
|
||||
props: async (propsValue) => {
|
||||
const { auth, table_name, on_conflict } = propsValue;
|
||||
const properties: DynamicPropsValue = {};
|
||||
|
||||
if (!auth || !table_name) {
|
||||
return properties;
|
||||
}
|
||||
|
||||
try {
|
||||
const { url, apiKey } =auth.props
|
||||
const supabase = createClient(url, apiKey);
|
||||
|
||||
let columns: any[] = [];
|
||||
|
||||
try {
|
||||
const { data: rpcColumns, error } = await supabase.rpc('get_table_columns', {
|
||||
p_table_name: table_name as unknown as string
|
||||
});
|
||||
if (!error && rpcColumns && rpcColumns.length > 0) {
|
||||
columns = rpcColumns;
|
||||
}
|
||||
} catch (rpcError) {
|
||||
console.log('RPC function not available for upsert columns');
|
||||
}
|
||||
|
||||
if (columns.length === 0) {
|
||||
const response = await fetch(`${url}/rest/v1/`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'apikey': apiKey,
|
||||
'Authorization': `Bearer ${apiKey}`,
|
||||
'Accept': 'application/openapi+json'
|
||||
}
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const openApiSpec = await response.json();
|
||||
const definitions = openApiSpec.definitions || openApiSpec.components?.schemas || {};
|
||||
const tableDefinition = definitions[table_name as unknown as string];
|
||||
|
||||
if (tableDefinition && tableDefinition.properties) {
|
||||
columns = Object.entries(tableDefinition.properties).map(([columnName, columnDef]: [string, any]) => ({
|
||||
column_name: columnName,
|
||||
data_type: columnDef.type || 'text',
|
||||
is_nullable: !tableDefinition.required?.includes(columnName) ? 'YES' : 'NO',
|
||||
column_default: columnDef.default || null
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const column of columns) {
|
||||
if (!column.data_type || column.column_name === on_conflict) continue;
|
||||
|
||||
const description = `Type: ${column.data_type}`;
|
||||
properties[column.column_name] = Property.LongText({
|
||||
displayName: column.column_name,
|
||||
description,
|
||||
required: false
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
properties['error'] = Property.MarkDown({
|
||||
value: `Error loading columns for table "${table_name}".`
|
||||
});
|
||||
}
|
||||
|
||||
if (on_conflict) {
|
||||
properties['_info'] = Property.MarkDown({
|
||||
value: `💡 **Note**: The "${on_conflict}" field is used for conflict detection and should not be included in the row data unless you want to update it.`
|
||||
});
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
})
|
||||
};
|
||||
@@ -0,0 +1,106 @@
|
||||
import { createTrigger, Property, TriggerStrategy } from '@activepieces/pieces-framework';
|
||||
import { supabaseAuth } from '../../index';
|
||||
import { supabaseCommon } from '../common/props';
|
||||
|
||||
export const newRow = createTrigger({
|
||||
name: 'new_row',
|
||||
displayName: 'New Row',
|
||||
description: 'Fires when a new row is created in a table',
|
||||
auth: supabaseAuth,
|
||||
type: TriggerStrategy.WEBHOOK,
|
||||
sampleData: {
|
||||
type: "INSERT",
|
||||
table: "customers",
|
||||
schema: "public",
|
||||
record: {
|
||||
id: 1,
|
||||
name: "John Doe",
|
||||
email: "john@example.com",
|
||||
created_at: "2023-01-01T00:00:00Z"
|
||||
},
|
||||
old_record: null
|
||||
},
|
||||
props: {
|
||||
instructions: Property.MarkDown({
|
||||
value: `## Setup Instructions
|
||||
|
||||
1. **Go to your Supabase Dashboard** → Database → Webhooks
|
||||
2. **Click "Create a new hook"**
|
||||
3. **Configure the webhook:**
|
||||
- **Name**: Give it a descriptive name (e.g., "Activepieces New Row")
|
||||
- **Table**: Select the table you want to monitor
|
||||
- **Events**: Check "Insert"
|
||||
- **Type**: HTTP Request
|
||||
- **Method**: POST
|
||||
- **URL**: Copy and paste the webhook URL below
|
||||
4. **Click "Create webhook"**
|
||||
|
||||
**Webhook URL:** \`{{webhookUrl}}\`
|
||||
|
||||
## Important Notes
|
||||
- The webhook will send a JSON payload with the new row data
|
||||
- Make sure your table has the necessary permissions
|
||||
- You can test the webhook by inserting a new row into your table
|
||||
|
||||
For more details, see [Supabase Database Webhooks documentation](https://supabase.com/docs/guides/database/webhooks).`
|
||||
}),
|
||||
table_name: supabaseCommon.table_name,
|
||||
schema: Property.ShortText({
|
||||
displayName: 'Schema',
|
||||
description: 'Database schema (default: public)',
|
||||
required: false,
|
||||
defaultValue: 'public'
|
||||
})
|
||||
},
|
||||
async onEnable(context) {
|
||||
const { table_name, schema } = context.propsValue;
|
||||
|
||||
if (!context.webhookUrl) {
|
||||
throw new Error('Webhook URL is required for Supabase triggers');
|
||||
}
|
||||
|
||||
const webhookConfig = {
|
||||
table: table_name,
|
||||
schema: schema || 'public',
|
||||
event: 'INSERT',
|
||||
webhook_url: context.webhookUrl,
|
||||
setup_instructions: 'Manual setup required in Supabase Dashboard'
|
||||
};
|
||||
|
||||
await context.store.put('webhook_config', webhookConfig);
|
||||
},
|
||||
|
||||
async onDisable(context) {
|
||||
try {
|
||||
await context.store.delete('webhook_config');
|
||||
} catch (error) {
|
||||
console.log('Error cleaning up webhook config:', error);
|
||||
}
|
||||
},
|
||||
|
||||
async run(context) {
|
||||
const payload = context.payload.body as any;
|
||||
|
||||
if (!payload || typeof payload !== 'object') {
|
||||
throw new Error('Invalid webhook payload received from Supabase');
|
||||
}
|
||||
|
||||
if (!payload.type || !payload.table) {
|
||||
throw new Error('Payload missing required Supabase webhook fields (type, table)');
|
||||
}
|
||||
|
||||
if (payload.type !== 'INSERT') {
|
||||
throw new Error(`Expected INSERT event, received ${payload.type}`);
|
||||
}
|
||||
|
||||
return [{
|
||||
type: payload.type,
|
||||
table: payload.table,
|
||||
schema: payload.schema || 'public',
|
||||
record: payload.record || null,
|
||||
old_record: payload.old_record || null,
|
||||
timestamp: new Date().toISOString(),
|
||||
raw_payload: payload
|
||||
}];
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"extends": "../../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"outDir": "../../../../dist/out-tsc",
|
||||
"declaration": true,
|
||||
"types": ["node"]
|
||||
},
|
||||
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"],
|
||||
"include": ["src/**/*.ts"]
|
||||
}
|
||||
Reference in New Issue
Block a user