@fachkraftfreund/n8n-nodes-supabase 1.3.5 → 1.3.6
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',
|
|
@@ -204,14 +204,17 @@ async function handleBulkUpsert(supabase, itemCount) {
|
|
|
204
204
|
const table = this.getNodeParameter('table', 0);
|
|
205
205
|
const onConflict = this.getNodeParameter('onConflict', 0, '');
|
|
206
206
|
(0, supabaseClient_1.validateTableName)(table);
|
|
207
|
+
const deduplicate = this.getNodeParameter('deduplicateByConflict', 0, false);
|
|
207
208
|
let rows = collectRowData(this, itemCount);
|
|
208
209
|
const options = {};
|
|
209
210
|
if (onConflict) {
|
|
210
211
|
options.onConflict = onConflict;
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
212
|
+
if (deduplicate) {
|
|
213
|
+
const before = rows.length;
|
|
214
|
+
rows = deduplicateByConflictKeys(rows, onConflict);
|
|
215
|
+
if (rows.length < before) {
|
|
216
|
+
console.log(`[Supabase UPSERT ${table}] deduplicated input: ${before} → ${rows.length} rows by conflict key "${onConflict}"`);
|
|
217
|
+
}
|
|
215
218
|
}
|
|
216
219
|
}
|
|
217
220
|
const returnData = [];
|
|
@@ -243,6 +246,7 @@ async function handleBulkUpdate(supabase, itemCount) {
|
|
|
243
246
|
if (!matchColumn) {
|
|
244
247
|
throw new Error('Match Column is required for update operations');
|
|
245
248
|
}
|
|
249
|
+
const deduplicate = this.getNodeParameter('deduplicateByConflict', 0, false);
|
|
246
250
|
let rows = collectRowData(this, itemCount);
|
|
247
251
|
for (let i = 0; i < rows.length; i++) {
|
|
248
252
|
const row = rows[i];
|
|
@@ -250,10 +254,12 @@ async function handleBulkUpdate(supabase, itemCount) {
|
|
|
250
254
|
throw new Error(`Item ${i} is missing the match column "${matchColumn}"`);
|
|
251
255
|
}
|
|
252
256
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
+
if (deduplicate) {
|
|
258
|
+
const before = rows.length;
|
|
259
|
+
rows = deduplicateByConflictKeys(rows, matchColumn);
|
|
260
|
+
if (rows.length < before) {
|
|
261
|
+
console.log(`[Supabase UPDATE ${table}] deduplicated input: ${before} → ${rows.length} rows by match column "${matchColumn}"`);
|
|
262
|
+
}
|
|
257
263
|
}
|
|
258
264
|
const returnData = [];
|
|
259
265
|
for (let offset = 0; offset < rows.length; offset += BULK_BATCH_SIZE) {
|
package/package.json
CHANGED