@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,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.convertFilterOperator = exports.validateColumnName = exports.validateTableName = exports.sanitizeColumnName = exports.isNetworkError = exports.isAuthError = exports.formatSupabaseError = exports.getDatabaseUrl = exports.getStorageUrl = exports.validateCredentials = exports.createSupabaseClient = void 0;
|
|
4
|
+
const supabase_js_1 = require("@supabase/supabase-js");
|
|
5
|
+
function createSupabaseClient(credentials) {
|
|
6
|
+
const client = (0, supabase_js_1.createClient)(credentials.host, credentials.serviceKey, {
|
|
7
|
+
auth: {
|
|
8
|
+
autoRefreshToken: true,
|
|
9
|
+
persistSession: false,
|
|
10
|
+
detectSessionInUrl: false,
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
return client;
|
|
14
|
+
}
|
|
15
|
+
exports.createSupabaseClient = createSupabaseClient;
|
|
16
|
+
function validateCredentials(credentials) {
|
|
17
|
+
if (!credentials.host) {
|
|
18
|
+
throw new Error('Supabase Project URL is required');
|
|
19
|
+
}
|
|
20
|
+
if (!credentials.serviceKey) {
|
|
21
|
+
throw new Error('Supabase API Key is required');
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
new URL(credentials.host);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
throw new Error('Invalid Supabase Project URL format');
|
|
28
|
+
}
|
|
29
|
+
if (!credentials.host.includes('supabase.co') && !credentials.host.includes('localhost')) {
|
|
30
|
+
throw new Error('URL must be a valid Supabase project URL');
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
exports.validateCredentials = validateCredentials;
|
|
34
|
+
function getStorageUrl(projectUrl) {
|
|
35
|
+
const url = new URL(projectUrl);
|
|
36
|
+
return `${url.protocol}//${url.host}/storage/v1`;
|
|
37
|
+
}
|
|
38
|
+
exports.getStorageUrl = getStorageUrl;
|
|
39
|
+
function getDatabaseUrl(projectUrl) {
|
|
40
|
+
const url = new URL(projectUrl);
|
|
41
|
+
return `${url.protocol}//${url.host}/rest/v1`;
|
|
42
|
+
}
|
|
43
|
+
exports.getDatabaseUrl = getDatabaseUrl;
|
|
44
|
+
function formatSupabaseError(error) {
|
|
45
|
+
if (!error)
|
|
46
|
+
return 'Unknown error occurred';
|
|
47
|
+
if (typeof error === 'string')
|
|
48
|
+
return error;
|
|
49
|
+
if (error.message)
|
|
50
|
+
return error.message;
|
|
51
|
+
if (error.error_description)
|
|
52
|
+
return error.error_description;
|
|
53
|
+
if (error.details)
|
|
54
|
+
return error.details;
|
|
55
|
+
return JSON.stringify(error);
|
|
56
|
+
}
|
|
57
|
+
exports.formatSupabaseError = formatSupabaseError;
|
|
58
|
+
function isAuthError(error) {
|
|
59
|
+
if (!error)
|
|
60
|
+
return false;
|
|
61
|
+
const authErrorCodes = [
|
|
62
|
+
'invalid_api_key',
|
|
63
|
+
'insufficient_privileges',
|
|
64
|
+
'unauthorized',
|
|
65
|
+
'forbidden',
|
|
66
|
+
];
|
|
67
|
+
return authErrorCodes.some(code => {
|
|
68
|
+
var _a;
|
|
69
|
+
return error.code === code ||
|
|
70
|
+
((_a = error.message) === null || _a === void 0 ? void 0 : _a.toLowerCase().includes(code)) ||
|
|
71
|
+
error.statusCode === 401 ||
|
|
72
|
+
error.statusCode === 403;
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
exports.isAuthError = isAuthError;
|
|
76
|
+
function isNetworkError(error) {
|
|
77
|
+
var _a;
|
|
78
|
+
if (!error)
|
|
79
|
+
return false;
|
|
80
|
+
const networkErrorPatterns = [
|
|
81
|
+
'network',
|
|
82
|
+
'connection',
|
|
83
|
+
'timeout',
|
|
84
|
+
'unreachable',
|
|
85
|
+
'dns',
|
|
86
|
+
'econnrefused',
|
|
87
|
+
'enotfound',
|
|
88
|
+
];
|
|
89
|
+
const errorMessage = ((_a = error.message) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || '';
|
|
90
|
+
return networkErrorPatterns.some(pattern => errorMessage.includes(pattern));
|
|
91
|
+
}
|
|
92
|
+
exports.isNetworkError = isNetworkError;
|
|
93
|
+
function sanitizeColumnName(columnName) {
|
|
94
|
+
return columnName.replace(/[^a-zA-Z0-9_-]/g, '');
|
|
95
|
+
}
|
|
96
|
+
exports.sanitizeColumnName = sanitizeColumnName;
|
|
97
|
+
function validateTableName(tableName) {
|
|
98
|
+
if (!tableName) {
|
|
99
|
+
throw new Error('Table name is required');
|
|
100
|
+
}
|
|
101
|
+
if (!/^[a-zA-Z][a-zA-Z0-9_]*$/.test(tableName)) {
|
|
102
|
+
throw new Error('Table name must start with a letter and contain only letters, numbers, and underscores');
|
|
103
|
+
}
|
|
104
|
+
if (tableName.length > 63) {
|
|
105
|
+
throw new Error('Table name must be 63 characters or less');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
exports.validateTableName = validateTableName;
|
|
109
|
+
function validateColumnName(columnName) {
|
|
110
|
+
if (!columnName) {
|
|
111
|
+
throw new Error('Column name is required');
|
|
112
|
+
}
|
|
113
|
+
if (!/^[a-zA-Z][a-zA-Z0-9_]*$/.test(columnName)) {
|
|
114
|
+
throw new Error('Column name must start with a letter and contain only letters, numbers, and underscores');
|
|
115
|
+
}
|
|
116
|
+
if (columnName.length > 63) {
|
|
117
|
+
throw new Error('Column name must be 63 characters or less');
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
exports.validateColumnName = validateColumnName;
|
|
121
|
+
function convertFilterOperator(operator) {
|
|
122
|
+
const operatorMap = {
|
|
123
|
+
'eq': 'eq',
|
|
124
|
+
'neq': 'neq',
|
|
125
|
+
'gt': 'gt',
|
|
126
|
+
'gte': 'gte',
|
|
127
|
+
'lt': 'lt',
|
|
128
|
+
'lte': 'lte',
|
|
129
|
+
'like': 'like',
|
|
130
|
+
'ilike': 'ilike',
|
|
131
|
+
'is': 'is',
|
|
132
|
+
'in': 'in',
|
|
133
|
+
'cs': 'cs',
|
|
134
|
+
'cd': 'cd',
|
|
135
|
+
};
|
|
136
|
+
return operatorMap[operator] || 'eq';
|
|
137
|
+
}
|
|
138
|
+
exports.convertFilterOperator = convertFilterOperator;
|
package/package.json
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fachkraftfreund/n8n-nodes-supabase",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "Comprehensive n8n community node for Supabase with database and storage operations",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"n8n-community-node-package",
|
|
7
|
+
"supabase",
|
|
8
|
+
"database",
|
|
9
|
+
"storage",
|
|
10
|
+
"postgresql",
|
|
11
|
+
"n8n",
|
|
12
|
+
"workflow",
|
|
13
|
+
"automation"
|
|
14
|
+
],
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"homepage": "https://github.com/yourusername/n8n-nodes-supabase",
|
|
17
|
+
"author": {
|
|
18
|
+
"name": "Your Name",
|
|
19
|
+
"email": "your.email@example.com"
|
|
20
|
+
},
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/yourusername/n8n-nodes-supabase.git"
|
|
24
|
+
},
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=16.10",
|
|
27
|
+
"pnpm": ">=7.18"
|
|
28
|
+
},
|
|
29
|
+
"packageManager": "pnpm@8.6.2",
|
|
30
|
+
"main": "index.js",
|
|
31
|
+
"files": [
|
|
32
|
+
"dist"
|
|
33
|
+
],
|
|
34
|
+
"n8n": {
|
|
35
|
+
"n8nNodesApiVersion": 1,
|
|
36
|
+
"credentials": [
|
|
37
|
+
"dist/credentials/SupabaseExtendedApi.credentials.js"
|
|
38
|
+
],
|
|
39
|
+
"nodes": [
|
|
40
|
+
"dist/nodes/Supabase/Supabase.node.js"
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/jest": "^29.5.5",
|
|
45
|
+
"@types/mime-types": "^3.0.1",
|
|
46
|
+
"@types/node": "^18.16.16",
|
|
47
|
+
"@typescript-eslint/eslint-plugin": "^8.49.0",
|
|
48
|
+
"@typescript-eslint/parser": "^6.0.0",
|
|
49
|
+
"eslint": "^8.42.0",
|
|
50
|
+
"eslint-plugin-n8n-nodes-base": "^1.11.0",
|
|
51
|
+
"gulp": "^4.0.2",
|
|
52
|
+
"jest": "^29.6.2",
|
|
53
|
+
"n8n-workflow": "^1.0.0",
|
|
54
|
+
"prettier": "^2.7.1",
|
|
55
|
+
"ts-jest": "^29.1.1",
|
|
56
|
+
"typescript": "^5.1.3"
|
|
57
|
+
},
|
|
58
|
+
"dependencies": {
|
|
59
|
+
"@supabase/supabase-js": "^2.38.0",
|
|
60
|
+
"form-data": "^4.0.0",
|
|
61
|
+
"mime-types": "^2.1.35"
|
|
62
|
+
},
|
|
63
|
+
"jest": {
|
|
64
|
+
"preset": "ts-jest",
|
|
65
|
+
"testEnvironment": "node",
|
|
66
|
+
"roots": [
|
|
67
|
+
"<rootDir>/nodes",
|
|
68
|
+
"<rootDir>/credentials"
|
|
69
|
+
],
|
|
70
|
+
"testMatch": [
|
|
71
|
+
"**/__tests__/**/*.ts",
|
|
72
|
+
"**/*.(test|spec).ts"
|
|
73
|
+
],
|
|
74
|
+
"collectCoverageFrom": [
|
|
75
|
+
"**/*.ts",
|
|
76
|
+
"!**/*.d.ts",
|
|
77
|
+
"!**/node_modules/**",
|
|
78
|
+
"!**/dist/**"
|
|
79
|
+
]
|
|
80
|
+
},
|
|
81
|
+
"scripts": {
|
|
82
|
+
"preinstall": "npx only-allow pnpm",
|
|
83
|
+
"build": "tsc && gulp build:icons",
|
|
84
|
+
"dev": "tsc --watch",
|
|
85
|
+
"format": "prettier nodes credentials --write",
|
|
86
|
+
"lint": "eslint nodes/**/*.ts credentials/**/*.ts package.json",
|
|
87
|
+
"lintfix": "eslint nodes/**/*.ts credentials/**/*.ts package.json --fix",
|
|
88
|
+
"test": "echo \"No tests specified\" && exit 0",
|
|
89
|
+
"test:watch": "jest --watch",
|
|
90
|
+
"test:cov": "jest --coverage"
|
|
91
|
+
}
|
|
92
|
+
}
|