@arela/uploader 0.0.1
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/.prettierrc +13 -0
- package/README.md +1 -0
- package/package.json +41 -0
- package/src/index.js +81 -0
package/.prettierrc
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"singleQuote": true,
|
|
3
|
+
"trailingComma": "all",
|
|
4
|
+
"importOrder": ["^\\.\\./services/(.*)$", "^\\.\\./dto/(.*)$", "^[./]"],
|
|
5
|
+
"importOrderSeparation": true,
|
|
6
|
+
"importOrderSortSpecifiers": true,
|
|
7
|
+
"importOrderParserPlugins": [
|
|
8
|
+
"typescript",
|
|
9
|
+
"classProperties",
|
|
10
|
+
"decorators-legacy"
|
|
11
|
+
],
|
|
12
|
+
"plugins": ["@trivago/prettier-plugin-sort-imports"]
|
|
13
|
+
}
|
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# arela-uploader
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@arela/uploader",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "CLI to upload files/directories to Arela",
|
|
5
|
+
"bin": {
|
|
6
|
+
"arela": "./src/index.js"
|
|
7
|
+
},
|
|
8
|
+
"type": "module",
|
|
9
|
+
"scripts": {
|
|
10
|
+
"start": "node ./src/index.js",
|
|
11
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
12
|
+
"format": "prettier --write \"src/**/*.js\""
|
|
13
|
+
},
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/inspiraCode/arela-uploader.git"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"arela",
|
|
20
|
+
"cli",
|
|
21
|
+
"uploader",
|
|
22
|
+
"record-keeping"
|
|
23
|
+
],
|
|
24
|
+
"author": "Alfredo Pacheco",
|
|
25
|
+
"license": "ISC",
|
|
26
|
+
"bugs": {
|
|
27
|
+
"url": "https://github.com/inspiraCode/arela-uploader/issues"
|
|
28
|
+
},
|
|
29
|
+
"homepage": "https://github.com/inspiraCode/arela-uploader#readme",
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@supabase/supabase-js": "^2.49.4",
|
|
32
|
+
"commander": "^13.1.0",
|
|
33
|
+
"dotenv": "^16.5.0",
|
|
34
|
+
"globby": "^14.1.0",
|
|
35
|
+
"mime-types": "^3.0.1"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
|
|
39
|
+
"prettier": "^3.5.3"
|
|
40
|
+
}
|
|
41
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createClient } from '@supabase/supabase-js';
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import { config } from 'dotenv';
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import { globby } from 'globby';
|
|
7
|
+
import mime from 'mime-types';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
|
|
10
|
+
config();
|
|
11
|
+
|
|
12
|
+
const program = new Command();
|
|
13
|
+
|
|
14
|
+
const supabaseUrl = process.env.SUPABASE_URL;
|
|
15
|
+
const supabaseKey = process.env.SUPABASE_KEY;
|
|
16
|
+
const bucket = process.env.SUPABASE_BUCKET;
|
|
17
|
+
|
|
18
|
+
const supabase = createClient(supabaseUrl, supabaseKey);
|
|
19
|
+
|
|
20
|
+
const checkCredentials = async () => {
|
|
21
|
+
if (!supabaseUrl || !supabaseKey || !bucket) {
|
|
22
|
+
console.error(
|
|
23
|
+
'⚠️ Missing Supabase credentials. Please set SUPABASE_URL, SUPABASE_KEY, and SUPABASE_BUCKET in your environment variables.',
|
|
24
|
+
);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
const { error } = await supabase.storage.from(bucket).list('');
|
|
30
|
+
if (error) {
|
|
31
|
+
console.error('⚠️ Error connecting to Supabase:', error.message);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
} catch (err) {
|
|
35
|
+
console.error('⚠️ Error:', err.message);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
await checkCredentials();
|
|
41
|
+
|
|
42
|
+
program
|
|
43
|
+
.name('supabase-uploader')
|
|
44
|
+
.description('CLI to upload files/directories to Supabase Storage')
|
|
45
|
+
.argument('<source>', 'File or directory to upload')
|
|
46
|
+
.option('-p, --prefix <prefix>', 'Prefix path in bucket', '')
|
|
47
|
+
.action(async (source, options) => {
|
|
48
|
+
try {
|
|
49
|
+
const stats = fs.statSync(source);
|
|
50
|
+
const files = stats.isDirectory()
|
|
51
|
+
? await globby([`${source}/**/*`], { onlyFiles: true })
|
|
52
|
+
: [source];
|
|
53
|
+
|
|
54
|
+
for (const file of files) {
|
|
55
|
+
const content = fs.readFileSync(file);
|
|
56
|
+
const relativePath = path.relative(source, file);
|
|
57
|
+
const uploadPath = options.prefix
|
|
58
|
+
? path.join(options.prefix, relativePath)
|
|
59
|
+
: relativePath;
|
|
60
|
+
|
|
61
|
+
const contentType = mime.lookup(file) || 'application/octet-stream';
|
|
62
|
+
|
|
63
|
+
const { data, error } = await supabase.storage
|
|
64
|
+
.from(bucket)
|
|
65
|
+
.upload(uploadPath.replace(/\\/g, '/'), content, {
|
|
66
|
+
upsert: true,
|
|
67
|
+
contentType,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
if (error) {
|
|
71
|
+
console.error(`❌ Failed to upload ${file}:`, error.message);
|
|
72
|
+
} else {
|
|
73
|
+
console.log(`✅ Uploaded ${file} -> ${uploadPath}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
} catch (err) {
|
|
77
|
+
console.error('⚠️ Error:', err.message);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
program.parse();
|