@orcapt/cli 1.0.1 → 1.0.3
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/README.md +0 -16
- package/bin/orca.js +30 -61
- package/package.json +1 -1
- package/src/commands/db.js +11 -11
- package/src/commands/fetch-doc.js +3 -3
- package/src/commands/kickstart-node.js +18 -18
- package/src/commands/kickstart-python.js +12 -13
- package/src/commands/lambda.js +24 -24
- package/src/commands/login.js +6 -6
- package/src/commands/storage.js +54 -183
- package/src/commands/ui.js +21 -21
- package/src/utils/index.js +1 -1
package/src/commands/storage.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* Manage S3-like storage buckets and files via
|
|
2
|
+
* orcapt Storage Commands
|
|
3
|
+
* Manage S3-like storage buckets and files via orcapt Deploy API
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
const chalk = require('chalk');
|
|
@@ -13,7 +13,7 @@ const { getCredentials } = require('./login');
|
|
|
13
13
|
const { API_BASE_URL, API_ENDPOINTS } = require('../config');
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
* Make API request to
|
|
16
|
+
* Make API request to orcapt Deploy API
|
|
17
17
|
*/
|
|
18
18
|
function makeApiRequest(method, endpoint, credentials, body = null) {
|
|
19
19
|
return new Promise((resolve, reject) => {
|
|
@@ -79,31 +79,31 @@ function uploadFileToApi(endpoint, credentials, filePath, bucketName, options =
|
|
|
79
79
|
const fileStream = fs.createReadStream(filePath);
|
|
80
80
|
const fileName = path.basename(filePath);
|
|
81
81
|
const boundary = `----FormBoundary${Date.now()}`;
|
|
82
|
-
|
|
82
|
+
|
|
83
83
|
const folderPath = options.folder || '';
|
|
84
|
-
|
|
84
|
+
|
|
85
85
|
// Build multipart form data
|
|
86
86
|
let formData = '';
|
|
87
|
-
|
|
87
|
+
|
|
88
88
|
// Add folder_path field
|
|
89
89
|
if (folderPath) {
|
|
90
90
|
formData += `--${boundary}\r\n`;
|
|
91
91
|
formData += `Content-Disposition: form-data; name="folder_path"\r\n\r\n`;
|
|
92
92
|
formData += `${folderPath}\r\n`;
|
|
93
93
|
}
|
|
94
|
-
|
|
94
|
+
|
|
95
95
|
// Add visibility field
|
|
96
96
|
if (options.visibility) {
|
|
97
97
|
formData += `--${boundary}\r\n`;
|
|
98
98
|
formData += `Content-Disposition: form-data; name="visibility"\r\n\r\n`;
|
|
99
99
|
formData += `${options.visibility}\r\n`;
|
|
100
100
|
}
|
|
101
|
-
|
|
101
|
+
|
|
102
102
|
// Add generate_url field
|
|
103
103
|
formData += `--${boundary}\r\n`;
|
|
104
104
|
formData += `Content-Disposition: form-data; name="generate_url"\r\n\r\n`;
|
|
105
105
|
formData += `true\r\n`;
|
|
106
|
-
|
|
106
|
+
|
|
107
107
|
// Add file field header
|
|
108
108
|
formData += `--${boundary}\r\n`;
|
|
109
109
|
formData += `Content-Disposition: form-data; name="file"; filename="${fileName}"\r\n`;
|
|
@@ -191,7 +191,7 @@ function requireAuth() {
|
|
|
191
191
|
const credentials = getCredentials();
|
|
192
192
|
if (!credentials) {
|
|
193
193
|
console.log(chalk.red('\n✗ Not authenticated'));
|
|
194
|
-
console.log(chalk.cyan('Please run:'), chalk.yellow('
|
|
194
|
+
console.log(chalk.cyan('Please run:'), chalk.yellow('orcapt login'), chalk.cyan('first\n'));
|
|
195
195
|
process.exit(1);
|
|
196
196
|
}
|
|
197
197
|
return credentials;
|
|
@@ -206,7 +206,7 @@ async function bucketCreate(bucketName, options = {}) {
|
|
|
206
206
|
console.log(chalk.cyan('============================================================\n'));
|
|
207
207
|
|
|
208
208
|
const credentials = requireAuth();
|
|
209
|
-
|
|
209
|
+
|
|
210
210
|
console.log(chalk.white('Bucket: '), chalk.yellow(bucketName));
|
|
211
211
|
console.log(chalk.white('Workspace: '), chalk.yellow(credentials.workspace));
|
|
212
212
|
console.log(chalk.white('Visibility: '), chalk.yellow(options.public ? 'public' : 'private'));
|
|
@@ -237,7 +237,7 @@ async function bucketCreate(bucketName, options = {}) {
|
|
|
237
237
|
);
|
|
238
238
|
|
|
239
239
|
spinner.succeed(chalk.green('✓ Bucket created successfully!'));
|
|
240
|
-
|
|
240
|
+
|
|
241
241
|
console.log(chalk.cyan('\n📦 Bucket Details:'));
|
|
242
242
|
console.log(chalk.white(' Name: '), chalk.yellow(response.bucket.bucket_name));
|
|
243
243
|
console.log(chalk.white(' AWS Bucket: '), chalk.gray(response.bucket.aws_bucket_name));
|
|
@@ -245,15 +245,15 @@ async function bucketCreate(bucketName, options = {}) {
|
|
|
245
245
|
console.log(chalk.white(' Status: '), chalk.green(response.bucket.status));
|
|
246
246
|
console.log(chalk.white(' Visibility: '), chalk.yellow(response.bucket.visibility));
|
|
247
247
|
console.log(chalk.white(' Encryption: '), chalk.yellow(response.bucket.encryption_enabled ? 'Enabled' : 'Disabled'));
|
|
248
|
-
|
|
248
|
+
|
|
249
249
|
console.log(chalk.cyan('\n💡 Next Steps:'));
|
|
250
|
-
console.log(chalk.white(' Upload file: '), chalk.yellow(`
|
|
251
|
-
console.log(chalk.white(' List files: '), chalk.yellow(`
|
|
250
|
+
console.log(chalk.white(' Upload file: '), chalk.yellow(`orcapt storage upload ${bucketName} <file-path>`));
|
|
251
|
+
console.log(chalk.white(' List files: '), chalk.yellow(`orcapt storage files ${bucketName}`));
|
|
252
252
|
console.log('');
|
|
253
253
|
|
|
254
254
|
} catch (error) {
|
|
255
255
|
spinner.fail(chalk.red('✗ Failed to create bucket'));
|
|
256
|
-
|
|
256
|
+
|
|
257
257
|
if (error.response) {
|
|
258
258
|
console.log(chalk.red(`\n✗ ${error.response.message || 'Unknown error'}`));
|
|
259
259
|
if (error.statusCode === 409) {
|
|
@@ -294,7 +294,7 @@ async function bucketList() {
|
|
|
294
294
|
if (response.count === 0) {
|
|
295
295
|
console.log(chalk.yellow('\n📭 No buckets found'));
|
|
296
296
|
console.log(chalk.cyan('\n💡 Create your first bucket:'));
|
|
297
|
-
console.log(chalk.white(' '), chalk.yellow('
|
|
297
|
+
console.log(chalk.white(' '), chalk.yellow('orcapt storage bucket create my-bucket'));
|
|
298
298
|
console.log('');
|
|
299
299
|
return;
|
|
300
300
|
}
|
|
@@ -316,7 +316,7 @@ async function bucketList() {
|
|
|
316
316
|
const files = String(bucket.file_count).padEnd(10);
|
|
317
317
|
const size = bucket.total_size.padEnd(15);
|
|
318
318
|
const visibility = bucket.visibility.padEnd(15);
|
|
319
|
-
const status = bucket.status === 'active'
|
|
319
|
+
const status = bucket.status === 'active'
|
|
320
320
|
? chalk.green(bucket.status.padEnd(15))
|
|
321
321
|
: chalk.yellow(bucket.status.padEnd(15));
|
|
322
322
|
const created = new Date(bucket.created_at).toLocaleDateString();
|
|
@@ -336,7 +336,7 @@ async function bucketList() {
|
|
|
336
336
|
|
|
337
337
|
} catch (error) {
|
|
338
338
|
spinner.fail(chalk.red('✗ Failed to list buckets'));
|
|
339
|
-
|
|
339
|
+
|
|
340
340
|
if (error.response) {
|
|
341
341
|
console.log(chalk.red(`\n✗ ${error.response.message || 'Unknown error'}\n`));
|
|
342
342
|
} else {
|
|
@@ -370,11 +370,11 @@ async function fileUpload(bucketName, localPath, options = {}) {
|
|
|
370
370
|
console.log(chalk.white('File: '), chalk.yellow(fileName));
|
|
371
371
|
console.log(chalk.white('Local Path: '), chalk.gray(localPath));
|
|
372
372
|
console.log(chalk.white('Size: '), chalk.yellow(`${fileSizeMB} MB`));
|
|
373
|
-
|
|
373
|
+
|
|
374
374
|
if (options.folder) {
|
|
375
375
|
console.log(chalk.white('Folder: '), chalk.yellow(options.folder));
|
|
376
376
|
}
|
|
377
|
-
|
|
377
|
+
|
|
378
378
|
console.log(chalk.white('Visibility: '), chalk.yellow(options.public ? 'public' : 'private'));
|
|
379
379
|
|
|
380
380
|
const spinner = ora('Uploading file...').start();
|
|
@@ -394,27 +394,27 @@ async function fileUpload(bucketName, localPath, options = {}) {
|
|
|
394
394
|
);
|
|
395
395
|
|
|
396
396
|
spinner.succeed(chalk.green('✓ File uploaded successfully!'));
|
|
397
|
-
|
|
397
|
+
|
|
398
398
|
console.log(chalk.cyan('\n📄 File Details:'));
|
|
399
399
|
console.log(chalk.white(' Name: '), chalk.yellow(response.file.file_name));
|
|
400
400
|
console.log(chalk.white(' Key: '), chalk.gray(response.file.file_key));
|
|
401
401
|
console.log(chalk.white(' Size: '), chalk.yellow(response.file.file_size));
|
|
402
402
|
console.log(chalk.white(' Type: '), chalk.yellow(response.file.mime_type));
|
|
403
403
|
console.log(chalk.white(' Visibility: '), chalk.yellow(response.file.visibility));
|
|
404
|
-
|
|
404
|
+
|
|
405
405
|
if (response.file.download_url) {
|
|
406
406
|
console.log(chalk.cyan('\n🔗 Download URL (valid for 60 minutes):'));
|
|
407
407
|
console.log(chalk.gray(response.file.download_url));
|
|
408
408
|
}
|
|
409
|
-
|
|
409
|
+
|
|
410
410
|
console.log(chalk.cyan('\n💡 Next Steps:'));
|
|
411
|
-
console.log(chalk.white(' List files: '), chalk.yellow(`
|
|
412
|
-
console.log(chalk.white(' Download: '), chalk.yellow(`
|
|
411
|
+
console.log(chalk.white(' List files: '), chalk.yellow(`orcapt storage files ${bucketName}`));
|
|
412
|
+
console.log(chalk.white(' Download: '), chalk.yellow(`orcapt storage download ${bucketName} ${response.file.file_key}`));
|
|
413
413
|
console.log('');
|
|
414
414
|
|
|
415
415
|
} catch (error) {
|
|
416
416
|
spinner.fail(chalk.red('✗ Upload failed'));
|
|
417
|
-
|
|
417
|
+
|
|
418
418
|
if (error.response) {
|
|
419
419
|
console.log(chalk.red(`\n✗ ${error.response.message || 'Unknown error'}`));
|
|
420
420
|
if (error.statusCode === 404) {
|
|
@@ -469,7 +469,7 @@ async function fileDownload(bucketName, fileKey, localPath) {
|
|
|
469
469
|
const httpModule = isHttps ? https : http;
|
|
470
470
|
|
|
471
471
|
const fileWriter = fs.createWriteStream(outputPath);
|
|
472
|
-
|
|
472
|
+
|
|
473
473
|
httpModule.get(downloadUrl, (res) => {
|
|
474
474
|
if (res.statusCode !== 200) {
|
|
475
475
|
reject(new Error(`Failed to download: ${res.statusCode}`));
|
|
@@ -483,18 +483,18 @@ async function fileDownload(bucketName, fileKey, localPath) {
|
|
|
483
483
|
resolve();
|
|
484
484
|
});
|
|
485
485
|
}).on('error', (err) => {
|
|
486
|
-
fs.unlink(outputPath, () => {});
|
|
486
|
+
fs.unlink(outputPath, () => { });
|
|
487
487
|
reject(err);
|
|
488
488
|
});
|
|
489
489
|
|
|
490
490
|
fileWriter.on('error', (err) => {
|
|
491
|
-
fs.unlink(outputPath, () => {});
|
|
491
|
+
fs.unlink(outputPath, () => { });
|
|
492
492
|
reject(err);
|
|
493
493
|
});
|
|
494
494
|
});
|
|
495
495
|
|
|
496
496
|
spinner.succeed(chalk.green('✓ File downloaded successfully!'));
|
|
497
|
-
|
|
497
|
+
|
|
498
498
|
console.log(chalk.cyan('\n📄 File Details:'));
|
|
499
499
|
console.log(chalk.white(' Name: '), chalk.yellow(response.file.file_name));
|
|
500
500
|
console.log(chalk.white(' Size: '), chalk.yellow(formatBytes(response.file.file_size_bytes)));
|
|
@@ -504,7 +504,7 @@ async function fileDownload(bucketName, fileKey, localPath) {
|
|
|
504
504
|
|
|
505
505
|
} catch (error) {
|
|
506
506
|
spinner.fail(chalk.red('✗ Download failed'));
|
|
507
|
-
|
|
507
|
+
|
|
508
508
|
if (error.response) {
|
|
509
509
|
console.log(chalk.red(`\n✗ ${error.response.message || 'Unknown error'}`));
|
|
510
510
|
if (error.statusCode === 404) {
|
|
@@ -550,17 +550,17 @@ async function bucketInfo(bucketName) {
|
|
|
550
550
|
console.log(chalk.white(' Total Size: '), chalk.cyan(bucket.total_size));
|
|
551
551
|
console.log(chalk.white(' Versioning: '), bucket.versioning_enabled ? chalk.green('Enabled') : chalk.gray('Disabled'));
|
|
552
552
|
console.log(chalk.white(' Encryption: '), bucket.encryption_enabled ? chalk.green(`Enabled (${bucket.encryption_type})`) : chalk.gray('Disabled'));
|
|
553
|
-
|
|
553
|
+
|
|
554
554
|
if (bucket.description) {
|
|
555
555
|
console.log(chalk.white(' Description: '), chalk.gray(bucket.description));
|
|
556
556
|
}
|
|
557
|
-
|
|
557
|
+
|
|
558
558
|
console.log(chalk.white(' Created: '), chalk.gray(new Date(bucket.created_at).toLocaleString()));
|
|
559
559
|
console.log('');
|
|
560
560
|
|
|
561
561
|
} catch (error) {
|
|
562
562
|
spinner.fail(chalk.red('✗ Failed to get bucket info'));
|
|
563
|
-
|
|
563
|
+
|
|
564
564
|
if (error.response) {
|
|
565
565
|
console.log(chalk.red(`\n✗ ${error.response.message || 'Unknown error'}`));
|
|
566
566
|
if (error.statusCode === 404) {
|
|
@@ -586,7 +586,7 @@ async function bucketDelete(bucketName, options = {}) {
|
|
|
586
586
|
|
|
587
587
|
console.log(chalk.white('Bucket: '), chalk.yellow(bucketName));
|
|
588
588
|
console.log(chalk.white('Workspace:'), chalk.yellow(credentials.workspace));
|
|
589
|
-
|
|
589
|
+
|
|
590
590
|
if (options.force) {
|
|
591
591
|
console.log(chalk.yellow('\n⚠️ Force delete enabled - all files will be deleted'));
|
|
592
592
|
}
|
|
@@ -594,9 +594,9 @@ async function bucketDelete(bucketName, options = {}) {
|
|
|
594
594
|
const spinner = ora('Deleting bucket...').start();
|
|
595
595
|
|
|
596
596
|
try {
|
|
597
|
-
const endpoint = API_ENDPOINTS.STORAGE_BUCKET_LIST.replace('/list', `/${bucketName}`) +
|
|
598
|
-
|
|
599
|
-
|
|
597
|
+
const endpoint = API_ENDPOINTS.STORAGE_BUCKET_LIST.replace('/list', `/${bucketName}`) +
|
|
598
|
+
(options.force ? '?force=true' : '');
|
|
599
|
+
|
|
600
600
|
await makeApiRequest('DELETE', endpoint, credentials);
|
|
601
601
|
|
|
602
602
|
spinner.succeed(chalk.green('✓ Bucket deleted successfully!'));
|
|
@@ -604,7 +604,7 @@ async function bucketDelete(bucketName, options = {}) {
|
|
|
604
604
|
|
|
605
605
|
} catch (error) {
|
|
606
606
|
spinner.fail(chalk.red('✗ Failed to delete bucket'));
|
|
607
|
-
|
|
607
|
+
|
|
608
608
|
if (error.response) {
|
|
609
609
|
console.log(chalk.red(`\n✗ ${error.response.message || 'Unknown error'}`));
|
|
610
610
|
if (error.statusCode === 404) {
|
|
@@ -612,7 +612,7 @@ async function bucketDelete(bucketName, options = {}) {
|
|
|
612
612
|
} else if (error.statusCode === 400 && error.response.file_count) {
|
|
613
613
|
console.log(chalk.yellow(` Bucket contains ${error.response.file_count} file(s)`));
|
|
614
614
|
console.log(chalk.cyan(' Use --force to delete anyway:'));
|
|
615
|
-
console.log(chalk.white(' '), chalk.yellow(`
|
|
615
|
+
console.log(chalk.white(' '), chalk.yellow(`orcapt storage bucket delete ${bucketName} --force`));
|
|
616
616
|
}
|
|
617
617
|
} else {
|
|
618
618
|
console.log(chalk.red(`\n✗ ${error.message}`));
|
|
@@ -642,7 +642,7 @@ async function fileList(bucketName, options = {}) {
|
|
|
642
642
|
try {
|
|
643
643
|
let endpoint = API_ENDPOINTS.STORAGE_FILE_LIST.replace('{bucketName}', bucketName);
|
|
644
644
|
const params = [];
|
|
645
|
-
|
|
645
|
+
|
|
646
646
|
if (options.folder) {
|
|
647
647
|
params.push(`folder_path=${encodeURIComponent(options.folder)}`);
|
|
648
648
|
}
|
|
@@ -652,7 +652,7 @@ async function fileList(bucketName, options = {}) {
|
|
|
652
652
|
if (options.perPage) {
|
|
653
653
|
params.push(`per_page=${options.perPage}`);
|
|
654
654
|
}
|
|
655
|
-
|
|
655
|
+
|
|
656
656
|
if (params.length > 0) {
|
|
657
657
|
endpoint += '?' + params.join('&');
|
|
658
658
|
}
|
|
@@ -664,7 +664,7 @@ async function fileList(bucketName, options = {}) {
|
|
|
664
664
|
if (response.pagination.total === 0) {
|
|
665
665
|
console.log(chalk.yellow('\n📭 No files found'));
|
|
666
666
|
console.log(chalk.cyan('\n💡 Upload a file:'));
|
|
667
|
-
console.log(chalk.white(' '), chalk.yellow(`
|
|
667
|
+
console.log(chalk.white(' '), chalk.yellow(`orcapt storage upload ${bucketName} <file-path>`));
|
|
668
668
|
console.log('');
|
|
669
669
|
return;
|
|
670
670
|
}
|
|
@@ -681,12 +681,12 @@ async function fileList(bucketName, options = {}) {
|
|
|
681
681
|
console.log(chalk.white('─'.repeat(120)));
|
|
682
682
|
|
|
683
683
|
response.files.forEach(file => {
|
|
684
|
-
const name = (file.file_name.length > 38
|
|
685
|
-
? file.file_name.substring(0, 35) + '...'
|
|
684
|
+
const name = (file.file_name.length > 38
|
|
685
|
+
? file.file_name.substring(0, 35) + '...'
|
|
686
686
|
: file.file_name).padEnd(40);
|
|
687
687
|
const size = file.file_size.padEnd(15);
|
|
688
|
-
const type = (file.mime_type.length > 18
|
|
689
|
-
? file.mime_type.substring(0, 15) + '...'
|
|
688
|
+
const type = (file.mime_type.length > 18
|
|
689
|
+
? file.mime_type.substring(0, 15) + '...'
|
|
690
690
|
: file.mime_type).padEnd(20);
|
|
691
691
|
const downloads = String(file.download_count).padEnd(12);
|
|
692
692
|
const uploaded = new Date(file.uploaded_at).toLocaleDateString();
|
|
@@ -701,19 +701,19 @@ async function fileList(bucketName, options = {}) {
|
|
|
701
701
|
});
|
|
702
702
|
|
|
703
703
|
console.log(chalk.white('─'.repeat(120)));
|
|
704
|
-
|
|
704
|
+
|
|
705
705
|
if (response.pagination.last_page > 1) {
|
|
706
706
|
console.log(chalk.gray(`Page ${response.pagination.current_page} of ${response.pagination.last_page}`));
|
|
707
707
|
if (response.pagination.current_page < response.pagination.last_page) {
|
|
708
|
-
console.log(chalk.cyan('Next page: '), chalk.yellow(`
|
|
708
|
+
console.log(chalk.cyan('Next page: '), chalk.yellow(`orcapt storage files ${bucketName} --page ${response.pagination.current_page + 1}`));
|
|
709
709
|
}
|
|
710
710
|
}
|
|
711
|
-
|
|
711
|
+
|
|
712
712
|
console.log('');
|
|
713
713
|
|
|
714
714
|
} catch (error) {
|
|
715
715
|
spinner.fail(chalk.red('✗ Failed to list files'));
|
|
716
|
-
|
|
716
|
+
|
|
717
717
|
if (error.response) {
|
|
718
718
|
console.log(chalk.red(`\n✗ ${error.response.message || 'Unknown error'}`));
|
|
719
719
|
if (error.statusCode === 404) {
|
|
@@ -755,79 +755,11 @@ async function fileDelete(bucketName, fileKey) {
|
|
|
755
755
|
|
|
756
756
|
} catch (error) {
|
|
757
757
|
spinner.fail(chalk.red('✗ Failed to delete file'));
|
|
758
|
-
|
|
759
|
-
if (error.response) {
|
|
760
|
-
console.log(chalk.red(`\n✗ ${error.response.message || 'Unknown error'}`));
|
|
761
|
-
if (error.statusCode === 404) {
|
|
762
|
-
console.log(chalk.yellow(' File or bucket not found'));
|
|
763
|
-
}
|
|
764
|
-
} else {
|
|
765
|
-
console.log(chalk.red(`\n✗ ${error.message}`));
|
|
766
|
-
}
|
|
767
|
-
console.log('');
|
|
768
|
-
process.exit(1);
|
|
769
|
-
}
|
|
770
|
-
}
|
|
771
758
|
|
|
772
|
-
/**
|
|
773
|
-
* Permission Add Command
|
|
774
|
-
*/
|
|
775
|
-
async function permissionAdd(bucketName, options = {}) {
|
|
776
|
-
console.log(chalk.cyan('\n============================================================'));
|
|
777
|
-
console.log(chalk.cyan('🔐 Adding Permission'));
|
|
778
|
-
console.log(chalk.cyan('============================================================\n'));
|
|
779
|
-
|
|
780
|
-
const credentials = requireAuth();
|
|
781
|
-
|
|
782
|
-
console.log(chalk.white('Bucket: '), chalk.yellow(bucketName));
|
|
783
|
-
console.log(chalk.white('Target Type: '), chalk.yellow(options.targetType || 'user'));
|
|
784
|
-
console.log(chalk.white('Target ID: '), chalk.yellow(options.targetId || 'N/A'));
|
|
785
|
-
console.log(chalk.white('Resource Type:'), chalk.yellow(options.resourceType || 'bucket'));
|
|
786
|
-
|
|
787
|
-
const spinner = ora('Adding permission...').start();
|
|
788
|
-
|
|
789
|
-
try {
|
|
790
|
-
const requestBody = {
|
|
791
|
-
target_type: options.targetType || 'user',
|
|
792
|
-
target_id: options.targetId,
|
|
793
|
-
resource_type: options.resourceType || 'bucket',
|
|
794
|
-
resource_path: options.resourcePath || null,
|
|
795
|
-
can_read: options.read || false,
|
|
796
|
-
can_write: options.write || false,
|
|
797
|
-
can_delete: options.delete || false,
|
|
798
|
-
can_list: options.list || false,
|
|
799
|
-
valid_until: options.validUntil || null,
|
|
800
|
-
reason: options.reason || null
|
|
801
|
-
};
|
|
802
|
-
|
|
803
|
-
const endpoint = API_ENDPOINTS.STORAGE_PERMISSION_ADD
|
|
804
|
-
.replace('{bucketName}', bucketName);
|
|
805
|
-
|
|
806
|
-
const response = await makeApiRequest('POST', endpoint, credentials, requestBody);
|
|
807
|
-
|
|
808
|
-
spinner.succeed(chalk.green('✓ Permission added successfully!'));
|
|
809
|
-
|
|
810
|
-
console.log(chalk.cyan('\n🔐 Permission Details:'));
|
|
811
|
-
console.log(chalk.white(' ID: '), chalk.yellow(response.permission.id));
|
|
812
|
-
console.log(chalk.white(' Target: '), chalk.yellow(`${response.permission.target_type}:${response.permission.target_id || 'all'}`));
|
|
813
|
-
console.log(chalk.white(' Resource: '), chalk.yellow(`${response.permission.resource_type}:${response.permission.resource_path || 'all'}`));
|
|
814
|
-
console.log(chalk.white(' Permissions: '), chalk.green(response.permission.permissions.join(', ')));
|
|
815
|
-
|
|
816
|
-
if (response.permission.valid_until) {
|
|
817
|
-
console.log(chalk.white(' Valid Until: '), chalk.gray(new Date(response.permission.valid_until).toLocaleString()));
|
|
818
|
-
}
|
|
819
|
-
|
|
820
|
-
console.log('');
|
|
821
|
-
|
|
822
|
-
} catch (error) {
|
|
823
|
-
spinner.fail(chalk.red('✗ Failed to add permission'));
|
|
824
|
-
|
|
825
759
|
if (error.response) {
|
|
826
760
|
console.log(chalk.red(`\n✗ ${error.response.message || 'Unknown error'}`));
|
|
827
761
|
if (error.statusCode === 404) {
|
|
828
|
-
console.log(chalk.yellow('
|
|
829
|
-
} else if (error.statusCode === 422) {
|
|
830
|
-
console.log(chalk.yellow(' Invalid permission parameters'));
|
|
762
|
+
console.log(chalk.yellow(' File or bucket not found'));
|
|
831
763
|
}
|
|
832
764
|
} else {
|
|
833
765
|
console.log(chalk.red(`\n✗ ${error.message}`));
|
|
@@ -837,65 +769,6 @@ async function permissionAdd(bucketName, options = {}) {
|
|
|
837
769
|
}
|
|
838
770
|
}
|
|
839
771
|
|
|
840
|
-
/**
|
|
841
|
-
* Permission List Command
|
|
842
|
-
*/
|
|
843
|
-
async function permissionList(bucketName) {
|
|
844
|
-
console.log(chalk.cyan('\n============================================================'));
|
|
845
|
-
console.log(chalk.cyan('🔐 Listing Permissions'));
|
|
846
|
-
console.log(chalk.cyan('============================================================\n'));
|
|
847
|
-
|
|
848
|
-
const credentials = requireAuth();
|
|
849
|
-
console.log(chalk.white('Bucket:'), chalk.yellow(bucketName));
|
|
850
|
-
|
|
851
|
-
const spinner = ora('Fetching permissions...').start();
|
|
852
|
-
|
|
853
|
-
try {
|
|
854
|
-
const endpoint = API_ENDPOINTS.STORAGE_PERMISSION_LIST
|
|
855
|
-
.replace('{bucketName}', bucketName);
|
|
856
|
-
|
|
857
|
-
const response = await makeApiRequest('GET', endpoint, credentials);
|
|
858
|
-
|
|
859
|
-
spinner.succeed(chalk.green(`✓ Found ${response.count} permission(s)`));
|
|
860
|
-
|
|
861
|
-
if (response.count === 0) {
|
|
862
|
-
console.log(chalk.yellow('\n📭 No permissions found'));
|
|
863
|
-
console.log(chalk.cyan('\n💡 Add a permission:'));
|
|
864
|
-
console.log(chalk.white(' '), chalk.yellow(`orca storage permission add ${bucketName} --target-type user --target-id USER_ID --read`));
|
|
865
|
-
console.log('');
|
|
866
|
-
return;
|
|
867
|
-
}
|
|
868
|
-
|
|
869
|
-
console.log('');
|
|
870
|
-
response.permissions.forEach(perm => {
|
|
871
|
-
const statusIcon = perm.is_valid ? '✓' : '✗';
|
|
872
|
-
const statusColor = perm.is_valid ? chalk.green : chalk.red;
|
|
873
|
-
|
|
874
|
-
console.log(statusColor(`${statusIcon} Permission #${perm.id}`));
|
|
875
|
-
console.log(chalk.white(' Target: '), chalk.yellow(`${perm.target_type}:${perm.target_id || 'all'}`));
|
|
876
|
-
console.log(chalk.white(' Resource: '), chalk.yellow(`${perm.resource_type}:${perm.resource_path || 'all'}`));
|
|
877
|
-
console.log(chalk.white(' Actions: '), chalk.green(perm.permissions.join(', ')));
|
|
878
|
-
console.log(chalk.white(' Status: '), statusColor(perm.status));
|
|
879
|
-
|
|
880
|
-
if (perm.valid_until) {
|
|
881
|
-
console.log(chalk.white(' Valid Until:'), chalk.gray(new Date(perm.valid_until).toLocaleString()));
|
|
882
|
-
}
|
|
883
|
-
|
|
884
|
-
console.log('');
|
|
885
|
-
});
|
|
886
|
-
|
|
887
|
-
} catch (error) {
|
|
888
|
-
spinner.fail(chalk.red('✗ Failed to list permissions'));
|
|
889
|
-
|
|
890
|
-
if (error.response) {
|
|
891
|
-
console.log(chalk.red(`\n✗ ${error.response.message || 'Unknown error'}\n`));
|
|
892
|
-
} else {
|
|
893
|
-
console.log(chalk.red(`\n✗ ${error.message}\n`));
|
|
894
|
-
}
|
|
895
|
-
process.exit(1);
|
|
896
|
-
}
|
|
897
|
-
}
|
|
898
|
-
|
|
899
772
|
module.exports = {
|
|
900
773
|
bucketCreate,
|
|
901
774
|
bucketList,
|
|
@@ -904,8 +777,6 @@ module.exports = {
|
|
|
904
777
|
fileUpload,
|
|
905
778
|
fileDownload,
|
|
906
779
|
fileList,
|
|
907
|
-
fileDelete
|
|
908
|
-
permissionAdd,
|
|
909
|
-
permissionList
|
|
780
|
+
fileDelete
|
|
910
781
|
};
|
|
911
782
|
|
package/src/commands/ui.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* Manage
|
|
2
|
+
* orcapt UI Commands
|
|
3
|
+
* Manage orcapt UI installation and execution
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
const chalk = require('chalk');
|
|
@@ -12,7 +12,7 @@ const os = require('os');
|
|
|
12
12
|
const { ensurePortAvailable } = require('../utils');
|
|
13
13
|
|
|
14
14
|
// Track UI installation status
|
|
15
|
-
const UI_CONFIG_FILE = path.join(os.homedir(), '.
|
|
15
|
+
const UI_CONFIG_FILE = path.join(os.homedir(), '.orcapt', 'ui-config.json');
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Check if npx is available (we'll use npx instead of global install to avoid conflicts)
|
|
@@ -88,17 +88,17 @@ function isUIInstalled() {
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
/**
|
|
91
|
-
* UI Init Command - Install
|
|
91
|
+
* UI Init Command - Install orcapt UI globally
|
|
92
92
|
*/
|
|
93
93
|
async function uiInit() {
|
|
94
94
|
console.log(chalk.cyan('\n============================================================'));
|
|
95
|
-
console.log(chalk.cyan('📦
|
|
95
|
+
console.log(chalk.cyan('📦 orcapt UI - Global Installation'));
|
|
96
96
|
console.log(chalk.cyan('============================================================\n'));
|
|
97
97
|
|
|
98
98
|
// Check if already installed
|
|
99
99
|
if (isUIInstalled()) {
|
|
100
|
-
console.log(chalk.yellow('⚠
|
|
101
|
-
console.log(chalk.cyan('\nTo reinstall, run:'), chalk.white('
|
|
100
|
+
console.log(chalk.yellow('⚠ orcapt UI is already installed globally'));
|
|
101
|
+
console.log(chalk.cyan('\nTo reinstall, run:'), chalk.white('orcapt ui remove'), chalk.cyan('first\n'));
|
|
102
102
|
return;
|
|
103
103
|
}
|
|
104
104
|
|
|
@@ -111,7 +111,7 @@ async function uiInit() {
|
|
|
111
111
|
});
|
|
112
112
|
|
|
113
113
|
if (result.status === 0) {
|
|
114
|
-
spinner.succeed(chalk.green('
|
|
114
|
+
spinner.succeed(chalk.green('orcapt UI installed successfully!'));
|
|
115
115
|
saveUIConfig(true);
|
|
116
116
|
|
|
117
117
|
console.log(chalk.cyan('\n============================================================'));
|
|
@@ -120,7 +120,7 @@ async function uiInit() {
|
|
|
120
120
|
console.log(chalk.white('\n📦 Package:'), chalk.yellow('@orcapt/ui'));
|
|
121
121
|
console.log(chalk.white('📁 Type:'), chalk.white('React component library with built UI'));
|
|
122
122
|
console.log(chalk.white('\nYou can now run:'));
|
|
123
|
-
console.log(chalk.yellow(' •
|
|
123
|
+
console.log(chalk.yellow(' • orcapt ui start --port 3000 --agent-port 5001'));
|
|
124
124
|
console.log(chalk.cyan('============================================================\n'));
|
|
125
125
|
} else {
|
|
126
126
|
spinner.fail(chalk.red('Installation failed'));
|
|
@@ -136,21 +136,21 @@ async function uiInit() {
|
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
/**
|
|
139
|
-
* UI Start Command - Run the
|
|
139
|
+
* UI Start Command - Run the orcapt UI
|
|
140
140
|
*/
|
|
141
141
|
async function uiStart(options) {
|
|
142
142
|
const port = options.port || '3000';
|
|
143
143
|
const agentPort = options.agentPort || '5001';
|
|
144
144
|
|
|
145
145
|
console.log(chalk.cyan('\n============================================================'));
|
|
146
|
-
console.log(chalk.cyan('🚀 Starting
|
|
146
|
+
console.log(chalk.cyan('🚀 Starting orcapt UI'));
|
|
147
147
|
console.log(chalk.cyan('============================================================\n'));
|
|
148
148
|
|
|
149
149
|
const isInstalled = isUIInstalled();
|
|
150
150
|
|
|
151
151
|
if (!isInstalled && !isNpxAvailable()) {
|
|
152
|
-
console.log(chalk.red('✗
|
|
153
|
-
console.log(chalk.yellow('\nPlease run:'), chalk.white('
|
|
152
|
+
console.log(chalk.red('✗ orcapt UI is not installed and npx is not available'));
|
|
153
|
+
console.log(chalk.yellow('\nPlease run:'), chalk.white('orcapt ui init'), chalk.yellow('to install\n'));
|
|
154
154
|
process.exit(1);
|
|
155
155
|
}
|
|
156
156
|
|
|
@@ -184,7 +184,7 @@ async function uiStart(options) {
|
|
|
184
184
|
|
|
185
185
|
if (!fs.existsSync(uiDistPath)) {
|
|
186
186
|
console.log(chalk.red(`\n✗ @orcapt/ui is installed but dist folder not found at: ${uiDistPath}`));
|
|
187
|
-
console.log(chalk.yellow('\nTry reinstalling:'), chalk.white('
|
|
187
|
+
console.log(chalk.yellow('\nTry reinstalling:'), chalk.white('orcapt ui remove && orcapt ui init\n'));
|
|
188
188
|
process.exit(1);
|
|
189
189
|
}
|
|
190
190
|
}
|
|
@@ -192,7 +192,7 @@ async function uiStart(options) {
|
|
|
192
192
|
|
|
193
193
|
if (!uiDistPath) {
|
|
194
194
|
console.log(chalk.red('\n✗ Could not find @orcapt/ui installation'));
|
|
195
|
-
console.log(chalk.yellow('\nPlease run:'), chalk.white('
|
|
195
|
+
console.log(chalk.yellow('\nPlease run:'), chalk.white('orcapt ui init\n'));
|
|
196
196
|
process.exit(1);
|
|
197
197
|
}
|
|
198
198
|
|
|
@@ -221,7 +221,7 @@ async function uiStart(options) {
|
|
|
221
221
|
// Handle Ctrl+C gracefully
|
|
222
222
|
process.on('SIGINT', () => {
|
|
223
223
|
console.log(chalk.cyan('\n\n============================================================'));
|
|
224
|
-
console.log(chalk.yellow('⚠ Stopping
|
|
224
|
+
console.log(chalk.yellow('⚠ Stopping orcapt UI...'));
|
|
225
225
|
console.log(chalk.cyan('============================================================\n'));
|
|
226
226
|
uiProcess.kill('SIGINT');
|
|
227
227
|
process.exit(0);
|
|
@@ -234,16 +234,16 @@ async function uiStart(options) {
|
|
|
234
234
|
}
|
|
235
235
|
|
|
236
236
|
/**
|
|
237
|
-
* UI Remove Command - Uninstall
|
|
237
|
+
* UI Remove Command - Uninstall orcapt UI
|
|
238
238
|
*/
|
|
239
239
|
async function uiRemove() {
|
|
240
240
|
console.log(chalk.cyan('\n============================================================'));
|
|
241
|
-
console.log(chalk.cyan('🗑️ Removing
|
|
241
|
+
console.log(chalk.cyan('🗑️ Removing orcapt UI'));
|
|
242
242
|
console.log(chalk.cyan('============================================================\n'));
|
|
243
243
|
|
|
244
244
|
// Check if installed
|
|
245
245
|
if (!isUIInstalled()) {
|
|
246
|
-
console.log(chalk.yellow('⚠
|
|
246
|
+
console.log(chalk.yellow('⚠ orcapt UI is not installed globally\n'));
|
|
247
247
|
return;
|
|
248
248
|
}
|
|
249
249
|
|
|
@@ -256,14 +256,14 @@ async function uiRemove() {
|
|
|
256
256
|
});
|
|
257
257
|
|
|
258
258
|
if (result.status === 0) {
|
|
259
|
-
spinner.succeed(chalk.green('
|
|
259
|
+
spinner.succeed(chalk.green('orcapt UI removed successfully!'));
|
|
260
260
|
saveUIConfig(false);
|
|
261
261
|
|
|
262
262
|
console.log(chalk.cyan('\n============================================================'));
|
|
263
263
|
console.log(chalk.green('✓ Uninstallation Complete'));
|
|
264
264
|
console.log(chalk.cyan('============================================================'));
|
|
265
265
|
console.log(chalk.white('\n@orcapt/ui package has been removed.'));
|
|
266
|
-
console.log(chalk.white('\nTo reinstall, run:'), chalk.yellow('
|
|
266
|
+
console.log(chalk.white('\nTo reinstall, run:'), chalk.yellow('orcapt ui init'));
|
|
267
267
|
console.log(chalk.cyan('============================================================\n'));
|
|
268
268
|
} else {
|
|
269
269
|
spinner.fail(chalk.red('Uninstallation failed'));
|
package/src/utils/index.js
CHANGED