@knocklabs/cli 0.1.0-rc.3 → 0.1.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 CHANGED
@@ -16,7 +16,7 @@ $ npm install -g @knocklabs/cli
16
16
  $ knock COMMAND
17
17
  running command...
18
18
  $ knock (--version)
19
- @knocklabs/cli/0.1.0-rc.3 linux-x64 node-v16.4.2
19
+ @knocklabs/cli/0.1.0 linux-x64 node-v16.4.2
20
20
  $ knock --help [COMMAND]
21
21
  USAGE
22
22
  $ knock COMMAND
@@ -30,7 +30,6 @@ USAGE
30
30
  * [`knock commit`](#knock-commit)
31
31
  * [`knock commit promote`](#knock-commit-promote)
32
32
  * [`knock help [COMMANDS]`](#knock-help-commands)
33
- * [`knock ping`](#knock-ping)
34
33
  * [`knock plugins`](#knock-plugins)
35
34
  * [`knock plugins:install PLUGIN...`](#knock-pluginsinstall-plugin)
36
35
  * [`knock plugins:inspect PLUGIN...`](#knock-pluginsinspect-plugin)
@@ -40,10 +39,12 @@ USAGE
40
39
  * [`knock plugins:uninstall PLUGIN...`](#knock-pluginsuninstall-plugin-1)
41
40
  * [`knock plugins:uninstall PLUGIN...`](#knock-pluginsuninstall-plugin-2)
42
41
  * [`knock plugins update`](#knock-plugins-update)
42
+ * [`knock translation get TRANSLATIONREF`](#knock-translation-get-translationref)
43
43
  * [`knock translation list`](#knock-translation-list)
44
- * [`knock translation pull`](#knock-translation-pull)
44
+ * [`knock translation pull [TRANSLATIONREF]`](#knock-translation-pull-translationref)
45
45
  * [`knock translation push [TRANSLATIONREF]`](#knock-translation-push-translationref)
46
46
  * [`knock translation validate [TRANSLATIONREF]`](#knock-translation-validate-translationref)
47
+ * [`knock whoami`](#knock-whoami)
47
48
  * [`knock workflow activate WORKFLOWKEY`](#knock-workflow-activate-workflowkey)
48
49
  * [`knock workflow get WORKFLOWKEY`](#knock-workflow-get-workflowkey)
49
50
  * [`knock workflow list`](#knock-workflow-list)
@@ -66,7 +67,7 @@ FLAGS
66
67
  --service-token=<value> (required) The service token to authenticate with
67
68
  ```
68
69
 
69
- _See code: [dist/commands/commit/index.ts](https://github.com/knocklabs/knock-cli/blob/v0.1.0-rc.3/dist/commands/commit/index.ts)_
70
+ _See code: [dist/commands/commit/index.ts](https://github.com/knocklabs/knock-cli/blob/v0.1.0/dist/commands/commit/index.ts)_
70
71
 
71
72
  ## `knock commit promote`
72
73
 
@@ -100,26 +101,6 @@ DESCRIPTION
100
101
 
101
102
  _See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v5.2.9/src/commands/help.ts)_
102
103
 
103
- ## `knock ping`
104
-
105
- Ping the Knock management API to verify access.
106
-
107
- ```
108
- USAGE
109
- $ knock ping --service-token <value>
110
-
111
- FLAGS
112
- --service-token=<value> (required) The service token to authenticate with
113
-
114
- DESCRIPTION
115
- Ping the Knock management API to verify access.
116
-
117
- EXAMPLES
118
- $ knock ping
119
- ```
120
-
121
- _See code: [dist/commands/ping.ts](https://github.com/knocklabs/knock-cli/blob/v0.1.0-rc.3/dist/commands/ping.ts)_
122
-
123
104
  ## `knock plugins`
124
105
 
125
106
  List installed plugins.
@@ -138,7 +119,7 @@ EXAMPLES
138
119
  $ knock plugins
139
120
  ```
140
121
 
141
- _See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v2.4.6/src/commands/plugins/index.ts)_
122
+ _See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v2.4.7/src/commands/plugins/index.ts)_
142
123
 
143
124
  ## `knock plugins:install PLUGIN...`
144
125
 
@@ -353,6 +334,22 @@ DESCRIPTION
353
334
  Update installed plugins.
354
335
  ```
355
336
 
337
+ ## `knock translation get TRANSLATIONREF`
338
+
339
+ ```
340
+ USAGE
341
+ $ knock translation get TRANSLATIONREF --service-token <value> [--environment <value>] [--hide-uncommitted-changes]
342
+ [--json]
343
+
344
+ FLAGS
345
+ --environment=<value> [default: development]
346
+ --hide-uncommitted-changes
347
+ --service-token=<value> (required) The service token to authenticate with
348
+
349
+ GLOBAL FLAGS
350
+ --json Format output as json.
351
+ ```
352
+
356
353
  ## `knock translation list`
357
354
 
358
355
  ```
@@ -372,12 +369,12 @@ GLOBAL FLAGS
372
369
  --json Format output as json.
373
370
  ```
374
371
 
375
- ## `knock translation pull`
372
+ ## `knock translation pull [TRANSLATIONREF]`
376
373
 
377
374
  ```
378
375
  USAGE
379
- $ knock translation pull --service-token <value> [--environment <value>] [--translations-dir <value> --all]
380
- [--hide-uncommitted-changes] [--force]
376
+ $ knock translation pull [TRANSLATIONREF] --service-token <value> [--environment <value>] [--translations-dir
377
+ <value> --all] [--hide-uncommitted-changes] [--force]
381
378
 
382
379
  FLAGS
383
380
  --all
@@ -421,6 +418,21 @@ FLAGS
421
418
  --translations-dir=<value>
422
419
  ```
423
420
 
421
+ ## `knock whoami`
422
+
423
+ ```
424
+ USAGE
425
+ $ knock whoami --service-token <value> [--json]
426
+
427
+ FLAGS
428
+ --service-token=<value> (required) The service token to authenticate with
429
+
430
+ GLOBAL FLAGS
431
+ --json Format output as json.
432
+ ```
433
+
434
+ _See code: [dist/commands/whoami.ts](https://github.com/knocklabs/knock-cli/blob/v0.1.0/dist/commands/whoami.ts)_
435
+
424
436
  ## `knock workflow activate WORKFLOWKEY`
425
437
 
426
438
  ```
@@ -490,25 +502,31 @@ FLAGS
490
502
 
491
503
  ```
492
504
  USAGE
493
- $ knock workflow push [WORKFLOWKEY] --service-token <value> [--environment development] [-m <value> --commit]
505
+ $ knock workflow push [WORKFLOWKEY] --service-token <value> [--environment development] [--workflows-dir <value>
506
+ --all] [-m <value> --commit]
494
507
 
495
508
  FLAGS
496
509
  -m, --commit-message=<value> Use the given value as the commit message
510
+ --all
497
511
  --commit Push and commit the workflow(s) at the same time
498
512
  --environment=<option> [default: development] Pushing a workflow is only allowed in the development environment
499
513
  <options: development>
500
514
  --service-token=<value> (required) The service token to authenticate with
515
+ --workflows-dir=<value>
501
516
  ```
502
517
 
503
518
  ## `knock workflow validate [WORKFLOWKEY]`
504
519
 
505
520
  ```
506
521
  USAGE
507
- $ knock workflow validate [WORKFLOWKEY] --service-token <value> [--environment development]
522
+ $ knock workflow validate [WORKFLOWKEY] --service-token <value> [--environment development] [--workflows-dir <value>
523
+ --all]
508
524
 
509
525
  FLAGS
526
+ --all
510
527
  --environment=<option> [default: development] Validating a workflow is only done in the development environment
511
528
  <options: development>
512
529
  --service-token=<value> (required) The service token to authenticate with
530
+ --workflows-dir=<value>
513
531
  ```
514
532
  <!-- commandsstop -->
@@ -18,6 +18,8 @@ class Ping extends _baseCommand.default {
18
18
  this.log(resp.data);
19
19
  }
20
20
  }
21
+ // Deprecated, in favor of the whoami command.
22
+ Ping.hidden = true;
21
23
  Ping.description = "Ping the Knock management API to verify access.";
22
24
  Ping.examples = [
23
25
  "<%= config.bin %> <%= command.id %>"
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "default", {
6
+ enumerable: true,
7
+ get: ()=>TranslationGet
8
+ });
9
+ const _core = require("@oclif/core");
10
+ const _baseCommand = /*#__PURE__*/ _interopRequireDefault(require("../../lib/base-command"));
11
+ const _date = require("../../lib/helpers/date");
12
+ const _request = require("../../lib/helpers/request");
13
+ const _translation = /*#__PURE__*/ _interopRequireWildcard(require("../../lib/marshal/translation"));
14
+ function _interopRequireDefault(obj) {
15
+ return obj && obj.__esModule ? obj : {
16
+ default: obj
17
+ };
18
+ }
19
+ function _getRequireWildcardCache(nodeInterop) {
20
+ if (typeof WeakMap !== "function") return null;
21
+ var cacheBabelInterop = new WeakMap();
22
+ var cacheNodeInterop = new WeakMap();
23
+ return (_getRequireWildcardCache = function(nodeInterop) {
24
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
25
+ })(nodeInterop);
26
+ }
27
+ function _interopRequireWildcard(obj, nodeInterop) {
28
+ if (!nodeInterop && obj && obj.__esModule) {
29
+ return obj;
30
+ }
31
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
32
+ return {
33
+ default: obj
34
+ };
35
+ }
36
+ var cache = _getRequireWildcardCache(nodeInterop);
37
+ if (cache && cache.has(obj)) {
38
+ return cache.get(obj);
39
+ }
40
+ var newObj = {};
41
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
42
+ for(var key in obj){
43
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
44
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
45
+ if (desc && (desc.get || desc.set)) {
46
+ Object.defineProperty(newObj, key, desc);
47
+ } else {
48
+ newObj[key] = obj[key];
49
+ }
50
+ }
51
+ }
52
+ newObj.default = obj;
53
+ if (cache) {
54
+ cache.set(obj, newObj);
55
+ }
56
+ return newObj;
57
+ }
58
+ class TranslationGet extends _baseCommand.default {
59
+ async run() {
60
+ const { args , flags } = this.props;
61
+ const parsedRef = _translation.parseTranslationRef(args.translationRef);
62
+ if (!parsedRef) {
63
+ return this.error(`Invalid translation ref \`${args.translationRef}\`, use valid <locale> or <namespace>.<locale> for namespaced translations`);
64
+ }
65
+ const resp = await (0, _request.withSpinner)(()=>this.apiV1.getTranslation(this.props, parsedRef));
66
+ if (flags.json) return resp.data;
67
+ this.render(resp.data);
68
+ }
69
+ render(translation) {
70
+ const { translationRef } = this.props.args;
71
+ const { environment: env , "hide-uncommitted-changes": commitedOnly } = this.props.flags;
72
+ const qualifier = env === "development" && !commitedOnly ? "(including uncommitted)" : "";
73
+ this.log(`‣ Showing translation \`${translationRef}\` in \`${env}\` environment ${qualifier}\n`);
74
+ /*
75
+ * Translation table
76
+ */ const rows = [
77
+ {
78
+ key: "Language",
79
+ value: _translation.formatLanguage(translation)
80
+ },
81
+ {
82
+ key: "Locale",
83
+ value: translation.locale_code
84
+ },
85
+ {
86
+ key: "Namespace",
87
+ value: translation.namespace || "-"
88
+ },
89
+ {
90
+ key: "Updated at",
91
+ value: (0, _date.formatDate)(translation.updated_at)
92
+ },
93
+ {
94
+ key: "Created at",
95
+ value: (0, _date.formatDate)(translation.created_at)
96
+ }
97
+ ];
98
+ _core.CliUx.ux.table(rows, {
99
+ key: {
100
+ header: "Translation",
101
+ minWidth: 24
102
+ },
103
+ value: {
104
+ header: "",
105
+ minWidth: 16
106
+ }
107
+ });
108
+ this.log("");
109
+ _core.CliUx.ux.styledJSON(JSON.parse(translation.content));
110
+ }
111
+ }
112
+ TranslationGet.flags = {
113
+ environment: _core.Flags.string({
114
+ default: "development"
115
+ }),
116
+ "hide-uncommitted-changes": _core.Flags.boolean()
117
+ };
118
+ TranslationGet.args = [
119
+ {
120
+ name: "translationRef",
121
+ required: true
122
+ }
123
+ ];
124
+ TranslationGet.enableJsonFlag = true;
@@ -7,17 +7,56 @@ Object.defineProperty(exports, "default", {
7
7
  get: ()=>TranslationList
8
8
  });
9
9
  const _core = require("@oclif/core");
10
- const _localeCodes = /*#__PURE__*/ _interopRequireDefault(require("locale-codes"));
11
10
  const _baseCommand = /*#__PURE__*/ _interopRequireDefault(require("../../lib/base-command"));
12
11
  const _date = require("../../lib/helpers/date");
13
12
  const _object = require("../../lib/helpers/object");
14
13
  const _page = require("../../lib/helpers/page");
15
14
  const _request = require("../../lib/helpers/request");
15
+ const _translation = /*#__PURE__*/ _interopRequireWildcard(require("../../lib/marshal/translation"));
16
16
  function _interopRequireDefault(obj) {
17
17
  return obj && obj.__esModule ? obj : {
18
18
  default: obj
19
19
  };
20
20
  }
21
+ function _getRequireWildcardCache(nodeInterop) {
22
+ if (typeof WeakMap !== "function") return null;
23
+ var cacheBabelInterop = new WeakMap();
24
+ var cacheNodeInterop = new WeakMap();
25
+ return (_getRequireWildcardCache = function(nodeInterop) {
26
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
27
+ })(nodeInterop);
28
+ }
29
+ function _interopRequireWildcard(obj, nodeInterop) {
30
+ if (!nodeInterop && obj && obj.__esModule) {
31
+ return obj;
32
+ }
33
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
34
+ return {
35
+ default: obj
36
+ };
37
+ }
38
+ var cache = _getRequireWildcardCache(nodeInterop);
39
+ if (cache && cache.has(obj)) {
40
+ return cache.get(obj);
41
+ }
42
+ var newObj = {};
43
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
44
+ for(var key in obj){
45
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
46
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
47
+ if (desc && (desc.get || desc.set)) {
48
+ Object.defineProperty(newObj, key, desc);
49
+ } else {
50
+ newObj[key] = obj[key];
51
+ }
52
+ }
53
+ }
54
+ newObj.default = obj;
55
+ if (cache) {
56
+ cache.set(obj, newObj);
57
+ }
58
+ return newObj;
59
+ }
21
60
  class TranslationList extends _baseCommand.default {
22
61
  async run() {
23
62
  const resp = await this.request();
@@ -41,15 +80,16 @@ class TranslationList extends _baseCommand.default {
41
80
  /*
42
81
  * Translations list table
43
82
  */ _core.CliUx.ux.table(entries, {
83
+ ref: {
84
+ header: "Ref",
85
+ get: (entry)=>_translation.formatRef(entry)
86
+ },
44
87
  language_name: {
45
88
  header: "Language",
46
- get: (entry)=>{
47
- const language = _localeCodes.default.getByTag(entry.locale_code);
48
- return language.location ? `${language.name}, ${language.location}` : language.name;
49
- }
89
+ get: (entry)=>_translation.formatLanguage(entry)
50
90
  },
51
91
  locale_code: {
52
- header: "Locale code"
92
+ header: "Locale"
53
93
  },
54
94
  namespace: {
55
95
  header: "Namespace"
@@ -57,6 +97,10 @@ class TranslationList extends _baseCommand.default {
57
97
  updated_at: {
58
98
  header: "Updated at",
59
99
  get: (entry)=>(0, _date.formatDate)(entry.updated_at)
100
+ },
101
+ created_at: {
102
+ header: "Created at",
103
+ get: (entry)=>(0, _date.formatDate)(entry.created_at)
60
104
  }
61
105
  });
62
106
  return this.prompt(data);
@@ -61,40 +61,76 @@ function _interopRequireWildcard(obj, nodeInterop) {
61
61
  }
62
62
  class TranslationPull extends _baseCommand.default {
63
63
  async run() {
64
+ const target = await _translation.ensureValidCommandTarget(this.props, this.runContext);
65
+ switch(target.type){
66
+ case "translationFile":
67
+ return this.pullOneTranslation(target.context);
68
+ case "translationDir":
69
+ return this.pullAllTranslationsForLocale(target.context);
70
+ case "translationsIndexDir":
71
+ return this.pullAllTranslations(target.context);
72
+ default:
73
+ throw new Error(`Invalid translation command target: ${target}`);
74
+ }
75
+ }
76
+ /*
77
+ * Pull a single translation (using TranslationFileContext)
78
+ */ async pullOneTranslation(targetCtx) {
64
79
  const { flags } = this.props;
65
- // TODO MKD: Enable pulling a single translation or group of translations for locale
66
- return flags.all ? this.pullAllTranslations() : this.error("Must use --all to pull all translations");
80
+ if (targetCtx.exists) {
81
+ this.log(`‣ Found \`${targetCtx.ref}\` at ${targetCtx.abspath}`);
82
+ } else {
83
+ const prompt = `Create a new translation file \`${targetCtx.ref}\` at ${targetCtx.abspath}?`;
84
+ const input = flags.force || await (0, _ux.promptToConfirm)(prompt);
85
+ if (!input) return;
86
+ }
87
+ const resp = await (0, _request.withSpinner)(()=>this.apiV1.getTranslation(this.props, targetCtx));
88
+ await _translation.writeTranslationFile(targetCtx, resp.data);
89
+ const actioned = targetCtx.exists ? "updated" : "created";
90
+ this.log(`‣ Successfully ${actioned} \`${targetCtx.ref}\` at ${targetCtx.abspath}`);
67
91
  }
68
92
  /*
69
- * Pull all translations
70
- */ async pullAllTranslations() {
93
+ * Pull all translations for a locale (using TranslationDirContext)
94
+ */ async pullAllTranslationsForLocale(targetCtx) {
71
95
  const { flags } = this.props;
72
- // TODO: In the future we should default to the knock project config first
73
- // if present, before defaulting to the cwd.
74
- const defaultToCwd = {
75
- abspath: this.runContext.cwd,
76
- exists: true
96
+ const prompt = targetCtx.exists ? `Pull latest \`${targetCtx.key}\` translations into ${targetCtx.abspath}?\n This will overwrite the contents of this directory.` : `Create a new \`${targetCtx.key}\` translations directory at ${targetCtx.abspath}?`;
97
+ const input = flags.force || await (0, _ux.promptToConfirm)(prompt);
98
+ if (!input) return;
99
+ // Fetch all translations for a given locale then write them to the local
100
+ // file system.
101
+ _ux.spinner.start(`‣ Loading`);
102
+ const filters = {
103
+ localeCode: targetCtx.key
77
104
  };
78
- const targetDirCtx = flags["translations-dir"] || defaultToCwd;
79
- const prompt = targetDirCtx.exists ? `Pull latest translations into ${targetDirCtx.abspath}?` : `Create a new translations directory at ${targetDirCtx.abspath}?`;
105
+ const translations = await this.listAllTranslations(filters);
106
+ await _translation.writeTranslationFiles(targetCtx, translations);
107
+ _ux.spinner.stop();
108
+ const actioned = targetCtx.exists ? "updated" : "created";
109
+ this.log(`‣ Successfully ${actioned} the \`${targetCtx.key}\` translations directory at ${targetCtx.abspath}`);
110
+ }
111
+ /*
112
+ * Pull all translations (using DirContext)
113
+ */ async pullAllTranslations(targetCtx) {
114
+ const { flags } = this.props;
115
+ const prompt = targetCtx.exists ? `Pull latest translations into ${targetCtx.abspath}?\n This will overwrite the contents of this directory.` : `Create a new translations directory at ${targetCtx.abspath}?`;
80
116
  const input = flags.force || await (0, _ux.promptToConfirm)(prompt);
81
117
  if (!input) return;
82
118
  // Fetch all translations then write them to the local file system.
83
119
  _ux.spinner.start(`‣ Loading`);
84
120
  const translations = await this.listAllTranslations();
85
- await _translation.writeTranslationsIndexDir(targetDirCtx, translations);
121
+ await _translation.writeTranslationFiles(targetCtx, translations);
86
122
  _ux.spinner.stop();
87
- const action = targetDirCtx.exists ? "updated" : "created";
88
- this.log(`‣ Successfully ${action} the translations directory at ${targetDirCtx.abspath}`);
123
+ const action = targetCtx.exists ? "updated" : "created";
124
+ this.log(`‣ Successfully ${action} the translations directory at ${targetCtx.abspath}`);
89
125
  }
90
- async listAllTranslations(pageParams = {}, translationsFetchedSoFar = []) {
126
+ async listAllTranslations(filters = {}, pageParams = {}, translationsFetchedSoFar = []) {
91
127
  const props = (0, _object.merge)(this.props, {
92
128
  flags: {
93
129
  ...pageParams,
94
130
  limit: _page.MAX_PAGINATION_LIMIT
95
131
  }
96
132
  });
97
- const resp = await this.apiV1.listTranslations(props);
133
+ const resp = await this.apiV1.listTranslations(props, filters);
98
134
  if (!(0, _request.isSuccessResp)(resp)) {
99
135
  const message = (0, _request.formatErrorRespMessage)(resp);
100
136
  this.error(new _error.ApiError(message));
@@ -104,7 +140,7 @@ class TranslationPull extends _baseCommand.default {
104
140
  ...translationsFetchedSoFar,
105
141
  ...entries
106
142
  ];
107
- return pageInfo.after ? this.listAllTranslations({
143
+ return pageInfo.after ? this.listAllTranslations(filters, {
108
144
  after: pageInfo.after
109
145
  }, translations) : translations;
110
146
  }
@@ -122,3 +158,9 @@ TranslationPull.flags = {
122
158
  "hide-uncommitted-changes": _core.Flags.boolean(),
123
159
  force: _core.Flags.boolean()
124
160
  };
161
+ TranslationPull.args = [
162
+ {
163
+ name: "translationRef",
164
+ required: false
165
+ }
166
+ ];
@@ -62,9 +62,10 @@ function _interopRequireWildcard(obj, nodeInterop) {
62
62
  }
63
63
  class TranslationPush extends _baseCommand.default {
64
64
  async run() {
65
- // First read all translation files found for the given command.
65
+ const { flags } = this.props;
66
+ // 1. First read all translation files found for the given command.
66
67
  const target = await _translation.ensureValidCommandTarget(this.props, this.runContext);
67
- const [translations, readErrors] = await _translation.readTranslationFilesForCommandTarget(target);
68
+ const [translations, readErrors] = await _translation.readAllForCommandTarget(target);
68
69
  if (readErrors.length > 0) {
69
70
  this.error((0, _error.formatErrors)(readErrors, {
70
71
  prependBy: "\n\n"
@@ -73,13 +74,17 @@ class TranslationPush extends _baseCommand.default {
73
74
  if (translations.length === 0) {
74
75
  this.error(`No translation files found in ${target.context.abspath}`);
75
76
  }
76
- // Then validate them all ahead of pushing them.
77
+ // 2. Then validate them all ahead of pushing them.
77
78
  _ux.spinner.start(`‣ Validating`);
78
79
  const apiErrors = await _validate.default.validateAll(this.apiV1, this.props, translations);
79
80
  if (apiErrors.length > 0) {
80
- this.error((0, _error.formatErrors)(apiErrors));
81
+ this.error((0, _error.formatErrors)(apiErrors, {
82
+ prependBy: "\n\n"
83
+ }));
81
84
  }
82
- // Finally push up each translation file, abort on the first error.
85
+ _ux.spinner.stop();
86
+ // 3. Finally push up each translation file, abort on the first error.
87
+ _ux.spinner.start(`‣ Pushing`);
83
88
  for (const translation of translations){
84
89
  // eslint-disable-next-line no-await-in-loop
85
90
  const resp = await this.apiV1.upsertTranslation(this.props, {
@@ -93,8 +98,10 @@ class TranslationPush extends _baseCommand.default {
93
98
  this.error((0, _error.formatError)(error));
94
99
  }
95
100
  _ux.spinner.stop();
101
+ // 4. Display a success message.
96
102
  const handledRefs = translations.map((t)=>t.ref);
97
- this.log(`‣ Successfully pushed ${translations.length} translation(s):\n` + (0, _string.indentString)(handledRefs.join("\n"), 4));
103
+ const actioned = flags.commit ? "pushed and committed" : "pushed";
104
+ this.log(`‣ Successfully ${actioned} ${translations.length} translation(s):\n` + (0, _string.indentString)(handledRefs.join("\n"), 4));
98
105
  }
99
106
  }
100
107
  TranslationPush.flags = {
@@ -62,7 +62,7 @@ function _interopRequireWildcard(obj, nodeInterop) {
62
62
  class TranslationValidate extends _baseCommand.default {
63
63
  async run() {
64
64
  const target = await _translation.ensureValidCommandTarget(this.props, this.runContext);
65
- const [translations, readErrors] = await _translation.readTranslationFilesForCommandTarget(target);
65
+ const [translations, readErrors] = await _translation.readAllForCommandTarget(target);
66
66
  if (readErrors.length > 0) {
67
67
  this.error((0, _error.formatErrors)(readErrors, {
68
68
  prependBy: "\n\n"
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "default", {
6
+ enumerable: true,
7
+ get: ()=>Whoami
8
+ });
9
+ const _baseCommand = /*#__PURE__*/ _interopRequireDefault(require("../lib/base-command"));
10
+ const _request = require("../lib/helpers/request");
11
+ const _string = require("../lib/helpers/string");
12
+ function _interopRequireDefault(obj) {
13
+ return obj && obj.__esModule ? obj : {
14
+ default: obj
15
+ };
16
+ }
17
+ class Whoami extends _baseCommand.default {
18
+ async run() {
19
+ const resp = await (0, _request.withSpinner)(()=>this.apiV1.whoami());
20
+ this.log(`‣ Successfully verified the provided service token:`);
21
+ const info = [
22
+ `Account name: ${resp.data.account_name}`,
23
+ `Service token name: ${resp.data.service_token_name}`
24
+ ];
25
+ this.log((0, _string.indentString)(info.join("\n"), 4));
26
+ }
27
+ }
28
+ Whoami.enableJsonFlag = true;
@@ -78,7 +78,7 @@ class WorkflowPull extends _baseCommand.default {
78
78
  if (dirContext.exists) {
79
79
  this.log(`‣ Found \`${dirContext.key}\` at ${dirContext.abspath}`);
80
80
  } else {
81
- const prompt = `Create a new workflow directory \`${dirContext.key}\`?`;
81
+ const prompt = `Create a new workflow directory \`${dirContext.key}\` at ${dirContext.abspath}?`;
82
82
  const input = flags.force || await (0, _ux.promptToConfirm)(prompt);
83
83
  if (!input) return;
84
84
  }
@@ -137,7 +137,7 @@ class WorkflowPull extends _baseCommand.default {
137
137
  exists: true
138
138
  };
139
139
  const targetDirCtx = flags["workflows-dir"] || defaultToCwd;
140
- const prompt = targetDirCtx.exists ? `Pull latest workflows into ${targetDirCtx.abspath}?` : `Create a new workflows directory at ${targetDirCtx.abspath}?`;
140
+ const prompt = targetDirCtx.exists ? `Pull latest workflows into ${targetDirCtx.abspath}?\n This will overwrite the contents of this directory.` : `Create a new workflows directory at ${targetDirCtx.abspath}?`;
141
141
  const input = flags.force || await (0, _ux.promptToConfirm)(prompt);
142
142
  if (!input) return;
143
143
  // Fetch all workflows then write them to the local file system.