para-cli 1.15.0 → 1.17.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/README.md +46 -44
- package/index.js +53 -9
- package/package.json +10 -32
- package/para-cli.js +11 -1
package/README.md
CHANGED
|
@@ -34,50 +34,52 @@ $ para-cli setup
|
|
|
34
34
|
Command-line tool for Para backend servers
|
|
35
35
|
|
|
36
36
|
Usage:
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
37
|
+
$ para-cli [command] [file]
|
|
38
|
+
|
|
39
|
+
Commands:
|
|
40
|
+
setup Initial setup, prompts you to enter your Para API keys and endpoint
|
|
41
|
+
create <file|glob> [--id] [--type] Persists files as Para objects and makes them searchable
|
|
42
|
+
read --id 123 [--id 345 ...] Fetches objects with the given ids
|
|
43
|
+
update <file.json|glob> ... Updates Para objects with the data from a JSON file (must contain id field)
|
|
44
|
+
delete [glob] --id 123 ... Deletes one or more objects from Para
|
|
45
|
+
search "query" [--limit --page --sort] Searches the Para index for objects given a query string
|
|
46
|
+
rebuild-index Rebuilds the entire search index
|
|
47
|
+
app-settings Returns all settings for the authenticated app
|
|
48
|
+
new-key Generates a new secret key and saves it to config.json
|
|
49
|
+
new-jwt Generates a new JWT super token to be used for app authentication
|
|
50
|
+
new-app <name> --name --shared Creates a new Para app. Only works if you have the keys for the "root" app
|
|
51
|
+
export Exports all data from the app's table
|
|
52
|
+
import <file> Imports data from a previously exported ZIP archive
|
|
53
|
+
ping Tests the connection to the Para server
|
|
54
|
+
me Returns the JSON for the currently authenticated user or app
|
|
55
|
+
|
|
56
|
+
Options:
|
|
57
|
+
--type Sets the "type" field of an object
|
|
58
|
+
--id Sets the "id" field of an object
|
|
59
|
+
--sanitize Strips all symbols from input files
|
|
60
|
+
--accessKey Sets the Para access key
|
|
61
|
+
--secretKey Sets the Para secret key
|
|
62
|
+
--endpoint Sets the URL of the Para server
|
|
63
|
+
--sort Sets the field on which to sort search results
|
|
64
|
+
--desc Descending sort for search results (default: true)
|
|
65
|
+
--page Page number for search results, "all" will auto-paginate through all results
|
|
66
|
+
--limit Limits the number of search results
|
|
67
|
+
--lastKey Sets the last id for search-after pagination
|
|
68
|
+
--cwd Sets the current directory - used for resolving file paths
|
|
69
|
+
--encodeId By default all ids are Base64 encoded, unless this is 'false'
|
|
70
|
+
--help Prints the list of commands
|
|
71
|
+
--version Prints the version of the program
|
|
72
|
+
|
|
73
|
+
Examples:
|
|
74
|
+
$ para-cli setup
|
|
75
|
+
$ para-cli create my-blog-post.md
|
|
76
|
+
$ para-cli read --id my-blog-post.md
|
|
77
|
+
$ para-cli create index.html --type webpage --id "My new article" --sanitize
|
|
78
|
+
$ para-cli delete --id 123 --id "my-blog-post.md"
|
|
79
|
+
$ para-cli search "type:article AND title:*" --sort timestamp --desc false --limit 10
|
|
80
|
+
$ para-cli search "*" --type article --page all
|
|
81
|
+
$ para-cli new-key
|
|
82
|
+
$ para-cli new-app "mynewapp" --name "Full app name"
|
|
81
83
|
|
|
82
84
|
```
|
|
83
85
|
|
package/index.js
CHANGED
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
/* eslint object-curly-spacing: ["error", "always"] */
|
|
27
27
|
|
|
28
28
|
'use strict';
|
|
29
|
-
import { statSync, readFileSync } from 'fs';
|
|
30
|
-
import { relative, basename } from 'path';
|
|
29
|
+
import { statSync, readFileSync, writeFileSync } from 'fs';
|
|
30
|
+
import { relative, basename, resolve } from 'path';
|
|
31
31
|
import { TextEncoder } from 'util';
|
|
32
32
|
var encoder = new TextEncoder('utf-8');
|
|
33
33
|
import striptags from 'striptags';
|
|
@@ -35,9 +35,10 @@ import { Parser } from 'htmlparser2';
|
|
|
35
35
|
import { createInterface } from 'readline';
|
|
36
36
|
import jsonwebtoken from 'jsonwebtoken';
|
|
37
37
|
import { lookup } from 'mime-types';
|
|
38
|
-
import {
|
|
38
|
+
import { globbySync } from 'globby';
|
|
39
39
|
import chalk from 'chalk';
|
|
40
40
|
import { Promise } from 'rsvp';
|
|
41
|
+
import apiClient from 'superagent';
|
|
41
42
|
import { ParaClient, ParaObject, Pager } from 'para-client-js';
|
|
42
43
|
|
|
43
44
|
const { cyan, red, yellow, green } = chalk;
|
|
@@ -53,15 +54,14 @@ export function setup(config) {
|
|
|
53
54
|
input: process.stdin,
|
|
54
55
|
output: process.stdout
|
|
55
56
|
});
|
|
56
|
-
var that = this;
|
|
57
57
|
rl.question(cyan.bold('Para Access Key: '), function (accessKey) {
|
|
58
58
|
rl.question(cyan.bold('Para Secret Key: '), function (secretKey) {
|
|
59
59
|
rl.question(cyan.bold('Para Endpoint: '), function (endpoint) {
|
|
60
60
|
var access = accessKey || config.get('accessKey');
|
|
61
61
|
var secret = secretKey || config.get('secretKey');
|
|
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
|
rl.close();
|
|
66
66
|
});
|
|
67
67
|
});
|
|
@@ -71,9 +71,10 @@ export function setup(config) {
|
|
|
71
71
|
export function createAll(pc, input, flags) {
|
|
72
72
|
if (!input[1]) {
|
|
73
73
|
fail('No files specified.');
|
|
74
|
+
return;
|
|
74
75
|
}
|
|
75
76
|
|
|
76
|
-
var files =
|
|
77
|
+
var files = globbySync(input[1], { realpath: true });
|
|
77
78
|
var totalSize = 0;
|
|
78
79
|
var totalObjects = 0;
|
|
79
80
|
var batches = [[]];
|
|
@@ -181,9 +182,10 @@ export function readAll(pc, flags) {
|
|
|
181
182
|
export function updateAll(pc, input, flags) {
|
|
182
183
|
if (!input[1]) {
|
|
183
184
|
fail('No files specified.');
|
|
185
|
+
return;
|
|
184
186
|
}
|
|
185
187
|
|
|
186
|
-
var files =
|
|
188
|
+
var files = globbySync(input[1], { realpath: true });
|
|
187
189
|
var updateList = [];
|
|
188
190
|
|
|
189
191
|
for (var i = 0; i < files.length; i++) {
|
|
@@ -217,7 +219,7 @@ export function updateAll(pc, input, flags) {
|
|
|
217
219
|
|
|
218
220
|
export function deleteAll(pc, input, flags) {
|
|
219
221
|
if (flags.id || input[1]) {
|
|
220
|
-
var deleteIds =
|
|
222
|
+
var deleteIds = globbySync(input[1] || ' ', { realpath: true });
|
|
221
223
|
if (deleteIds.length === 0) {
|
|
222
224
|
deleteIds = flags.id instanceof Array ? flags.id : [String(flags.id)];
|
|
223
225
|
}
|
|
@@ -248,6 +250,7 @@ export function newKeys(pc, config) {
|
|
|
248
250
|
export function newJWT(accessKey, secretKey, endpoint, config) {
|
|
249
251
|
if (!accessKey || accessKey.length < 3 || !secretKey || secretKey.length < 6) {
|
|
250
252
|
fail('Invalid credentials.');
|
|
253
|
+
return;
|
|
251
254
|
}
|
|
252
255
|
|
|
253
256
|
var now = Math.round(new Date().getTime() / 1000);
|
|
@@ -267,6 +270,7 @@ export function newJWT(accessKey, secretKey, endpoint, config) {
|
|
|
267
270
|
export function newApp(pc, input, flags) {
|
|
268
271
|
if (!input[1]) {
|
|
269
272
|
fail('App name not specified.');
|
|
273
|
+
return;
|
|
270
274
|
}
|
|
271
275
|
|
|
272
276
|
var appid = input[1];
|
|
@@ -305,6 +309,46 @@ export function me(pc, config) {
|
|
|
305
309
|
});
|
|
306
310
|
}
|
|
307
311
|
|
|
312
|
+
export function exportData(pc, config) {
|
|
313
|
+
pc.invokeGet('/_export').then(function (data) {
|
|
314
|
+
try {
|
|
315
|
+
var filename = (data.headers['content-disposition'] || 'export.zip');
|
|
316
|
+
var filesize = Math.round(((data.headers['content-length'] || 0) / 1000000) * 100) / 100;
|
|
317
|
+
filename = filename.substring(filename.lastIndexOf('=') + 1);
|
|
318
|
+
writeFileSync(filename, data.body);
|
|
319
|
+
console.log(green('✔'), yellow('Exported ' + filesize + 'MB of data to file ' + filename));
|
|
320
|
+
} catch (e) {
|
|
321
|
+
console.error(e);
|
|
322
|
+
}
|
|
323
|
+
}).catch(function () {
|
|
324
|
+
fail('Connection failed. Server might be down. Check the configuration file', yellow(config.path));
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
export function importData(pc, input, config) {
|
|
329
|
+
if (!input[1]) {
|
|
330
|
+
fail('No file to import.');
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
if (!config.get('jwt')) {
|
|
334
|
+
newJWT(config.get('accessKey'), config.get('secretKey'), config.get('endpoint'), config);
|
|
335
|
+
}
|
|
336
|
+
var headers = {
|
|
337
|
+
'User-Agent': 'Para CLI tool',
|
|
338
|
+
'Content-Type': 'application/zip',
|
|
339
|
+
'Authorization': 'Bearer ' + config.get('jwt')
|
|
340
|
+
};
|
|
341
|
+
try {
|
|
342
|
+
apiClient.put(pc.endpoint + '/v1/_import').set(headers).send(readFileSync(resolve(input[1]))).then(function(res) {
|
|
343
|
+
console.log(green('✔'), yellow('Imported ' + res.body.count + ' object into app "' + res.body.appid) + '"');
|
|
344
|
+
}).catch(function (e) {
|
|
345
|
+
fail('Import request failed. ' + e);
|
|
346
|
+
});
|
|
347
|
+
} catch (e) {
|
|
348
|
+
fail('Import request failed: ' + e);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
308
352
|
function promiseWhile(results, fn) {
|
|
309
353
|
return new Promise(function (resolve, _reject) {
|
|
310
354
|
function loop() {
|
package/package.json
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "para-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.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,46 +24,22 @@
|
|
|
22
24
|
"api"
|
|
23
25
|
],
|
|
24
26
|
"devDependencies": {
|
|
25
|
-
"eslint": "^
|
|
26
|
-
"eslint-config-xo-space": "^0.27.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.4.1"
|
|
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": "^12.0.2",
|
|
38
|
+
"htmlparser2": "^7.2.0",
|
|
61
39
|
"jsonwebtoken": "^8.5.1",
|
|
62
|
-
"meow": "^10.0.
|
|
63
|
-
"mime-types": "^2.1.
|
|
64
|
-
"para-client-js": "^1.37.
|
|
40
|
+
"meow": "^10.0.1",
|
|
41
|
+
"mime-types": "^2.1.31",
|
|
42
|
+
"para-client-js": "^1.37.6",
|
|
65
43
|
"resolve": "^1.20.0",
|
|
66
44
|
"striptags": "^3.1.1",
|
|
67
45
|
"update-notifier": "^5.1.0",
|
package/para-cli.js
CHANGED
|
@@ -29,7 +29,7 @@ import Conf from 'conf';
|
|
|
29
29
|
import figlet from 'figlet';
|
|
30
30
|
import chalk from 'chalk';
|
|
31
31
|
import meow from 'meow';
|
|
32
|
-
import { defaultConfig, setup, createAll, readAll, updateAll, deleteAll, search, newKeys, newJWT, newApp, ping, me, appSettings, rebuildIndex } from './index.js';
|
|
32
|
+
import { defaultConfig, setup, createAll, readAll, updateAll, deleteAll, search, newKeys, newJWT, newApp, ping, me, appSettings, rebuildIndex, exportData, importData } from './index.js';
|
|
33
33
|
|
|
34
34
|
const { blue } = chalk;
|
|
35
35
|
const { textSync } = figlet;
|
|
@@ -50,6 +50,8 @@ var cli = meow(`
|
|
|
50
50
|
new-key Generates a new secret key and saves it to config.json
|
|
51
51
|
new-jwt Generates a new JWT super token to be used for app authentication
|
|
52
52
|
new-app <name> --name --shared Creates a new Para app. Only works if you have the keys for the "root" app
|
|
53
|
+
export Exports all data from the app's table
|
|
54
|
+
import <file> Imports data from a previously exported ZIP archive
|
|
53
55
|
ping Tests the connection to the Para server
|
|
54
56
|
me Returns the JSON for the currently authenticated user or app
|
|
55
57
|
|
|
@@ -161,3 +163,11 @@ if (input[0] === 'app-settings') {
|
|
|
161
163
|
if (input[0] === 'rebuild-index') {
|
|
162
164
|
rebuildIndex(pc, config, flags);
|
|
163
165
|
}
|
|
166
|
+
|
|
167
|
+
if (input[0] === 'export') {
|
|
168
|
+
exportData(pc, config, flags);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (input[0] === 'import') {
|
|
172
|
+
importData(pc, input, config);
|
|
173
|
+
}
|