@fachkraftfreund/n8n-nodes-supabase 1.3.10 → 1.3.11
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.
|
@@ -594,6 +594,36 @@ class Supabase {
|
|
|
594
594
|
default: 'left',
|
|
595
595
|
description: 'Left returns all rows even without a match; Inner only returns rows with a match',
|
|
596
596
|
},
|
|
597
|
+
{
|
|
598
|
+
displayName: 'Order By',
|
|
599
|
+
name: 'orderBy',
|
|
600
|
+
type: 'string',
|
|
601
|
+
default: '',
|
|
602
|
+
placeholder: 'created_at',
|
|
603
|
+
description: 'Column in the joined table to order by (leave empty for no ordering)',
|
|
604
|
+
},
|
|
605
|
+
{
|
|
606
|
+
displayName: 'Order Ascending',
|
|
607
|
+
name: 'orderAscending',
|
|
608
|
+
type: 'boolean',
|
|
609
|
+
default: false,
|
|
610
|
+
description: 'Whether to sort in ascending order (default descending, useful for "latest first")',
|
|
611
|
+
displayOptions: {
|
|
612
|
+
hide: {
|
|
613
|
+
orderBy: [''],
|
|
614
|
+
},
|
|
615
|
+
},
|
|
616
|
+
},
|
|
617
|
+
{
|
|
618
|
+
displayName: 'Limit',
|
|
619
|
+
name: 'limit',
|
|
620
|
+
type: 'number',
|
|
621
|
+
typeOptions: {
|
|
622
|
+
minValue: 0,
|
|
623
|
+
},
|
|
624
|
+
default: 0,
|
|
625
|
+
description: 'Max rows to return from the joined table per parent row (0 = no limit). Set to 1 to get only the latest match.',
|
|
626
|
+
},
|
|
597
627
|
],
|
|
598
628
|
},
|
|
599
629
|
],
|
|
@@ -54,7 +54,8 @@ function streamWrite(stream, data) {
|
|
|
54
54
|
}
|
|
55
55
|
});
|
|
56
56
|
}
|
|
57
|
-
function buildSelectQuery(supabase, table, selectFields, filters, sort) {
|
|
57
|
+
function buildSelectQuery(supabase, table, selectFields, filters, sort, joins) {
|
|
58
|
+
var _a;
|
|
58
59
|
let query = supabase.from(table).select(selectFields);
|
|
59
60
|
for (const filter of filters) {
|
|
60
61
|
const operator = (0, supabaseClient_2.convertFilterOperator)(filter.operator);
|
|
@@ -63,6 +64,21 @@ function buildSelectQuery(supabase, table, selectFields, filters, sort) {
|
|
|
63
64
|
for (const s of sort) {
|
|
64
65
|
query = query.order(s.column, { ascending: s.ascending });
|
|
65
66
|
}
|
|
67
|
+
if (joins) {
|
|
68
|
+
for (const j of joins) {
|
|
69
|
+
if (!j.table)
|
|
70
|
+
continue;
|
|
71
|
+
if (j.orderBy) {
|
|
72
|
+
query = query.order(j.orderBy, {
|
|
73
|
+
ascending: (_a = j.orderAscending) !== null && _a !== void 0 ? _a : false,
|
|
74
|
+
referencedTable: j.table,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
if (j.limit && j.limit > 0) {
|
|
78
|
+
query = query.limit(j.limit, { referencedTable: j.table });
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
66
82
|
return query;
|
|
67
83
|
}
|
|
68
84
|
function parseFilters(context, itemIndex) {
|
|
@@ -92,7 +108,7 @@ function parseFilters(context, itemIndex) {
|
|
|
92
108
|
}
|
|
93
109
|
}
|
|
94
110
|
const BATCH_SIZE = 1000;
|
|
95
|
-
async function* fetchBatches(supabase, table, selectFields, filters, sort, hostUrl, returnAll, limit) {
|
|
111
|
+
async function* fetchBatches(supabase, table, selectFields, filters, sort, hostUrl, returnAll, limit, joins) {
|
|
96
112
|
const overhead = (0, supabaseClient_2.estimateUrlOverhead)(hostUrl, table, selectFields, filters, sort);
|
|
97
113
|
const maxInChars = Math.max(500, supabaseClient_2.MAX_SAFE_URL_LENGTH - overhead);
|
|
98
114
|
const maxItems = (0, supabaseClient_2.computeMaxIdsPerChunk)(selectFields);
|
|
@@ -112,7 +128,7 @@ async function* fetchBatches(supabase, table, selectFields, filters, sort, hostU
|
|
|
112
128
|
if (hasIdColumn) {
|
|
113
129
|
let lastId = null;
|
|
114
130
|
while (hasMore) {
|
|
115
|
-
let query = buildSelectQuery(supabase, table, selectFields, chunkFilters, []);
|
|
131
|
+
let query = buildSelectQuery(supabase, table, selectFields, chunkFilters, [], joins);
|
|
116
132
|
if (lastId !== null)
|
|
117
133
|
query = query.gt('id', lastId);
|
|
118
134
|
query = query.order('id', { ascending: true }).limit(BATCH_SIZE);
|
|
@@ -138,7 +154,7 @@ async function* fetchBatches(supabase, table, selectFields, filters, sort, hostU
|
|
|
138
154
|
else {
|
|
139
155
|
let offset = 0;
|
|
140
156
|
while (hasMore) {
|
|
141
|
-
const query = buildSelectQuery(supabase, table, selectFields, chunkFilters, sort);
|
|
157
|
+
const query = buildSelectQuery(supabase, table, selectFields, chunkFilters, sort, joins);
|
|
142
158
|
const { data, error } = await query.range(offset, offset + BATCH_SIZE - 1);
|
|
143
159
|
if (error)
|
|
144
160
|
throw new Error((0, supabaseClient_2.formatSupabaseError)(error));
|
|
@@ -163,7 +179,7 @@ async function* fetchBatches(supabase, table, selectFields, filters, sort, hostU
|
|
|
163
179
|
const remaining = maxRows - totalYielded;
|
|
164
180
|
if (remaining <= 0)
|
|
165
181
|
break;
|
|
166
|
-
const query = buildSelectQuery(supabase, table, selectFields, chunkFilters, sort);
|
|
182
|
+
const query = buildSelectQuery(supabase, table, selectFields, chunkFilters, sort, joins);
|
|
167
183
|
const { data, error } = await query.limit(remaining);
|
|
168
184
|
if (error)
|
|
169
185
|
throw new Error((0, supabaseClient_2.formatSupabaseError)(error));
|
|
@@ -256,6 +272,36 @@ class SupabaseCsvExport {
|
|
|
256
272
|
],
|
|
257
273
|
default: 'left',
|
|
258
274
|
},
|
|
275
|
+
{
|
|
276
|
+
displayName: 'Order By',
|
|
277
|
+
name: 'orderBy',
|
|
278
|
+
type: 'string',
|
|
279
|
+
default: '',
|
|
280
|
+
placeholder: 'created_at',
|
|
281
|
+
description: 'Column in the joined table to order by (leave empty for no ordering)',
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
displayName: 'Order Ascending',
|
|
285
|
+
name: 'orderAscending',
|
|
286
|
+
type: 'boolean',
|
|
287
|
+
default: false,
|
|
288
|
+
description: 'Whether to sort in ascending order (default descending, useful for "latest first")',
|
|
289
|
+
displayOptions: {
|
|
290
|
+
hide: {
|
|
291
|
+
orderBy: [''],
|
|
292
|
+
},
|
|
293
|
+
},
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
displayName: 'Limit',
|
|
297
|
+
name: 'limit',
|
|
298
|
+
type: 'number',
|
|
299
|
+
typeOptions: {
|
|
300
|
+
minValue: 0,
|
|
301
|
+
},
|
|
302
|
+
default: 0,
|
|
303
|
+
description: 'Max rows from the joined table per parent row (0 = no limit, 1 = latest only)',
|
|
304
|
+
},
|
|
259
305
|
],
|
|
260
306
|
},
|
|
261
307
|
],
|
|
@@ -619,7 +665,7 @@ class SupabaseCsvExport {
|
|
|
619
665
|
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Transform code syntax error: ${msg}`);
|
|
620
666
|
}
|
|
621
667
|
}
|
|
622
|
-
for await (const batch of fetchBatches(supabase, table, selectWithJoins, filters, sort, credentials.host, returnAll, limit)) {
|
|
668
|
+
for await (const batch of fetchBatches(supabase, table, selectWithJoins, filters, sort, credentials.host, returnAll, limit, joins)) {
|
|
623
669
|
let rows = batch;
|
|
624
670
|
if (transformFn) {
|
|
625
671
|
try {
|
|
@@ -315,7 +315,8 @@ function getFilters(context, itemIndex) {
|
|
|
315
315
|
throw new Error('Invalid advanced filters JSON');
|
|
316
316
|
}
|
|
317
317
|
}
|
|
318
|
-
function buildReadQuery(supabase, table, returnFields, filters, sort, options) {
|
|
318
|
+
function buildReadQuery(supabase, table, returnFields, filters, sort, options, joins) {
|
|
319
|
+
var _a;
|
|
319
320
|
const selectFields = returnFields && returnFields !== '*' ? returnFields : '*';
|
|
320
321
|
let query = supabase.from(table).select(selectFields, options);
|
|
321
322
|
for (const filter of filters) {
|
|
@@ -325,6 +326,21 @@ function buildReadQuery(supabase, table, returnFields, filters, sort, options) {
|
|
|
325
326
|
for (const sortField of sort) {
|
|
326
327
|
query = query.order(sortField.column, { ascending: sortField.ascending });
|
|
327
328
|
}
|
|
329
|
+
if (joins) {
|
|
330
|
+
for (const j of joins) {
|
|
331
|
+
if (!j.table)
|
|
332
|
+
continue;
|
|
333
|
+
if (j.orderBy) {
|
|
334
|
+
query = query.order(j.orderBy, {
|
|
335
|
+
ascending: (_a = j.orderAscending) !== null && _a !== void 0 ? _a : false,
|
|
336
|
+
referencedTable: j.table,
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
if (j.limit && j.limit > 0) {
|
|
340
|
+
query = query.limit(j.limit, { referencedTable: j.table });
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
328
344
|
return query;
|
|
329
345
|
}
|
|
330
346
|
async function handleRead(supabase, itemIndex, hostUrl) {
|
|
@@ -370,7 +386,7 @@ async function handleRead(supabase, itemIndex, hostUrl) {
|
|
|
370
386
|
if (hasIdColumn) {
|
|
371
387
|
let lastId = null;
|
|
372
388
|
while (hasMore) {
|
|
373
|
-
let query = buildReadQuery(supabase, table, selectWithJoins, chunkFilters, []);
|
|
389
|
+
let query = buildReadQuery(supabase, table, selectWithJoins, chunkFilters, [], undefined, joins);
|
|
374
390
|
if (lastId !== null) {
|
|
375
391
|
query = query.gt('id', lastId);
|
|
376
392
|
}
|
|
@@ -398,7 +414,7 @@ async function handleRead(supabase, itemIndex, hostUrl) {
|
|
|
398
414
|
else {
|
|
399
415
|
let batchOffset = 0;
|
|
400
416
|
while (hasMore) {
|
|
401
|
-
const query = buildReadQuery(supabase, table, selectWithJoins, chunkFilters, sort);
|
|
417
|
+
const query = buildReadQuery(supabase, table, selectWithJoins, chunkFilters, sort, undefined, joins);
|
|
402
418
|
const { data, error } = await query.range(batchOffset, batchOffset + batchSize - 1);
|
|
403
419
|
if (error) {
|
|
404
420
|
console.log(`[Supabase READ] chunk ${ci + 1} batch ${batchCount + 1} FAILED after ${Date.now() - chunkStart}ms: ${(0, supabaseClient_1.formatSupabaseError)(error)}`);
|
|
@@ -447,7 +463,7 @@ async function handleRead(supabase, itemIndex, hostUrl) {
|
|
|
447
463
|
const userOffset = this.getNodeParameter('offset', itemIndex, 0);
|
|
448
464
|
const isMultiChunk = filterChunks.length > 1;
|
|
449
465
|
for (const chunkFilters of filterChunks) {
|
|
450
|
-
let query = buildReadQuery(supabase, table, selectWithJoins, chunkFilters, sort);
|
|
466
|
+
let query = buildReadQuery(supabase, table, selectWithJoins, chunkFilters, sort, undefined, joins);
|
|
451
467
|
if (isMultiChunk) {
|
|
452
468
|
query = query.limit(userOffset + limit);
|
|
453
469
|
}
|
package/package.json
CHANGED