para-cli 1.16.0 → 1.18.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 +1 -1
- package/README.md +3 -0
- package/index.js +90 -10
- package/package.json +9 -31
- package/para-cli.js +71 -51
package/LICENSE
CHANGED
|
@@ -187,7 +187,7 @@
|
|
|
187
187
|
same "printed page" as the copyright notice for easier
|
|
188
188
|
identification within third-party archives.
|
|
189
189
|
|
|
190
|
-
Copyright
|
|
190
|
+
Copyright 2022 Erudika LTD, https://erudika.com
|
|
191
191
|
|
|
192
192
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
193
193
|
you may not use this file except in compliance with the License.
|
package/README.md
CHANGED
|
@@ -19,6 +19,7 @@ This is the command-line tool for interacting with a Para server.
|
|
|
19
19
|
```sh
|
|
20
20
|
$ npm install -g para-cli
|
|
21
21
|
$ para-cli setup
|
|
22
|
+
$ para-cli ping
|
|
22
23
|
```
|
|
23
24
|
|
|
24
25
|
## Usage
|
|
@@ -38,6 +39,8 @@ $ para-cli setup
|
|
|
38
39
|
|
|
39
40
|
Commands:
|
|
40
41
|
setup Initial setup, prompts you to enter your Para API keys and endpoint
|
|
42
|
+
apps Returns a list of all Para apps
|
|
43
|
+
select <appid> Selects a Para app as a target for all subsequent read/write requests.
|
|
41
44
|
create <file|glob> [--id] [--type] Persists files as Para objects and makes them searchable
|
|
42
45
|
read --id 123 [--id 345 ...] Fetches objects with the given ids
|
|
43
46
|
update <file.json|glob> ... Updates Para objects with the data from a JSON file (must contain id field)
|
package/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright 2013-
|
|
2
|
+
* Copyright 2013-2022 Erudika. https://erudika.com
|
|
3
3
|
*
|
|
4
4
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
5
|
* you may not use this file except in compliance with the License.
|
|
@@ -25,7 +25,6 @@
|
|
|
25
25
|
/* eslint indent: ["error", "tab"] */
|
|
26
26
|
/* eslint object-curly-spacing: ["error", "always"] */
|
|
27
27
|
|
|
28
|
-
'use strict';
|
|
29
28
|
import { statSync, readFileSync, writeFileSync } from 'fs';
|
|
30
29
|
import { relative, basename, resolve } from 'path';
|
|
31
30
|
import { TextEncoder } from 'util';
|
|
@@ -35,7 +34,7 @@ import { Parser } from 'htmlparser2';
|
|
|
35
34
|
import { createInterface } from 'readline';
|
|
36
35
|
import jsonwebtoken from 'jsonwebtoken';
|
|
37
36
|
import { lookup } from 'mime-types';
|
|
38
|
-
import {
|
|
37
|
+
import { globbySync } from 'globby';
|
|
39
38
|
import chalk from 'chalk';
|
|
40
39
|
import { Promise } from 'rsvp';
|
|
41
40
|
import apiClient from 'superagent';
|
|
@@ -57,12 +56,28 @@ export function setup(config) {
|
|
|
57
56
|
rl.question(cyan.bold('Para Access Key: '), function (accessKey) {
|
|
58
57
|
rl.question(cyan.bold('Para Secret Key: '), function (secretKey) {
|
|
59
58
|
rl.question(cyan.bold('Para Endpoint: '), function (endpoint) {
|
|
60
|
-
var access = accessKey || config.get('accessKey');
|
|
61
|
-
var secret = secretKey || config.get('secretKey');
|
|
59
|
+
var access = (accessKey || config.get('accessKey')).trim();
|
|
60
|
+
var secret = (secretKey || config.get('secretKey')).trim();
|
|
61
|
+
var endpoint = (endpoint || config.get('endpoint')).trim();
|
|
62
62
|
newJWT(access, secret, endpoint, config);
|
|
63
63
|
var pc = new ParaClient(access, secret, { endpoint: endpoint || defaultConfig.endpoint });
|
|
64
64
|
ping(pc, config);
|
|
65
|
-
|
|
65
|
+
if (access === 'app:para') {
|
|
66
|
+
listApps(pc, function () {
|
|
67
|
+
// if none, ask to create one
|
|
68
|
+
rl.question(cyan.bold('Would you like to create a new Para app? [Y/n] '), function (Yn) {
|
|
69
|
+
Yn = Yn.trim();
|
|
70
|
+
if ('' === Yn || 'y' === Yn || 'Y' === Yn) {
|
|
71
|
+
rl.question(cyan.bold('App name: '), function (appname) {
|
|
72
|
+
newApp(pc, ['', appname], {});
|
|
73
|
+
rl.close();
|
|
74
|
+
});
|
|
75
|
+
} else {
|
|
76
|
+
rl.close();
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
}
|
|
66
81
|
});
|
|
67
82
|
});
|
|
68
83
|
});
|
|
@@ -74,7 +89,7 @@ export function createAll(pc, input, flags) {
|
|
|
74
89
|
return;
|
|
75
90
|
}
|
|
76
91
|
|
|
77
|
-
var files =
|
|
92
|
+
var files = globbySync(input[1], { realpath: true });
|
|
78
93
|
var totalSize = 0;
|
|
79
94
|
var totalObjects = 0;
|
|
80
95
|
var batches = [[]];
|
|
@@ -185,7 +200,7 @@ export function updateAll(pc, input, flags) {
|
|
|
185
200
|
return;
|
|
186
201
|
}
|
|
187
202
|
|
|
188
|
-
var files =
|
|
203
|
+
var files = globbySync(input[1], { realpath: true });
|
|
189
204
|
var updateList = [];
|
|
190
205
|
|
|
191
206
|
for (var i = 0; i < files.length; i++) {
|
|
@@ -219,7 +234,7 @@ export function updateAll(pc, input, flags) {
|
|
|
219
234
|
|
|
220
235
|
export function deleteAll(pc, input, flags) {
|
|
221
236
|
if (flags.id || input[1]) {
|
|
222
|
-
var deleteIds =
|
|
237
|
+
var deleteIds = globbySync(input[1] || ' ', { realpath: true });
|
|
223
238
|
if (deleteIds.length === 0) {
|
|
224
239
|
deleteIds = flags.id instanceof Array ? flags.id : [String(flags.id)];
|
|
225
240
|
}
|
|
@@ -295,9 +310,11 @@ export function ping(pc, config) {
|
|
|
295
310
|
cyan(mee.type + ' ' + mee.name + ' (' + mee.id + ')'));
|
|
296
311
|
}).catch(function () {
|
|
297
312
|
fail('Connection failed. Run "para-cli setup" or check the configuration file', yellow(config.path));
|
|
313
|
+
process.exit(1);
|
|
298
314
|
});
|
|
299
315
|
}).catch(function () {
|
|
300
316
|
fail('Connection failed. Run "para-cli setup" or check the configuration file', yellow(config.path));
|
|
317
|
+
process.exit(1);
|
|
301
318
|
});
|
|
302
319
|
}
|
|
303
320
|
|
|
@@ -354,7 +371,9 @@ function promiseWhile(results, fn) {
|
|
|
354
371
|
function loop() {
|
|
355
372
|
return Promise.resolve(fn()).then(function (result) {
|
|
356
373
|
if (result && result.length > 0) {
|
|
357
|
-
|
|
374
|
+
result.forEach(function (res) {
|
|
375
|
+
results.push(res);
|
|
376
|
+
});
|
|
358
377
|
return loop();
|
|
359
378
|
}
|
|
360
379
|
resolve();
|
|
@@ -407,6 +426,67 @@ export function rebuildIndex(pc, config, flags) {
|
|
|
407
426
|
});
|
|
408
427
|
}
|
|
409
428
|
|
|
429
|
+
export function listApps(config, flags, parentAccessKey, failureCallback) {
|
|
430
|
+
var accessKey = flags.accessKey || process.env.PARA_ACCESS_KEY || config.get('accessKey');
|
|
431
|
+
var secretKey = flags.secretKey || process.env.PARA_SECRET_KEY || config.get('secretKey');
|
|
432
|
+
var endpoint = flags.endpoint || process.env.PARA_ENDPOINT || config.get('endpoint');
|
|
433
|
+
var pc = new ParaClient(accessKey, secretKey, {endpoint: endpoint});
|
|
434
|
+
var p = new Pager();
|
|
435
|
+
var results = [];
|
|
436
|
+
p.sortby = '_docid';
|
|
437
|
+
p.page = 1;
|
|
438
|
+
promiseWhile(results, function () {
|
|
439
|
+
return pc.findQuery('app', '*', p);
|
|
440
|
+
}).then(function () {
|
|
441
|
+
var apps = results.map(function (app) {return app.appIdentifier.trim();});
|
|
442
|
+
if (apps.length) {
|
|
443
|
+
console.log('Found', p.count, 'apps:', yellow('[') + green(apps.join(yellow('] ['))) + yellow(']'));
|
|
444
|
+
console.log('Typing', cyan('para-cli select'), green(apps[0]), 'will switch to that app. Current app:',
|
|
445
|
+
green(parentAccessKey));
|
|
446
|
+
process.exit(0);
|
|
447
|
+
} else {
|
|
448
|
+
failureCallback();
|
|
449
|
+
}
|
|
450
|
+
}).catch(function (err) {
|
|
451
|
+
failureCallback();
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
export function selectApp(pc, input, config, flags) {
|
|
456
|
+
var accessKey = flags.accessKey || process.env.PARA_ACCESS_KEY || config.get('accessKey');
|
|
457
|
+
var secretKey = flags.secretKey || process.env.PARA_SECRET_KEY || config.get('secretKey');
|
|
458
|
+
if (accessKey === 'app:para' && secretKey) {
|
|
459
|
+
var selectedApp = 'app:' + (input[1] || 'para').trim();
|
|
460
|
+
if (selectedApp === 'app:para') {
|
|
461
|
+
config.delete('selectedApp');
|
|
462
|
+
console.log(green('✔'), 'Selected', green(selectedApp), 'as the current app.');
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
var now = Math.round(new Date().getTime() / 1000);
|
|
466
|
+
var jwt = sign(JSON.stringify({
|
|
467
|
+
iat: now,
|
|
468
|
+
exp: now + 60,
|
|
469
|
+
appid: accessKey,
|
|
470
|
+
getCredentials: selectedApp
|
|
471
|
+
}), secretKey, { algorithm: 'HS256' });
|
|
472
|
+
pc.setAccessToken(jwt);
|
|
473
|
+
pc.me(jwt).then(function (data) {
|
|
474
|
+
if (data && data.credentials) {
|
|
475
|
+
config.set('selectedApp', data.credentials);
|
|
476
|
+
console.log(green('✔'), 'Selected', green(selectedApp), 'as the current app.');
|
|
477
|
+
} else {
|
|
478
|
+
fail('That did not work -' + red(input[1]) + ' try updating Para to the latest version.');
|
|
479
|
+
}
|
|
480
|
+
pc.clearAccessToken();
|
|
481
|
+
}).catch(function (err) {
|
|
482
|
+
fail('App ' + red(input[1]) + ' not found!');
|
|
483
|
+
pc.clearAccessToken();
|
|
484
|
+
});
|
|
485
|
+
} else {
|
|
486
|
+
fail('This command only works when Para CLI is configured to use the keys for the root app.');
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
410
490
|
function sendFileChunk(chunkId, textEncoded, json, id, flags, start, end, pc, decoder) {
|
|
411
491
|
if (start > 0 && textEncoded[start] !== 32) {
|
|
412
492
|
for (var i = 0; i < 100 && start - i >= 0; i++) {
|
package/package.json
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "para-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.18.0",
|
|
4
|
+
"license": "Apache-2.0",
|
|
4
5
|
"description": "Command-line tool for Para backend servers",
|
|
5
6
|
"homepage": "https://paraio.org",
|
|
6
7
|
"type": "module",
|
|
8
|
+
"exports": "./index.js",
|
|
7
9
|
"author": {
|
|
8
10
|
"name": "Alex Bogdanovski",
|
|
9
11
|
"email": "alex@erudika.com",
|
|
@@ -22,47 +24,23 @@
|
|
|
22
24
|
"api"
|
|
23
25
|
],
|
|
24
26
|
"devDependencies": {
|
|
25
|
-
"eslint": "^
|
|
26
|
-
"eslint-config-xo-space": "^0.28.0",
|
|
27
|
-
"gulp": "^4.0.2",
|
|
28
|
-
"gulp-eslint": "^6.0.0",
|
|
29
|
-
"gulp-exclude-gitignore": "^1.2.0",
|
|
30
|
-
"gulp-istanbul": "^1.1.3",
|
|
31
|
-
"gulp-line-ending-corrector": "^1.0.3",
|
|
32
|
-
"gulp-mocha": "^8.0.0",
|
|
33
|
-
"gulp-plumber": "^1.2.1",
|
|
34
|
-
"gulp-xo": "^0.25.0",
|
|
35
|
-
"handlebars": "^4.7.6",
|
|
36
|
-
"lodash": "^4.17.21",
|
|
37
|
-
"mem": "^8.1.1",
|
|
38
|
-
"minimist": ">=1.2.3",
|
|
39
|
-
"yargs-parser": ">=20.2.7"
|
|
40
|
-
},
|
|
41
|
-
"eslintConfig": {
|
|
42
|
-
"extends": "xo-space",
|
|
43
|
-
"env": {
|
|
44
|
-
"mocha": true
|
|
45
|
-
}
|
|
27
|
+
"eslint": "^8.8.0"
|
|
46
28
|
},
|
|
47
29
|
"repository": "Erudika/para-cli",
|
|
48
|
-
"scripts": {
|
|
49
|
-
"test": "gulp"
|
|
50
|
-
},
|
|
51
|
-
"license": "Apache-2.0",
|
|
52
30
|
"dependencies": {
|
|
53
31
|
"brace-expansion": "^2.0.1",
|
|
54
|
-
"chalk": "^
|
|
32
|
+
"chalk": "^5.0.0",
|
|
55
33
|
"conf": "^10.0.1",
|
|
56
34
|
"exit": "^0.1.2",
|
|
57
35
|
"figlet": "^1.5.0",
|
|
58
36
|
"get-stdin": "^9.0.0",
|
|
59
|
-
"globby": "^
|
|
60
|
-
"htmlparser2": "^
|
|
37
|
+
"globby": "^13.1.1",
|
|
38
|
+
"htmlparser2": "^7.2.0",
|
|
61
39
|
"jsonwebtoken": "^8.5.1",
|
|
62
40
|
"meow": "^10.0.1",
|
|
63
41
|
"mime-types": "^2.1.31",
|
|
64
|
-
"para-client-js": "^1.37.
|
|
65
|
-
"resolve": "^1.
|
|
42
|
+
"para-client-js": "^1.37.9",
|
|
43
|
+
"resolve": "^1.22.0",
|
|
66
44
|
"striptags": "^3.1.1",
|
|
67
45
|
"update-notifier": "^5.1.0",
|
|
68
46
|
"yargs-parser": ">=20.2.7"
|
package/para-cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/*
|
|
4
|
-
* Copyright 2013-
|
|
4
|
+
* Copyright 2013-2022 Erudika. https://erudika.com
|
|
5
5
|
*
|
|
6
6
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
7
|
* you may not use this file except in compliance with the License.
|
|
@@ -21,17 +21,15 @@
|
|
|
21
21
|
/* eslint indent: ["error", "tab"] */
|
|
22
22
|
/* eslint object-curly-spacing: ["error", "always"] */
|
|
23
23
|
|
|
24
|
-
'use strict';
|
|
25
|
-
|
|
26
24
|
import updateNotifier from 'update-notifier';
|
|
27
25
|
import ParaClient from 'para-client-js';
|
|
28
26
|
import Conf from 'conf';
|
|
29
27
|
import figlet from 'figlet';
|
|
30
28
|
import chalk from 'chalk';
|
|
31
29
|
import meow from 'meow';
|
|
32
|
-
import { defaultConfig, setup, createAll, readAll, updateAll, deleteAll, search, newKeys, newJWT, newApp, ping, me, appSettings, rebuildIndex, exportData, importData } from './index.js';
|
|
30
|
+
import { defaultConfig, setup, listApps, selectApp, createAll, readAll, updateAll, deleteAll, search, newKeys, newJWT, newApp, ping, me, appSettings, rebuildIndex, exportData, importData } from './index.js';
|
|
33
31
|
|
|
34
|
-
const { blue } = chalk;
|
|
32
|
+
const { red, green, blue } = chalk;
|
|
35
33
|
const { textSync } = figlet;
|
|
36
34
|
|
|
37
35
|
var cli = meow(`
|
|
@@ -40,6 +38,8 @@ var cli = meow(`
|
|
|
40
38
|
|
|
41
39
|
Commands:
|
|
42
40
|
setup Initial setup, prompts you to enter your Para API keys and endpoint
|
|
41
|
+
apps Returns a list of all Para apps
|
|
42
|
+
select <appid> Selects a Para app as a target for all subsequent read/write requests.
|
|
43
43
|
create <file|glob> [--id] [--type] Persists files as Para objects and makes them searchable
|
|
44
44
|
read --id 123 [--id 345 ...] Fetches objects with the given ids
|
|
45
45
|
update <file.json|glob> ... Updates Para objects with the data from a JSON file (must contain id field)
|
|
@@ -106,68 +106,88 @@ var flags = cli.flags;
|
|
|
106
106
|
var accessKey = flags.accessKey || process.env.PARA_ACCESS_KEY || config.get('accessKey');
|
|
107
107
|
var secretKey = flags.secretKey || process.env.PARA_SECRET_KEY || config.get('secretKey');
|
|
108
108
|
var endpoint = flags.endpoint || process.env.PARA_ENDPOINT || config.get('endpoint');
|
|
109
|
-
var
|
|
109
|
+
var selectedApp = config.get('selectedApp');
|
|
110
110
|
|
|
111
|
-
if (
|
|
112
|
-
|
|
111
|
+
if (selectedApp && selectedApp.accessKey && selectedApp.accessKey.indexOf("app:") === 0) {
|
|
112
|
+
accessKey = selectedApp.accessKey;
|
|
113
|
+
secretKey = selectedApp.secretKey;
|
|
113
114
|
}
|
|
114
115
|
|
|
115
|
-
if (input[0]
|
|
116
|
+
if (!input[0]) {
|
|
117
|
+
console.log(help);
|
|
118
|
+
} else if (!accessKey || !secretKey) {
|
|
119
|
+
console.error(red('Command ' + input[0] + ' failed! Blank credentials, running setup first...'));
|
|
120
|
+
process.exitCode = 1;
|
|
116
121
|
setup(config);
|
|
117
|
-
}
|
|
122
|
+
} else {
|
|
123
|
+
var pc = new ParaClient(accessKey, secretKey, { endpoint: endpoint });
|
|
118
124
|
|
|
119
|
-
if (input[0] === '
|
|
120
|
-
|
|
121
|
-
}
|
|
125
|
+
if (input[0] === 'setup') {
|
|
126
|
+
setup(config);
|
|
127
|
+
}
|
|
122
128
|
|
|
123
|
-
if (input[0] === '
|
|
124
|
-
|
|
125
|
-
}
|
|
129
|
+
if (input[0] === 'apps') {
|
|
130
|
+
listApps(config, flags, accessKey, function () {console.log('No apps found within', green(accessKey));});
|
|
131
|
+
}
|
|
126
132
|
|
|
127
|
-
if (input[0] === '
|
|
128
|
-
|
|
129
|
-
}
|
|
133
|
+
if (input[0] === 'select') {
|
|
134
|
+
selectApp(pc, input, config, flags);
|
|
135
|
+
}
|
|
130
136
|
|
|
131
|
-
if (input[0] === '
|
|
132
|
-
|
|
133
|
-
}
|
|
137
|
+
if (input[0] === 'create') {
|
|
138
|
+
createAll(pc, input, flags);
|
|
139
|
+
}
|
|
134
140
|
|
|
135
|
-
if (input[0] === '
|
|
136
|
-
|
|
137
|
-
}
|
|
141
|
+
if (input[0] === 'read') {
|
|
142
|
+
readAll(pc, flags);
|
|
143
|
+
}
|
|
138
144
|
|
|
139
|
-
if (input[0] === '
|
|
140
|
-
|
|
141
|
-
}
|
|
145
|
+
if (input[0] === 'update') {
|
|
146
|
+
updateAll(pc, input, flags);
|
|
147
|
+
}
|
|
142
148
|
|
|
143
|
-
if (input[0] === '
|
|
144
|
-
|
|
145
|
-
}
|
|
149
|
+
if (input[0] === 'delete') {
|
|
150
|
+
deleteAll(pc, input, flags);
|
|
151
|
+
}
|
|
146
152
|
|
|
147
|
-
if (input[0] === '
|
|
148
|
-
|
|
149
|
-
}
|
|
153
|
+
if (input[0] === 'search') {
|
|
154
|
+
search(pc, input, flags);
|
|
155
|
+
}
|
|
150
156
|
|
|
151
|
-
if (input[0] === '
|
|
152
|
-
|
|
153
|
-
}
|
|
157
|
+
if (input[0] === 'new-key') {
|
|
158
|
+
newKeys(pc, config);
|
|
159
|
+
}
|
|
154
160
|
|
|
155
|
-
if (input[0] === '
|
|
156
|
-
|
|
157
|
-
}
|
|
161
|
+
if (input[0] === 'new-jwt') {
|
|
162
|
+
newJWT(accessKey, secretKey, endpoint, config);
|
|
163
|
+
}
|
|
158
164
|
|
|
159
|
-
if (input[0] === 'app
|
|
160
|
-
|
|
161
|
-
}
|
|
165
|
+
if (input[0] === 'new-app') {
|
|
166
|
+
newApp(pc, input, flags);
|
|
167
|
+
}
|
|
162
168
|
|
|
163
|
-
if (input[0] === '
|
|
164
|
-
|
|
165
|
-
}
|
|
169
|
+
if (input[0] === 'ping') {
|
|
170
|
+
ping(pc, config);
|
|
171
|
+
}
|
|
166
172
|
|
|
167
|
-
if (input[0] === '
|
|
168
|
-
|
|
169
|
-
}
|
|
173
|
+
if (input[0] === 'me') {
|
|
174
|
+
me(pc, config);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (input[0] === 'app-settings') {
|
|
178
|
+
appSettings(pc, config);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (input[0] === 'rebuild-index') {
|
|
182
|
+
rebuildIndex(pc, config, flags);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (input[0] === 'export') {
|
|
186
|
+
exportData(pc, config, flags);
|
|
187
|
+
}
|
|
170
188
|
|
|
171
|
-
if (input[0] === 'import') {
|
|
172
|
-
|
|
189
|
+
if (input[0] === 'import') {
|
|
190
|
+
importData(pc, input, config);
|
|
191
|
+
}
|
|
173
192
|
}
|
|
193
|
+
|