@fachkraftfreund/n8n-nodes-supabase 1.2.0
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.
- package/LICENSE +21 -0
- package/README.md +428 -0
- package/dist/credentials/SupabaseExtendedApi.credentials.d.ts +9 -0
- package/dist/credentials/SupabaseExtendedApi.credentials.js +71 -0
- package/dist/nodes/Supabase/Supabase.node.d.ts +12 -0
- package/dist/nodes/Supabase/Supabase.node.js +750 -0
- package/dist/nodes/Supabase/icons/supabase.svg +15 -0
- package/dist/nodes/Supabase/operations/database/index.d.ts +4 -0
- package/dist/nodes/Supabase/operations/database/index.js +388 -0
- package/dist/nodes/Supabase/operations/storage/index.d.ts +4 -0
- package/dist/nodes/Supabase/operations/storage/index.js +474 -0
- package/dist/nodes/Supabase/types/index.d.ts +107 -0
- package/dist/nodes/Supabase/types/index.js +2 -0
- package/dist/nodes/Supabase/utils/supabaseClient.d.ts +13 -0
- package/dist/nodes/Supabase/utils/supabaseClient.js +138 -0
- package/package.json +92 -0
|
@@ -0,0 +1,474 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.executeStorageOperation = void 0;
|
|
27
|
+
const supabaseClient_1 = require("../../utils/supabaseClient");
|
|
28
|
+
const path = __importStar(require("path"));
|
|
29
|
+
const mime_types_1 = require("mime-types");
|
|
30
|
+
async function executeStorageOperation(supabase, operation, itemIndex) {
|
|
31
|
+
const returnData = [];
|
|
32
|
+
try {
|
|
33
|
+
switch (operation) {
|
|
34
|
+
case 'uploadFile':
|
|
35
|
+
returnData.push(...await handleUploadFile.call(this, supabase, itemIndex));
|
|
36
|
+
break;
|
|
37
|
+
case 'downloadFile':
|
|
38
|
+
returnData.push(...await handleDownloadFile.call(this, supabase, itemIndex));
|
|
39
|
+
break;
|
|
40
|
+
case 'listFiles':
|
|
41
|
+
returnData.push(...await handleListFiles.call(this, supabase, itemIndex));
|
|
42
|
+
break;
|
|
43
|
+
case 'deleteFile':
|
|
44
|
+
returnData.push(...await handleDeleteFile.call(this, supabase, itemIndex));
|
|
45
|
+
break;
|
|
46
|
+
case 'moveFile':
|
|
47
|
+
returnData.push(...await handleMoveFile.call(this, supabase, itemIndex));
|
|
48
|
+
break;
|
|
49
|
+
case 'copyFile':
|
|
50
|
+
returnData.push(...await handleCopyFile.call(this, supabase, itemIndex));
|
|
51
|
+
break;
|
|
52
|
+
case 'createBucket':
|
|
53
|
+
returnData.push(...await handleCreateBucket.call(this, supabase, itemIndex));
|
|
54
|
+
break;
|
|
55
|
+
case 'deleteBucket':
|
|
56
|
+
returnData.push(...await handleDeleteBucket.call(this, supabase, itemIndex));
|
|
57
|
+
break;
|
|
58
|
+
case 'listBuckets':
|
|
59
|
+
returnData.push(...await handleListBuckets.call(this, supabase, itemIndex));
|
|
60
|
+
break;
|
|
61
|
+
case 'getBucketDetails':
|
|
62
|
+
returnData.push(...await handleGetBucketDetails.call(this, supabase, itemIndex));
|
|
63
|
+
break;
|
|
64
|
+
case 'getFileInfo':
|
|
65
|
+
returnData.push(...await handleGetFileInfo.call(this, supabase, itemIndex));
|
|
66
|
+
break;
|
|
67
|
+
case 'generateSignedUrl':
|
|
68
|
+
returnData.push(...await handleGenerateSignedUrl.call(this, supabase, itemIndex));
|
|
69
|
+
break;
|
|
70
|
+
default:
|
|
71
|
+
throw new Error(`Unknown storage operation: ${operation}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
throw new Error(`Storage operation failed: ${(0, supabaseClient_1.formatSupabaseError)(error)}`);
|
|
76
|
+
}
|
|
77
|
+
return returnData;
|
|
78
|
+
}
|
|
79
|
+
exports.executeStorageOperation = executeStorageOperation;
|
|
80
|
+
async function handleUploadFile(supabase, itemIndex) {
|
|
81
|
+
const bucket = this.getNodeParameter('bucket', itemIndex);
|
|
82
|
+
const fileName = this.getNodeParameter('fileName', itemIndex);
|
|
83
|
+
const inputType = this.getNodeParameter('inputType', itemIndex, 'binary');
|
|
84
|
+
if (!bucket || !fileName) {
|
|
85
|
+
throw new Error('Bucket name and file name are required');
|
|
86
|
+
}
|
|
87
|
+
let fileData;
|
|
88
|
+
let contentType;
|
|
89
|
+
if (inputType === 'binary') {
|
|
90
|
+
const binaryPropertyName = this.getNodeParameter('binaryPropertyName', itemIndex, 'data');
|
|
91
|
+
const binaryData = this.helpers.assertBinaryData(itemIndex, binaryPropertyName);
|
|
92
|
+
fileData = await this.helpers.getBinaryDataBuffer(itemIndex, binaryPropertyName);
|
|
93
|
+
contentType = binaryData.mimeType;
|
|
94
|
+
}
|
|
95
|
+
else if (inputType === 'url') {
|
|
96
|
+
const fileUrl = this.getNodeParameter('fileUrl', itemIndex);
|
|
97
|
+
const response = await this.helpers.httpRequest({
|
|
98
|
+
method: 'GET',
|
|
99
|
+
url: fileUrl,
|
|
100
|
+
encoding: 'arraybuffer',
|
|
101
|
+
});
|
|
102
|
+
fileData = response.body;
|
|
103
|
+
contentType = response.headers['content-type'] || (0, mime_types_1.lookup)(fileName) || 'application/octet-stream';
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
const textContent = this.getNodeParameter('textContent', itemIndex);
|
|
107
|
+
fileData = Buffer.from(textContent, 'utf-8');
|
|
108
|
+
contentType = 'text/plain';
|
|
109
|
+
}
|
|
110
|
+
const options = {};
|
|
111
|
+
const cacheControl = this.getNodeParameter('cacheControl', itemIndex, '');
|
|
112
|
+
const upsert = this.getNodeParameter('upsert', itemIndex, false);
|
|
113
|
+
const customContentType = this.getNodeParameter('contentType', itemIndex, '');
|
|
114
|
+
if (cacheControl)
|
|
115
|
+
options.cacheControl = cacheControl;
|
|
116
|
+
if (upsert)
|
|
117
|
+
options.upsert = upsert;
|
|
118
|
+
if (customContentType)
|
|
119
|
+
options.contentType = customContentType;
|
|
120
|
+
else if (contentType)
|
|
121
|
+
options.contentType = contentType;
|
|
122
|
+
const metadata = this.getNodeParameter('metadata', itemIndex, '');
|
|
123
|
+
if (metadata) {
|
|
124
|
+
try {
|
|
125
|
+
options.metadata = JSON.parse(metadata);
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
throw new Error('Invalid metadata JSON');
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
const { data, error } = await supabase.storage
|
|
132
|
+
.from(bucket)
|
|
133
|
+
.upload(fileName, fileData, options);
|
|
134
|
+
if (error) {
|
|
135
|
+
throw new Error((0, supabaseClient_1.formatSupabaseError)(error));
|
|
136
|
+
}
|
|
137
|
+
return [{
|
|
138
|
+
json: {
|
|
139
|
+
operation: 'uploadFile',
|
|
140
|
+
bucket,
|
|
141
|
+
fileName,
|
|
142
|
+
path: data === null || data === void 0 ? void 0 : data.path,
|
|
143
|
+
id: data === null || data === void 0 ? void 0 : data.id,
|
|
144
|
+
fullPath: data === null || data === void 0 ? void 0 : data.fullPath,
|
|
145
|
+
success: true,
|
|
146
|
+
},
|
|
147
|
+
}];
|
|
148
|
+
}
|
|
149
|
+
async function handleDownloadFile(supabase, itemIndex) {
|
|
150
|
+
const bucket = this.getNodeParameter('bucket', itemIndex);
|
|
151
|
+
const filePath = this.getNodeParameter('filePath', itemIndex);
|
|
152
|
+
const outputFormat = this.getNodeParameter('outputFormat', itemIndex, 'binary');
|
|
153
|
+
if (!bucket || !filePath) {
|
|
154
|
+
throw new Error('Bucket name and file path are required');
|
|
155
|
+
}
|
|
156
|
+
const { data, error } = await supabase.storage
|
|
157
|
+
.from(bucket)
|
|
158
|
+
.download(filePath);
|
|
159
|
+
if (error) {
|
|
160
|
+
throw new Error((0, supabaseClient_1.formatSupabaseError)(error));
|
|
161
|
+
}
|
|
162
|
+
if (!data) {
|
|
163
|
+
throw new Error('No file data received');
|
|
164
|
+
}
|
|
165
|
+
if (outputFormat === 'binary') {
|
|
166
|
+
const buffer = Buffer.from(await data.arrayBuffer());
|
|
167
|
+
const fileName = path.basename(filePath);
|
|
168
|
+
const mimeType = data.type || (0, mime_types_1.lookup)(fileName) || 'application/octet-stream';
|
|
169
|
+
const binaryData = {
|
|
170
|
+
data: buffer.toString('base64'),
|
|
171
|
+
mimeType,
|
|
172
|
+
fileName,
|
|
173
|
+
};
|
|
174
|
+
return [{
|
|
175
|
+
json: {
|
|
176
|
+
operation: 'downloadFile',
|
|
177
|
+
bucket,
|
|
178
|
+
filePath,
|
|
179
|
+
fileName,
|
|
180
|
+
size: buffer.length,
|
|
181
|
+
mimeType,
|
|
182
|
+
},
|
|
183
|
+
binary: {
|
|
184
|
+
data: binaryData,
|
|
185
|
+
},
|
|
186
|
+
}];
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
const text = await data.text();
|
|
190
|
+
return [{
|
|
191
|
+
json: {
|
|
192
|
+
operation: 'downloadFile',
|
|
193
|
+
bucket,
|
|
194
|
+
filePath,
|
|
195
|
+
content: text,
|
|
196
|
+
size: data.size,
|
|
197
|
+
type: data.type,
|
|
198
|
+
},
|
|
199
|
+
}];
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
async function handleListFiles(supabase, itemIndex) {
|
|
203
|
+
const bucket = this.getNodeParameter('bucket', itemIndex);
|
|
204
|
+
const folderPath = this.getNodeParameter('folderPath', itemIndex, '');
|
|
205
|
+
if (!bucket) {
|
|
206
|
+
throw new Error('Bucket name is required');
|
|
207
|
+
}
|
|
208
|
+
const limit = this.getNodeParameter('limit', itemIndex, undefined);
|
|
209
|
+
const offset = this.getNodeParameter('offset', itemIndex, undefined);
|
|
210
|
+
const search = this.getNodeParameter('search', itemIndex, '');
|
|
211
|
+
const sortColumn = this.getNodeParameter('sortColumn', itemIndex, 'name');
|
|
212
|
+
const sortOrder = this.getNodeParameter('sortOrder', itemIndex, 'asc');
|
|
213
|
+
const options = {};
|
|
214
|
+
if (limit !== undefined)
|
|
215
|
+
options.limit = limit;
|
|
216
|
+
if (offset !== undefined)
|
|
217
|
+
options.offset = offset;
|
|
218
|
+
if (search)
|
|
219
|
+
options.search = search;
|
|
220
|
+
if (sortColumn && sortOrder) {
|
|
221
|
+
options.sortBy = { column: sortColumn, order: sortOrder };
|
|
222
|
+
}
|
|
223
|
+
const { data, error } = await supabase.storage
|
|
224
|
+
.from(bucket)
|
|
225
|
+
.list(folderPath, options);
|
|
226
|
+
if (error) {
|
|
227
|
+
throw new Error((0, supabaseClient_1.formatSupabaseError)(error));
|
|
228
|
+
}
|
|
229
|
+
const returnData = [];
|
|
230
|
+
if (Array.isArray(data)) {
|
|
231
|
+
for (const file of data) {
|
|
232
|
+
returnData.push({
|
|
233
|
+
json: {
|
|
234
|
+
...file,
|
|
235
|
+
bucket,
|
|
236
|
+
folderPath,
|
|
237
|
+
},
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
if (returnData.length === 0) {
|
|
242
|
+
returnData.push({
|
|
243
|
+
json: {
|
|
244
|
+
operation: 'listFiles',
|
|
245
|
+
bucket,
|
|
246
|
+
folderPath,
|
|
247
|
+
files: [],
|
|
248
|
+
count: 0,
|
|
249
|
+
message: 'No files found',
|
|
250
|
+
},
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
return returnData;
|
|
254
|
+
}
|
|
255
|
+
async function handleDeleteFile(supabase, itemIndex) {
|
|
256
|
+
const bucket = this.getNodeParameter('bucket', itemIndex);
|
|
257
|
+
const filePaths = this.getNodeParameter('filePaths', itemIndex);
|
|
258
|
+
if (!bucket || !filePaths) {
|
|
259
|
+
throw new Error('Bucket name and file path(s) are required');
|
|
260
|
+
}
|
|
261
|
+
const pathsArray = Array.isArray(filePaths) ? filePaths : [filePaths];
|
|
262
|
+
const { data, error } = await supabase.storage
|
|
263
|
+
.from(bucket)
|
|
264
|
+
.remove(pathsArray);
|
|
265
|
+
if (error) {
|
|
266
|
+
throw new Error((0, supabaseClient_1.formatSupabaseError)(error));
|
|
267
|
+
}
|
|
268
|
+
return [{
|
|
269
|
+
json: {
|
|
270
|
+
operation: 'deleteFile',
|
|
271
|
+
bucket,
|
|
272
|
+
deletedFiles: pathsArray,
|
|
273
|
+
result: data,
|
|
274
|
+
success: true,
|
|
275
|
+
},
|
|
276
|
+
}];
|
|
277
|
+
}
|
|
278
|
+
async function handleMoveFile(supabase, itemIndex) {
|
|
279
|
+
const bucket = this.getNodeParameter('bucket', itemIndex);
|
|
280
|
+
const fromPath = this.getNodeParameter('fromPath', itemIndex);
|
|
281
|
+
const toPath = this.getNodeParameter('toPath', itemIndex);
|
|
282
|
+
if (!bucket || !fromPath || !toPath) {
|
|
283
|
+
throw new Error('Bucket name, source path, and destination path are required');
|
|
284
|
+
}
|
|
285
|
+
const { data, error } = await supabase.storage
|
|
286
|
+
.from(bucket)
|
|
287
|
+
.move(fromPath, toPath);
|
|
288
|
+
if (error) {
|
|
289
|
+
throw new Error((0, supabaseClient_1.formatSupabaseError)(error));
|
|
290
|
+
}
|
|
291
|
+
return [{
|
|
292
|
+
json: {
|
|
293
|
+
operation: 'moveFile',
|
|
294
|
+
bucket,
|
|
295
|
+
fromPath,
|
|
296
|
+
toPath,
|
|
297
|
+
result: data,
|
|
298
|
+
success: true,
|
|
299
|
+
},
|
|
300
|
+
}];
|
|
301
|
+
}
|
|
302
|
+
async function handleCopyFile(supabase, itemIndex) {
|
|
303
|
+
const bucket = this.getNodeParameter('bucket', itemIndex);
|
|
304
|
+
const fromPath = this.getNodeParameter('fromPath', itemIndex);
|
|
305
|
+
const toPath = this.getNodeParameter('toPath', itemIndex);
|
|
306
|
+
if (!bucket || !fromPath || !toPath) {
|
|
307
|
+
throw new Error('Bucket name, source path, and destination path are required');
|
|
308
|
+
}
|
|
309
|
+
const { data, error } = await supabase.storage
|
|
310
|
+
.from(bucket)
|
|
311
|
+
.copy(fromPath, toPath);
|
|
312
|
+
if (error) {
|
|
313
|
+
throw new Error((0, supabaseClient_1.formatSupabaseError)(error));
|
|
314
|
+
}
|
|
315
|
+
return [{
|
|
316
|
+
json: {
|
|
317
|
+
operation: 'copyFile',
|
|
318
|
+
bucket,
|
|
319
|
+
fromPath,
|
|
320
|
+
toPath,
|
|
321
|
+
result: data,
|
|
322
|
+
success: true,
|
|
323
|
+
},
|
|
324
|
+
}];
|
|
325
|
+
}
|
|
326
|
+
async function handleCreateBucket(supabase, itemIndex) {
|
|
327
|
+
const bucketName = this.getNodeParameter('bucketName', itemIndex);
|
|
328
|
+
const isPublic = this.getNodeParameter('isPublic', itemIndex, false);
|
|
329
|
+
const fileSizeLimit = this.getNodeParameter('fileSizeLimit', itemIndex, undefined);
|
|
330
|
+
const allowedMimeTypes = this.getNodeParameter('allowedMimeTypes', itemIndex, '');
|
|
331
|
+
if (!bucketName) {
|
|
332
|
+
throw new Error('Bucket name is required');
|
|
333
|
+
}
|
|
334
|
+
const options = {
|
|
335
|
+
public: isPublic,
|
|
336
|
+
};
|
|
337
|
+
if (fileSizeLimit !== undefined) {
|
|
338
|
+
options.fileSizeLimit = fileSizeLimit;
|
|
339
|
+
}
|
|
340
|
+
if (allowedMimeTypes) {
|
|
341
|
+
try {
|
|
342
|
+
options.allowedMimeTypes = allowedMimeTypes.split(',').map(type => type.trim());
|
|
343
|
+
}
|
|
344
|
+
catch {
|
|
345
|
+
throw new Error('Invalid allowed MIME types format');
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
const { data, error } = await supabase.storage.createBucket(bucketName, options);
|
|
349
|
+
if (error) {
|
|
350
|
+
throw new Error((0, supabaseClient_1.formatSupabaseError)(error));
|
|
351
|
+
}
|
|
352
|
+
return [{
|
|
353
|
+
json: {
|
|
354
|
+
operation: 'createBucket',
|
|
355
|
+
bucketName,
|
|
356
|
+
options,
|
|
357
|
+
result: data,
|
|
358
|
+
success: true,
|
|
359
|
+
},
|
|
360
|
+
}];
|
|
361
|
+
}
|
|
362
|
+
async function handleDeleteBucket(supabase, itemIndex) {
|
|
363
|
+
const bucketName = this.getNodeParameter('bucketName', itemIndex);
|
|
364
|
+
if (!bucketName) {
|
|
365
|
+
throw new Error('Bucket name is required');
|
|
366
|
+
}
|
|
367
|
+
const { data, error } = await supabase.storage.deleteBucket(bucketName);
|
|
368
|
+
if (error) {
|
|
369
|
+
throw new Error((0, supabaseClient_1.formatSupabaseError)(error));
|
|
370
|
+
}
|
|
371
|
+
return [{
|
|
372
|
+
json: {
|
|
373
|
+
operation: 'deleteBucket',
|
|
374
|
+
bucketName,
|
|
375
|
+
result: data,
|
|
376
|
+
success: true,
|
|
377
|
+
},
|
|
378
|
+
}];
|
|
379
|
+
}
|
|
380
|
+
async function handleListBuckets(supabase, itemIndex) {
|
|
381
|
+
const { data, error } = await supabase.storage.listBuckets();
|
|
382
|
+
if (error) {
|
|
383
|
+
throw new Error((0, supabaseClient_1.formatSupabaseError)(error));
|
|
384
|
+
}
|
|
385
|
+
const returnData = [];
|
|
386
|
+
if (Array.isArray(data)) {
|
|
387
|
+
for (const bucket of data) {
|
|
388
|
+
returnData.push({ json: bucket });
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
if (returnData.length === 0) {
|
|
392
|
+
returnData.push({
|
|
393
|
+
json: {
|
|
394
|
+
operation: 'listBuckets',
|
|
395
|
+
buckets: [],
|
|
396
|
+
count: 0,
|
|
397
|
+
message: 'No buckets found',
|
|
398
|
+
},
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
return returnData;
|
|
402
|
+
}
|
|
403
|
+
async function handleGetBucketDetails(supabase, itemIndex) {
|
|
404
|
+
const bucketName = this.getNodeParameter('bucketName', itemIndex);
|
|
405
|
+
if (!bucketName) {
|
|
406
|
+
throw new Error('Bucket name is required');
|
|
407
|
+
}
|
|
408
|
+
const { data, error } = await supabase.storage.getBucket(bucketName);
|
|
409
|
+
if (error) {
|
|
410
|
+
throw new Error((0, supabaseClient_1.formatSupabaseError)(error));
|
|
411
|
+
}
|
|
412
|
+
return [{
|
|
413
|
+
json: {
|
|
414
|
+
operation: 'getBucketDetails',
|
|
415
|
+
bucketName,
|
|
416
|
+
...data,
|
|
417
|
+
},
|
|
418
|
+
}];
|
|
419
|
+
}
|
|
420
|
+
async function handleGetFileInfo(supabase, itemIndex) {
|
|
421
|
+
const bucket = this.getNodeParameter('bucket', itemIndex);
|
|
422
|
+
const filePath = this.getNodeParameter('filePath', itemIndex);
|
|
423
|
+
if (!bucket || !filePath) {
|
|
424
|
+
throw new Error('Bucket name and file path are required');
|
|
425
|
+
}
|
|
426
|
+
const { data, error } = await supabase.storage
|
|
427
|
+
.from(bucket)
|
|
428
|
+
.list(path.dirname(filePath), {
|
|
429
|
+
search: path.basename(filePath),
|
|
430
|
+
});
|
|
431
|
+
if (error) {
|
|
432
|
+
throw new Error((0, supabaseClient_1.formatSupabaseError)(error));
|
|
433
|
+
}
|
|
434
|
+
const fileInfo = data === null || data === void 0 ? void 0 : data.find(file => file.name === path.basename(filePath));
|
|
435
|
+
if (!fileInfo) {
|
|
436
|
+
throw new Error('File not found');
|
|
437
|
+
}
|
|
438
|
+
return [{
|
|
439
|
+
json: {
|
|
440
|
+
operation: 'getFileInfo',
|
|
441
|
+
bucket,
|
|
442
|
+
filePath,
|
|
443
|
+
...fileInfo,
|
|
444
|
+
},
|
|
445
|
+
}];
|
|
446
|
+
}
|
|
447
|
+
async function handleGenerateSignedUrl(supabase, itemIndex) {
|
|
448
|
+
const bucket = this.getNodeParameter('bucket', itemIndex);
|
|
449
|
+
const filePath = this.getNodeParameter('filePath', itemIndex);
|
|
450
|
+
const expiresIn = this.getNodeParameter('expiresIn', itemIndex, 3600);
|
|
451
|
+
const download = this.getNodeParameter('download', itemIndex, false);
|
|
452
|
+
if (!bucket || !filePath) {
|
|
453
|
+
throw new Error('Bucket name and file path are required');
|
|
454
|
+
}
|
|
455
|
+
const options = { download };
|
|
456
|
+
const { data, error } = await supabase.storage
|
|
457
|
+
.from(bucket)
|
|
458
|
+
.createSignedUrl(filePath, expiresIn, options);
|
|
459
|
+
if (error) {
|
|
460
|
+
throw new Error((0, supabaseClient_1.formatSupabaseError)(error));
|
|
461
|
+
}
|
|
462
|
+
return [{
|
|
463
|
+
json: {
|
|
464
|
+
operation: 'generateSignedUrl',
|
|
465
|
+
bucket,
|
|
466
|
+
filePath,
|
|
467
|
+
expiresIn,
|
|
468
|
+
download,
|
|
469
|
+
signedUrl: data === null || data === void 0 ? void 0 : data.signedUrl,
|
|
470
|
+
...(data && 'path' in data ? { path: data.path } : {}),
|
|
471
|
+
...(data && 'token' in data ? { token: data.token } : {}),
|
|
472
|
+
},
|
|
473
|
+
}];
|
|
474
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
export interface ISupabaseCredentials {
|
|
2
|
+
host: string;
|
|
3
|
+
serviceKey: string;
|
|
4
|
+
additionalOptions?: {
|
|
5
|
+
schema?: string;
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
export interface IRowFilter {
|
|
9
|
+
column: string;
|
|
10
|
+
operator: 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'like' | 'ilike' | 'is' | 'in' | 'cs' | 'cd';
|
|
11
|
+
value: string | number | boolean | null;
|
|
12
|
+
}
|
|
13
|
+
export interface IRowSort {
|
|
14
|
+
column: string;
|
|
15
|
+
ascending: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface IColumnDefinition {
|
|
18
|
+
name: string;
|
|
19
|
+
type: string;
|
|
20
|
+
nullable?: boolean;
|
|
21
|
+
defaultValue?: string;
|
|
22
|
+
primaryKey?: boolean;
|
|
23
|
+
unique?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface IIndexDefinition {
|
|
26
|
+
name: string;
|
|
27
|
+
columns: string[];
|
|
28
|
+
unique?: boolean;
|
|
29
|
+
method?: 'btree' | 'hash' | 'gist' | 'gin';
|
|
30
|
+
}
|
|
31
|
+
export interface IStorageFile {
|
|
32
|
+
name: string;
|
|
33
|
+
id?: string;
|
|
34
|
+
updated_at?: string;
|
|
35
|
+
created_at?: string;
|
|
36
|
+
last_accessed_at?: string;
|
|
37
|
+
metadata?: Record<string, any>;
|
|
38
|
+
}
|
|
39
|
+
export interface IStorageBucket {
|
|
40
|
+
id: string;
|
|
41
|
+
name: string;
|
|
42
|
+
owner?: string;
|
|
43
|
+
public?: boolean;
|
|
44
|
+
file_size_limit?: number;
|
|
45
|
+
allowed_mime_types?: string[];
|
|
46
|
+
created_at?: string;
|
|
47
|
+
updated_at?: string;
|
|
48
|
+
}
|
|
49
|
+
export interface IFileUploadOptions {
|
|
50
|
+
cacheControl?: string;
|
|
51
|
+
contentType?: string;
|
|
52
|
+
upsert?: boolean;
|
|
53
|
+
metadata?: Record<string, any>;
|
|
54
|
+
}
|
|
55
|
+
export interface IFileListOptions {
|
|
56
|
+
limit?: number;
|
|
57
|
+
offset?: number;
|
|
58
|
+
sortBy?: {
|
|
59
|
+
column: 'name' | 'id' | 'updated_at' | 'created_at' | 'last_accessed_at';
|
|
60
|
+
order: 'asc' | 'desc';
|
|
61
|
+
};
|
|
62
|
+
search?: string;
|
|
63
|
+
}
|
|
64
|
+
export interface ISupabaseResponse<T = any> {
|
|
65
|
+
data: T | null;
|
|
66
|
+
error: any;
|
|
67
|
+
count?: number;
|
|
68
|
+
status?: number;
|
|
69
|
+
statusText?: string;
|
|
70
|
+
}
|
|
71
|
+
export interface ISupabaseStorageResponse<T = any> {
|
|
72
|
+
data: T | null;
|
|
73
|
+
error: {
|
|
74
|
+
message: string;
|
|
75
|
+
statusCode?: string;
|
|
76
|
+
} | null;
|
|
77
|
+
}
|
|
78
|
+
export type DatabaseOperation = 'create' | 'read' | 'update' | 'delete' | 'upsert' | 'createTable' | 'dropTable' | 'addColumn' | 'dropColumn' | 'createIndex' | 'dropIndex' | 'customQuery';
|
|
79
|
+
export type StorageOperation = 'uploadFile' | 'downloadFile' | 'listFiles' | 'deleteFile' | 'moveFile' | 'copyFile' | 'createBucket' | 'deleteBucket' | 'listBuckets' | 'getBucketDetails' | 'getFileInfo' | 'generateSignedUrl';
|
|
80
|
+
export type SupabaseResource = 'database' | 'storage';
|
|
81
|
+
export interface ISupabaseNodeParameters {
|
|
82
|
+
resource: SupabaseResource;
|
|
83
|
+
operation: DatabaseOperation | StorageOperation;
|
|
84
|
+
table?: string;
|
|
85
|
+
columns?: string;
|
|
86
|
+
filters?: IRowFilter[];
|
|
87
|
+
sort?: IRowSort[];
|
|
88
|
+
limit?: number;
|
|
89
|
+
offset?: number;
|
|
90
|
+
returnFields?: string;
|
|
91
|
+
tableName?: string;
|
|
92
|
+
columnDefinitions?: IColumnDefinition[];
|
|
93
|
+
indexDefinition?: IIndexDefinition;
|
|
94
|
+
customSql?: string;
|
|
95
|
+
bucket?: string;
|
|
96
|
+
fileName?: string;
|
|
97
|
+
filePath?: string;
|
|
98
|
+
fileContent?: string;
|
|
99
|
+
fileOptions?: IFileUploadOptions;
|
|
100
|
+
listOptions?: IFileListOptions;
|
|
101
|
+
signedUrlOptions?: {
|
|
102
|
+
expiresIn: number;
|
|
103
|
+
download?: boolean;
|
|
104
|
+
};
|
|
105
|
+
uiMode?: 'simple' | 'advanced';
|
|
106
|
+
additionalOptions?: Record<string, any>;
|
|
107
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { SupabaseClient } from '@supabase/supabase-js';
|
|
2
|
+
import { ISupabaseCredentials } from '../types';
|
|
3
|
+
export declare function createSupabaseClient(credentials: ISupabaseCredentials): SupabaseClient;
|
|
4
|
+
export declare function validateCredentials(credentials: ISupabaseCredentials): void;
|
|
5
|
+
export declare function getStorageUrl(projectUrl: string): string;
|
|
6
|
+
export declare function getDatabaseUrl(projectUrl: string): string;
|
|
7
|
+
export declare function formatSupabaseError(error: any): string;
|
|
8
|
+
export declare function isAuthError(error: any): boolean;
|
|
9
|
+
export declare function isNetworkError(error: any): boolean;
|
|
10
|
+
export declare function sanitizeColumnName(columnName: string): string;
|
|
11
|
+
export declare function validateTableName(tableName: string): void;
|
|
12
|
+
export declare function validateColumnName(columnName: string): void;
|
|
13
|
+
export declare function convertFilterOperator(operator: string): string;
|