para-cli 1.18.7 → 1.19.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/README.md +30 -6
- package/index.js +140 -13
- package/package.json +7 -7
- package/para-cli.js +21 -3
package/README.md
CHANGED
|
@@ -17,9 +17,9 @@ This is the command-line tool for interacting with a Para server.
|
|
|
17
17
|
## Installation
|
|
18
18
|
|
|
19
19
|
```sh
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
npm install -g para-cli
|
|
21
|
+
para-cli setup
|
|
22
|
+
para-cli ping
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
## Usage
|
|
@@ -41,6 +41,7 @@ $ para-cli ping
|
|
|
41
41
|
setup Initial setup, prompts you to enter your Para API keys and endpoint
|
|
42
42
|
apps Returns a list of all Para apps
|
|
43
43
|
select <appid> Selects a Para app as a target for all subsequent read/write requests.
|
|
44
|
+
endpoints [add|remove] List and select Para server endpoints, add new or remove an exiting one.
|
|
44
45
|
create <file|glob> [--id] [--type] Persists files as Para objects and makes them searchable
|
|
45
46
|
read --id 123 [--id 345 ...] Fetches objects with the given ids
|
|
46
47
|
update <file.json|glob> ... Updates Para objects with the data from a JSON file (must contain id field)
|
|
@@ -83,6 +84,9 @@ $ para-cli ping
|
|
|
83
84
|
$ para-cli search "*" --type article --page all
|
|
84
85
|
$ para-cli new-key
|
|
85
86
|
$ para-cli new-app "mynewapp" --name "Full app name"
|
|
87
|
+
$ para-cli apps
|
|
88
|
+
$ para-cli select scoold
|
|
89
|
+
$ para-cli endpoints
|
|
86
90
|
|
|
87
91
|
```
|
|
88
92
|
|
|
@@ -95,7 +99,7 @@ The plan is to add more functionality in the near future.
|
|
|
95
99
|
|
|
96
100
|
**Quick start:**
|
|
97
101
|
```
|
|
98
|
-
|
|
102
|
+
para-cli setup
|
|
99
103
|
```
|
|
100
104
|
|
|
101
105
|
The configuration file is located in `~/.config/para-cli-nodejs/config.json` and contains the keys used to authenticate
|
|
@@ -115,12 +119,32 @@ Here's an example `config.json` file:
|
|
|
115
119
|
Once configured you can test your connection to the server:
|
|
116
120
|
|
|
117
121
|
```
|
|
118
|
-
|
|
122
|
+
para-cli ping
|
|
119
123
|
```
|
|
120
124
|
|
|
121
125
|
To get the currently authenticated app/user object run:
|
|
122
126
|
```
|
|
123
|
-
|
|
127
|
+
para-cli me
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Switching between apps and endpoints
|
|
131
|
+
|
|
132
|
+
Para CLI can be configured to work with multiple Para servers and apps. Here's how to add additional Para server endpoints:
|
|
133
|
+
```
|
|
134
|
+
para-cli endpoints add
|
|
135
|
+
```
|
|
136
|
+
To select a specific endpoint run:
|
|
137
|
+
```
|
|
138
|
+
para-cli endpoints
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
After selecting the Para server you wish to connect to, you can list and select apps within it:
|
|
142
|
+
```
|
|
143
|
+
para-cli apps
|
|
144
|
+
```
|
|
145
|
+
Select the 'scoold' app, for example:
|
|
146
|
+
```
|
|
147
|
+
para-cli select scoold
|
|
124
148
|
```
|
|
125
149
|
|
|
126
150
|
## Para Docs
|
package/index.js
CHANGED
|
@@ -38,6 +38,7 @@ import { globbySync } from 'globby';
|
|
|
38
38
|
import chalk from 'chalk';
|
|
39
39
|
import { Promise } from 'rsvp';
|
|
40
40
|
import apiClient from 'superagent';
|
|
41
|
+
import { URL } from 'url';
|
|
41
42
|
import { ParaClient, ParaObject, Pager } from 'para-client-js';
|
|
42
43
|
|
|
43
44
|
const { cyan, red, yellow, green } = chalk;
|
|
@@ -56,7 +57,7 @@ export function setup(config) {
|
|
|
56
57
|
rl.question(cyan.bold('Para Access Key: '), function (accessKey) {
|
|
57
58
|
rl.question(cyan.bold('Para Secret Key: '), function (secretKey) {
|
|
58
59
|
rl.question(cyan.bold('Para Endpoint: '), function (endpoint) {
|
|
59
|
-
var access = (accessKey || config.get('accessKey')).trim();
|
|
60
|
+
var access = (accessKey || config.get('accessKey') || "app:para").trim();
|
|
60
61
|
var secret = (secretKey || config.get('secretKey')).trim();
|
|
61
62
|
var endpoint = (endpoint || config.get('endpoint')).trim();
|
|
62
63
|
newJWT(access, secret, endpoint, config);
|
|
@@ -427,9 +428,10 @@ export function rebuildIndex(pc, config, flags) {
|
|
|
427
428
|
}
|
|
428
429
|
|
|
429
430
|
export function listApps(config, flags, parentAccessKey, failureCallback) {
|
|
430
|
-
var
|
|
431
|
-
var
|
|
432
|
-
var
|
|
431
|
+
var selectedEndpoint = getSelectedEndpoint(config, flags);
|
|
432
|
+
var accessKey = selectedEndpoint.accessKey;
|
|
433
|
+
var secretKey = selectedEndpoint.secretKey;
|
|
434
|
+
var endpoint = selectedEndpoint.endpoint;
|
|
433
435
|
var pc = new ParaClient(accessKey, secretKey, {endpoint: endpoint});
|
|
434
436
|
var p = new Pager();
|
|
435
437
|
var results = [];
|
|
@@ -440,7 +442,7 @@ export function listApps(config, flags, parentAccessKey, failureCallback) {
|
|
|
440
442
|
}).then(function () {
|
|
441
443
|
var apps = results.map(function (app) {return app.appIdentifier.trim();});
|
|
442
444
|
if (apps.length) {
|
|
443
|
-
console.log('Found', p.count, 'apps:', yellow('[') + green(apps.join(yellow('] ['))) + yellow(']'));
|
|
445
|
+
console.log('Found', p.count, 'apps on ' + cyan(endpoint) + ':', yellow('[') + green(apps.join(yellow('] ['))) + yellow(']'));
|
|
444
446
|
console.log('Typing', cyan('para-cli select'), green(apps[0]), 'will switch to that app. Current app:',
|
|
445
447
|
green(parentAccessKey));
|
|
446
448
|
process.exit(0);
|
|
@@ -452,9 +454,11 @@ export function listApps(config, flags, parentAccessKey, failureCallback) {
|
|
|
452
454
|
});
|
|
453
455
|
}
|
|
454
456
|
|
|
455
|
-
export function selectApp(
|
|
456
|
-
var
|
|
457
|
-
var
|
|
457
|
+
export function selectApp(input, config, flags) {
|
|
458
|
+
var selectedEndpoint = getSelectedEndpoint(config, flags);
|
|
459
|
+
var accessKey = selectedEndpoint.accessKey;
|
|
460
|
+
var secretKey = selectedEndpoint.secretKey;
|
|
461
|
+
var endpoint = selectedEndpoint.endpoint;
|
|
458
462
|
if (accessKey === 'app:para' && secretKey) {
|
|
459
463
|
var selectedApp = 'app:' + (input[1] || 'para').trim();
|
|
460
464
|
if (selectedApp === 'app:para') {
|
|
@@ -465,28 +469,142 @@ export function selectApp(pc, input, config, flags) {
|
|
|
465
469
|
var now = Math.round(new Date().getTime() / 1000);
|
|
466
470
|
var jwt = sign(JSON.stringify({
|
|
467
471
|
iat: now,
|
|
468
|
-
exp: now +
|
|
472
|
+
exp: now + 10,
|
|
469
473
|
appid: accessKey,
|
|
470
474
|
getCredentials: selectedApp
|
|
471
475
|
}), secretKey, { algorithm: 'HS256' });
|
|
472
|
-
|
|
473
|
-
|
|
476
|
+
var paraClient = new ParaClient(accessKey, secretKey, { endpoint: endpoint });
|
|
477
|
+
paraClient.setAccessToken(jwt);
|
|
478
|
+
paraClient.me(jwt).then(function (data) {
|
|
474
479
|
if (data && data.credentials) {
|
|
475
480
|
config.set('selectedApp', data.credentials);
|
|
476
481
|
console.log(green('✔'), 'Selected', green(selectedApp), 'as the current app.');
|
|
477
482
|
} else {
|
|
478
483
|
fail('That did not work -' + red(input[1]) + ' try updating Para to the latest version.');
|
|
479
484
|
}
|
|
480
|
-
pc.clearAccessToken();
|
|
481
485
|
}).catch(function (err) {
|
|
482
486
|
fail('App ' + red(input[1]) + ' not found!');
|
|
483
|
-
pc.clearAccessToken();
|
|
484
487
|
});
|
|
485
488
|
} else {
|
|
486
489
|
fail('This command only works when Para CLI is configured to use the keys for the root app.');
|
|
487
490
|
}
|
|
488
491
|
}
|
|
489
492
|
|
|
493
|
+
export function listEndpoints(config, flags, failureCallback) {
|
|
494
|
+
var accessKey = flags.accessKey || process.env.PARA_ACCESS_KEY || config.get('accessKey');
|
|
495
|
+
var secretKey = flags.secretKey || process.env.PARA_SECRET_KEY || config.get('secretKey');
|
|
496
|
+
var endpoint = flags.endpoint || process.env.PARA_ENDPOINT || config.get('endpoint');
|
|
497
|
+
var endpoints = config.get('endpoints') || [];
|
|
498
|
+
var list = [{endpoint: endpoint, accessKey: accessKey, secretKey: secretKey}].concat(endpoints);
|
|
499
|
+
if (list.length === 0) {
|
|
500
|
+
failureCallback();
|
|
501
|
+
return [];
|
|
502
|
+
}
|
|
503
|
+
for (var i = 0; i < list.length; i++) {
|
|
504
|
+
var ep = list[i];
|
|
505
|
+
var selected = (config.get('selectedEndpoint') || 0) === i;
|
|
506
|
+
var rootAppConfigured = ep.accessKey === 'app:para' && ep.secretKey.length > 10;
|
|
507
|
+
console.log(yellow((selected ? ' ➤' : ' '), (i + 1) + '. ') + cyan(ep.endpoint), rootAppConfigured ?
|
|
508
|
+
green('✔ root app configured') : red('root app not configured'));
|
|
509
|
+
}
|
|
510
|
+
return list;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
export function addEndpoint(config) {
|
|
514
|
+
var endpoints = config.get('endpoints') || [];
|
|
515
|
+
var rl = createInterface({
|
|
516
|
+
input: process.stdin,
|
|
517
|
+
output: process.stdout
|
|
518
|
+
});
|
|
519
|
+
rl.question(cyan.bold('Para Endpoint: '), function (endpoint) {
|
|
520
|
+
if (!isValidUrl(endpoint)) {
|
|
521
|
+
fail('Endpoint must be a valid URL.');
|
|
522
|
+
rl.close();
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
rl.question(cyan.bold('Para Secret Key (for root app app:para): '), function (secretKey) {
|
|
526
|
+
var pc = new ParaClient("app:para", secretKey, {endpoint: endpoint});
|
|
527
|
+
var endpoints = config.get('endpoints') || [];
|
|
528
|
+
var existing = false;
|
|
529
|
+
for (var i = 0; i < endpoints.length; i++) {
|
|
530
|
+
var ep = endpoints[i];
|
|
531
|
+
if (ep.endpoint === endpoint) {
|
|
532
|
+
ep.secretKey = secretKey;
|
|
533
|
+
existing = true;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
if (!existing) {
|
|
537
|
+
endpoints.push({accessKey: 'app:para', secretKey: secretKey, endpoint: endpoint});
|
|
538
|
+
}
|
|
539
|
+
config.set('endpoints', endpoints);
|
|
540
|
+
ping(pc, config);
|
|
541
|
+
rl.close();
|
|
542
|
+
});
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
export function removeEndpoint(config, flags) {
|
|
547
|
+
var list = listEndpoints(config, flags, function () {console.log('No endpoints found.');});
|
|
548
|
+
var rl = createInterface({
|
|
549
|
+
input: process.stdin,
|
|
550
|
+
output: process.stdout
|
|
551
|
+
});
|
|
552
|
+
|
|
553
|
+
rl.question(yellow.bold('Type the number of the Para endpoint to remove: '), function (index) {
|
|
554
|
+
var selectedEndpoint = 0;
|
|
555
|
+
if (!isNaN(index) && index <= list.length && index >= 1) {
|
|
556
|
+
selectedEndpoint = index - 1;
|
|
557
|
+
}
|
|
558
|
+
var url = list[selectedEndpoint].endpoint;
|
|
559
|
+
if (selectedEndpoint === 0) {
|
|
560
|
+
config.set('accessKey', 'app:para');
|
|
561
|
+
config.set('secretKey', '');
|
|
562
|
+
config.set('endpoint', defaultConfig.endpoint);
|
|
563
|
+
} else {
|
|
564
|
+
if (selectedEndpoint === config.get('selectedEndpoint')) {
|
|
565
|
+
config.delete('selectedEndpoint');
|
|
566
|
+
config.delete('selectedApp');
|
|
567
|
+
}
|
|
568
|
+
list.splice(selectedEndpoint, 1);
|
|
569
|
+
list.shift();
|
|
570
|
+
config.set('endpoints', list);
|
|
571
|
+
}
|
|
572
|
+
console.log("Removed endpoint: " + cyan(url));
|
|
573
|
+
rl.close();
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
export function selectEndpoint(config, flags) {
|
|
578
|
+
var list = listEndpoints(config, flags, function () {console.log('No endpoints found.');});
|
|
579
|
+
var rl = createInterface({
|
|
580
|
+
input: process.stdin,
|
|
581
|
+
output: process.stdout
|
|
582
|
+
});
|
|
583
|
+
rl.question(yellow.bold('Type the number of the Para endpoint to select: '), function (index) {
|
|
584
|
+
var selectedEndpoint = 0;
|
|
585
|
+
if (!isNaN(index) && index <= list.length && index >= 1) {
|
|
586
|
+
selectedEndpoint = index - 1;
|
|
587
|
+
}
|
|
588
|
+
config.delete('selectedApp');
|
|
589
|
+
config.set('selectedEndpoint', selectedEndpoint);
|
|
590
|
+
console.log("Selected endpoint: " + cyan(list[selectedEndpoint].endpoint));
|
|
591
|
+
rl.close();
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
function getSelectedEndpoint(config, flags) {
|
|
596
|
+
var accessKey = flags.accessKey || process.env.PARA_ACCESS_KEY || config.get('accessKey');
|
|
597
|
+
var secretKey = flags.secretKey || process.env.PARA_SECRET_KEY || config.get('secretKey');
|
|
598
|
+
var endpoint = flags.endpoint || process.env.PARA_ENDPOINT || config.get('endpoint');
|
|
599
|
+
var endpoints = [{endpoint: endpoint, accessKey: accessKey, secretKey: secretKey}].concat(config.get('endpoints') || []);
|
|
600
|
+
try {
|
|
601
|
+
return endpoints[config.get('selectedEndpoint') || 0];
|
|
602
|
+
} catch (e) {
|
|
603
|
+
config.delete('selectedEndpoint');
|
|
604
|
+
return endpoints[0];
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
|
|
490
608
|
function sendFileChunk(chunkId, textEncoded, json, id, flags, start, end, pc, decoder) {
|
|
491
609
|
if (start > 0 && textEncoded[start] !== 32) {
|
|
492
610
|
for (var i = 0; i < 100 && start - i >= 0; i++) {
|
|
@@ -604,6 +722,15 @@ function parseHTML(file) {
|
|
|
604
722
|
};
|
|
605
723
|
}
|
|
606
724
|
|
|
725
|
+
function isValidUrl(url) {
|
|
726
|
+
try {
|
|
727
|
+
new URL(url);
|
|
728
|
+
return true;
|
|
729
|
+
} catch (err) {
|
|
730
|
+
return false;
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
|
|
607
734
|
function readFile(filePath) {
|
|
608
735
|
return readFileSync(filePath, { encoding: 'utf8' });
|
|
609
736
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "para-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.19.1",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "Command-line tool for Para backend servers",
|
|
6
6
|
"homepage": "https://paraio.org",
|
|
@@ -24,25 +24,25 @@
|
|
|
24
24
|
"api"
|
|
25
25
|
],
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"eslint": "^8.
|
|
27
|
+
"eslint": "^8.28.0"
|
|
28
28
|
},
|
|
29
29
|
"repository": "Erudika/para-cli",
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"brace-expansion": "^2.0.1",
|
|
32
|
-
"chalk": "^5.
|
|
33
|
-
"conf": "^10.
|
|
32
|
+
"chalk": "^5.1.2",
|
|
33
|
+
"conf": "^10.2.0",
|
|
34
34
|
"exit": "^0.1.2",
|
|
35
35
|
"figlet": "^1.5.2",
|
|
36
36
|
"get-stdin": "^9.0.0",
|
|
37
37
|
"globby": "^13.1.2",
|
|
38
38
|
"htmlparser2": "^8.0.1",
|
|
39
39
|
"jsonwebtoken": "^8.5.1",
|
|
40
|
-
"meow": "^
|
|
40
|
+
"meow": "^11.0.0",
|
|
41
41
|
"mime-types": "^2.1.35",
|
|
42
|
-
"para-client-js": "^1.
|
|
42
|
+
"para-client-js": "^1.38.0",
|
|
43
43
|
"resolve": "^1.22.1",
|
|
44
44
|
"striptags": "^3.2.0",
|
|
45
45
|
"update-notifier": "^6.0.2",
|
|
46
|
-
"yargs-parser": "^21.
|
|
46
|
+
"yargs-parser": "^21.1.1"
|
|
47
47
|
}
|
|
48
48
|
}
|
package/para-cli.js
CHANGED
|
@@ -27,7 +27,10 @@ import Conf from 'conf';
|
|
|
27
27
|
import figlet from 'figlet';
|
|
28
28
|
import chalk from 'chalk';
|
|
29
29
|
import meow from 'meow';
|
|
30
|
-
import {
|
|
30
|
+
import {
|
|
31
|
+
defaultConfig, setup, listApps, selectEndpoint, addEndpoint, removeEndpoint, selectApp, createAll, readAll,
|
|
32
|
+
updateAll, deleteAll, search, newKeys, newJWT, newApp, ping, me, appSettings, rebuildIndex, exportData, importData
|
|
33
|
+
} from './index.js';
|
|
31
34
|
|
|
32
35
|
const { red, green, blue } = chalk;
|
|
33
36
|
const { textSync } = figlet;
|
|
@@ -40,6 +43,7 @@ var cli = meow(`
|
|
|
40
43
|
setup Initial setup, prompts you to enter your Para API keys and endpoint
|
|
41
44
|
apps Returns a list of all Para apps
|
|
42
45
|
select <appid> Selects a Para app as a target for all subsequent read/write requests.
|
|
46
|
+
endpoints [add|remove] List and select Para server endpoints, add new or remove an exiting one.
|
|
43
47
|
create <file|glob> [--id] [--type] Persists files as Para objects and makes them searchable
|
|
44
48
|
read --id 123 [--id 345 ...] Fetches objects with the given ids
|
|
45
49
|
update <file.json|glob> ... Updates Para objects with the data from a JSON file (must contain id field)
|
|
@@ -82,7 +86,9 @@ var cli = meow(`
|
|
|
82
86
|
$ para-cli search "*" --type article --page all
|
|
83
87
|
$ para-cli new-key
|
|
84
88
|
$ para-cli new-app "mynewapp" --name "Full app name"
|
|
85
|
-
|
|
89
|
+
$ para-cli apps
|
|
90
|
+
$ para-cli select scoold
|
|
91
|
+
$ para-cli endpoints
|
|
86
92
|
`, {
|
|
87
93
|
importMeta: import.meta,
|
|
88
94
|
flags: {
|
|
@@ -111,12 +117,14 @@ var selectedApp = config.get('selectedApp');
|
|
|
111
117
|
if (!flags.accessKey && !flags.secretKey && selectedApp && selectedApp.accessKey && selectedApp.accessKey.indexOf("app:") === 0) {
|
|
112
118
|
accessKey = selectedApp.accessKey;
|
|
113
119
|
secretKey = selectedApp.secretKey;
|
|
120
|
+
endpoint = selectedApp.endpoint;
|
|
114
121
|
}
|
|
115
122
|
|
|
116
123
|
if (!input[0]) {
|
|
117
124
|
console.log(help);
|
|
118
125
|
} else if (!accessKey || !secretKey) {
|
|
119
126
|
console.error(red('Command ' + input[0] + ' failed! Blank credentials, running setup first...'));
|
|
127
|
+
console.log("Please enter the access key and secret key for the root app 'app:para' first.");
|
|
120
128
|
process.exitCode = 1;
|
|
121
129
|
setup(config);
|
|
122
130
|
} else {
|
|
@@ -130,8 +138,18 @@ if (!input[0]) {
|
|
|
130
138
|
listApps(config, flags, accessKey, function () {console.log('No apps found within', green(accessKey));});
|
|
131
139
|
}
|
|
132
140
|
|
|
141
|
+
if (input[0] === 'endpoints') {
|
|
142
|
+
if (input.length > 1 && input[1] === 'add') {
|
|
143
|
+
addEndpoint(config);
|
|
144
|
+
} else if (input.length > 1 && input[1] === 'remove') {
|
|
145
|
+
removeEndpoint(config, flags);
|
|
146
|
+
} else {
|
|
147
|
+
selectEndpoint(config, flags);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
133
151
|
if (input[0] === 'select') {
|
|
134
|
-
selectApp(
|
|
152
|
+
selectApp(input, config, flags);
|
|
135
153
|
}
|
|
136
154
|
|
|
137
155
|
if (input[0] === 'create') {
|