@fachkraftfreund/n8n-nodes-supabase 1.3.5 → 1.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -341,6 +341,19 @@ class Supabase {
341
341
  },
342
342
  },
343
343
  },
344
+ {
345
+ displayName: 'Remove Duplicate Rows',
346
+ name: 'deduplicateByConflict',
347
+ type: 'boolean',
348
+ default: false,
349
+ description: 'When enabled, removes duplicate rows by the conflict/match column(s) before sending to Supabase. Keeps the last occurrence. Prevents the "ON CONFLICT DO UPDATE command cannot affect row a second time" error.',
350
+ displayOptions: {
351
+ show: {
352
+ resource: ['database'],
353
+ operation: ['upsert', 'update'],
354
+ },
355
+ },
356
+ },
344
357
  {
345
358
  displayName: 'Match Column',
346
359
  name: 'matchColumn',
@@ -203,16 +203,16 @@ async function handleBulkCreate(supabase, itemCount) {
203
203
  async function handleBulkUpsert(supabase, itemCount) {
204
204
  const table = this.getNodeParameter('table', 0);
205
205
  const onConflict = this.getNodeParameter('onConflict', 0, '');
206
+ const deduplicate = this.getNodeParameter('deduplicateByConflict', 0, false);
206
207
  (0, supabaseClient_1.validateTableName)(table);
207
208
  let rows = collectRowData(this, itemCount);
208
209
  const options = {};
209
- if (onConflict) {
210
+ if (onConflict)
210
211
  options.onConflict = onConflict;
212
+ if (deduplicate && onConflict) {
211
213
  const before = rows.length;
212
214
  rows = deduplicateByConflictKeys(rows, onConflict);
213
- if (rows.length < before) {
214
- console.log(`[Supabase UPSERT ${table}] deduplicated input: ${before} → ${rows.length} rows by conflict key "${onConflict}"`);
215
- }
215
+ console.log(`[Supabase UPSERT ${table}] dedup by "${onConflict}": ${before} → ${rows.length} rows`);
216
216
  }
217
217
  const returnData = [];
218
218
  for (let offset = 0; offset < rows.length; offset += BULK_BATCH_SIZE) {
@@ -243,6 +243,7 @@ async function handleBulkUpdate(supabase, itemCount) {
243
243
  if (!matchColumn) {
244
244
  throw new Error('Match Column is required for update operations');
245
245
  }
246
+ const deduplicate = this.getNodeParameter('deduplicateByConflict', 0, false);
246
247
  let rows = collectRowData(this, itemCount);
247
248
  for (let i = 0; i < rows.length; i++) {
248
249
  const row = rows[i];
@@ -250,10 +251,12 @@ async function handleBulkUpdate(supabase, itemCount) {
250
251
  throw new Error(`Item ${i} is missing the match column "${matchColumn}"`);
251
252
  }
252
253
  }
253
- const before = rows.length;
254
- rows = deduplicateByConflictKeys(rows, matchColumn);
255
- if (rows.length < before) {
256
- console.log(`[Supabase UPDATE ${table}] deduplicated input: ${before} → ${rows.length} rows by match column "${matchColumn}"`);
254
+ if (deduplicate) {
255
+ const before = rows.length;
256
+ rows = deduplicateByConflictKeys(rows, matchColumn);
257
+ if (rows.length < before) {
258
+ console.log(`[Supabase UPDATE ${table}] deduplicated input: ${before} → ${rows.length} rows by match column "${matchColumn}"`);
259
+ }
257
260
  }
258
261
  const returnData = [];
259
262
  for (let offset = 0; offset < rows.length; offset += BULK_BATCH_SIZE) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fachkraftfreund/n8n-nodes-supabase",
3
- "version": "1.3.5",
3
+ "version": "1.3.7",
4
4
  "description": "Comprehensive n8n community node for Supabase with database and storage operations",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",