@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
|
-
|
|
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
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
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