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 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 2021 Erudika LTD, https://erudika.com
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-2021 Erudika. https://erudika.com
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 { sync } from 'globby';
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
- rl.close();
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 = sync(input[1], { realpath: true });
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 = sync(input[1], { realpath: true });
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 = sync(input[1] || ' ', { realpath: true });
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
- results = results.concat(result);
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.16.0",
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": "^7.28.0",
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": "^4.1.1",
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": "^11.0.4",
60
- "htmlparser2": "^6.1.0",
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.6",
65
- "resolve": "^1.20.0",
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-2021 Erudika. https://erudika.com
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 pc = new ParaClient(accessKey, secretKey, { endpoint: endpoint });
109
+ var selectedApp = config.get('selectedApp');
110
110
 
111
- if (!input[0]) {
112
- console.log(help);
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] === 'setup') {
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] === 'create') {
120
- createAll(pc, input, flags);
121
- }
125
+ if (input[0] === 'setup') {
126
+ setup(config);
127
+ }
122
128
 
123
- if (input[0] === 'read') {
124
- readAll(pc, flags);
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] === 'update') {
128
- updateAll(pc, input, flags);
129
- }
133
+ if (input[0] === 'select') {
134
+ selectApp(pc, input, config, flags);
135
+ }
130
136
 
131
- if (input[0] === 'delete') {
132
- deleteAll(pc, input, flags);
133
- }
137
+ if (input[0] === 'create') {
138
+ createAll(pc, input, flags);
139
+ }
134
140
 
135
- if (input[0] === 'search') {
136
- search(pc, input, flags);
137
- }
141
+ if (input[0] === 'read') {
142
+ readAll(pc, flags);
143
+ }
138
144
 
139
- if (input[0] === 'new-key') {
140
- newKeys(pc, config);
141
- }
145
+ if (input[0] === 'update') {
146
+ updateAll(pc, input, flags);
147
+ }
142
148
 
143
- if (input[0] === 'new-jwt') {
144
- newJWT(accessKey, secretKey, endpoint, config);
145
- }
149
+ if (input[0] === 'delete') {
150
+ deleteAll(pc, input, flags);
151
+ }
146
152
 
147
- if (input[0] === 'new-app') {
148
- newApp(pc, input, flags);
149
- }
153
+ if (input[0] === 'search') {
154
+ search(pc, input, flags);
155
+ }
150
156
 
151
- if (input[0] === 'ping') {
152
- ping(pc, config);
153
- }
157
+ if (input[0] === 'new-key') {
158
+ newKeys(pc, config);
159
+ }
154
160
 
155
- if (input[0] === 'me') {
156
- me(pc, config);
157
- }
161
+ if (input[0] === 'new-jwt') {
162
+ newJWT(accessKey, secretKey, endpoint, config);
163
+ }
158
164
 
159
- if (input[0] === 'app-settings') {
160
- appSettings(pc, config);
161
- }
165
+ if (input[0] === 'new-app') {
166
+ newApp(pc, input, flags);
167
+ }
162
168
 
163
- if (input[0] === 'rebuild-index') {
164
- rebuildIndex(pc, config, flags);
165
- }
169
+ if (input[0] === 'ping') {
170
+ ping(pc, config);
171
+ }
166
172
 
167
- if (input[0] === 'export') {
168
- exportData(pc, config, flags);
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
- importData(pc, input, config);
189
+ if (input[0] === 'import') {
190
+ importData(pc, input, config);
191
+ }
173
192
  }
193
+