@fachkraftfreund/n8n-nodes-supabase 1.2.20 → 1.2.22
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.
|
@@ -609,6 +609,19 @@ class Supabase {
|
|
|
609
609
|
},
|
|
610
610
|
},
|
|
611
611
|
},
|
|
612
|
+
{
|
|
613
|
+
displayName: 'Single Result Item',
|
|
614
|
+
name: 'singleItem',
|
|
615
|
+
type: 'boolean',
|
|
616
|
+
default: false,
|
|
617
|
+
description: 'Whether to return all rows wrapped in a single n8n item (as a "data" array) instead of one item per row',
|
|
618
|
+
displayOptions: {
|
|
619
|
+
show: {
|
|
620
|
+
resource: ['database'],
|
|
621
|
+
operation: ['read'],
|
|
622
|
+
},
|
|
623
|
+
},
|
|
624
|
+
},
|
|
612
625
|
{
|
|
613
626
|
displayName: 'Bucket',
|
|
614
627
|
name: 'bucket',
|
|
@@ -211,44 +211,71 @@ async function handleRead(supabase, itemIndex, hostUrl) {
|
|
|
211
211
|
const returnData = [];
|
|
212
212
|
if (returnAll) {
|
|
213
213
|
const batchSize = 1000;
|
|
214
|
+
const selectFields = returnFields && returnFields !== '*' ? returnFields : '*';
|
|
215
|
+
const hasIdColumn = selectFields === '*' || selectFields.split(',').some(f => f.trim() === 'id');
|
|
214
216
|
for (let ci = 0; ci < filterChunks.length; ci++) {
|
|
215
217
|
const chunkFilters = filterChunks[ci];
|
|
216
218
|
const inFilter = chunkFilters.find(f => f.operator === 'in');
|
|
217
219
|
const chunkIds = inFilter && Array.isArray(inFilter.value) ? inFilter.value.length : '?';
|
|
218
|
-
console.log(`[Supabase READ] chunk ${ci + 1}/${filterChunks.length} (${chunkIds} IDs) - starting...`);
|
|
220
|
+
console.log(`[Supabase READ] chunk ${ci + 1}/${filterChunks.length} (${chunkIds} IDs) keyset=${hasIdColumn} - starting...`);
|
|
219
221
|
const chunkStart = Date.now();
|
|
220
|
-
let lastId = null;
|
|
221
|
-
let hasMore = true;
|
|
222
222
|
let batchCount = 0;
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
223
|
+
let hasMore = true;
|
|
224
|
+
if (hasIdColumn) {
|
|
225
|
+
let lastId = null;
|
|
226
|
+
while (hasMore) {
|
|
227
|
+
let query = buildReadQuery(supabase, table, returnFields, chunkFilters, []);
|
|
228
|
+
if (lastId !== null) {
|
|
229
|
+
query = query.gt('id', lastId);
|
|
230
|
+
}
|
|
231
|
+
query = query.order('id', { ascending: true }).limit(batchSize);
|
|
232
|
+
const { data, error } = await query;
|
|
233
|
+
if (error) {
|
|
234
|
+
console.log(`[Supabase READ] chunk ${ci + 1} batch ${batchCount + 1} FAILED after ${Date.now() - chunkStart}ms: ${(0, supabaseClient_1.formatSupabaseError)(error)}`);
|
|
235
|
+
throw new Error((0, supabaseClient_1.formatSupabaseError)(error));
|
|
236
|
+
}
|
|
237
|
+
if (Array.isArray(data) && data.length > 0) {
|
|
238
|
+
for (const row of data)
|
|
239
|
+
returnData.push({ json: row });
|
|
240
|
+
lastId = data[data.length - 1].id;
|
|
241
|
+
hasMore = data.length === batchSize;
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
hasMore = false;
|
|
245
|
+
}
|
|
246
|
+
batchCount++;
|
|
247
|
+
if (batchCount % 50 === 0) {
|
|
248
|
+
console.log(`[Supabase READ] chunk ${ci + 1} progress: ${batchCount} batches, ${returnData.length} rows, ${Date.now() - chunkStart}ms`);
|
|
237
249
|
}
|
|
238
|
-
lastId = data[data.length - 1].id;
|
|
239
|
-
hasMore = data.length === batchSize;
|
|
240
|
-
}
|
|
241
|
-
else {
|
|
242
|
-
hasMore = false;
|
|
243
250
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
let batchOffset = 0;
|
|
254
|
+
while (hasMore) {
|
|
255
|
+
const query = buildReadQuery(supabase, table, returnFields, chunkFilters, sort);
|
|
256
|
+
const { data, error } = await query.range(batchOffset, batchOffset + batchSize - 1);
|
|
257
|
+
if (error) {
|
|
258
|
+
console.log(`[Supabase READ] chunk ${ci + 1} batch ${batchCount + 1} FAILED after ${Date.now() - chunkStart}ms: ${(0, supabaseClient_1.formatSupabaseError)(error)}`);
|
|
259
|
+
throw new Error((0, supabaseClient_1.formatSupabaseError)(error));
|
|
260
|
+
}
|
|
261
|
+
if (Array.isArray(data) && data.length > 0) {
|
|
262
|
+
for (const row of data)
|
|
263
|
+
returnData.push({ json: row });
|
|
264
|
+
hasMore = data.length === batchSize;
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
hasMore = false;
|
|
268
|
+
}
|
|
269
|
+
batchOffset += batchSize;
|
|
270
|
+
batchCount++;
|
|
271
|
+
if (batchCount % 50 === 0) {
|
|
272
|
+
console.log(`[Supabase READ] chunk ${ci + 1} progress: ${batchCount} batches, ${returnData.length} rows, ${Date.now() - chunkStart}ms`);
|
|
273
|
+
}
|
|
247
274
|
}
|
|
248
275
|
}
|
|
249
276
|
console.log(`[Supabase READ] chunk ${ci + 1}/${filterChunks.length} done in ${Date.now() - chunkStart}ms — ${batchCount} batches, ${returnData.length} total rows`);
|
|
250
277
|
}
|
|
251
|
-
if (sort.length > 0) {
|
|
278
|
+
if (hasIdColumn && sort.length > 0) {
|
|
252
279
|
returnData.sort((a, b) => {
|
|
253
280
|
var _a, _b;
|
|
254
281
|
for (const s of sort) {
|
|
@@ -314,6 +341,11 @@ async function handleRead(supabase, itemIndex, hostUrl) {
|
|
|
314
341
|
},
|
|
315
342
|
});
|
|
316
343
|
}
|
|
344
|
+
const singleItem = this.getNodeParameter('singleItem', itemIndex, false);
|
|
345
|
+
if (singleItem && returnData.length > 0) {
|
|
346
|
+
const allRows = returnData.map(item => item.json);
|
|
347
|
+
return [{ json: { data: allRows, count: allRows.length } }];
|
|
348
|
+
}
|
|
317
349
|
return returnData;
|
|
318
350
|
}
|
|
319
351
|
async function handleDelete(supabase, itemIndex, hostUrl) {
|
package/package.json
CHANGED