@knocklabs/cli 0.1.0-rc.2 → 0.1.0-rc.4

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.
Files changed (38) hide show
  1. package/README.md +82 -6
  2. package/dist/commands/commit/index.js +4 -18
  3. package/dist/commands/commit/promote.js +4 -17
  4. package/dist/commands/translation/list.js +82 -0
  5. package/dist/commands/translation/pull.js +124 -0
  6. package/dist/commands/translation/push.js +130 -0
  7. package/dist/commands/translation/validate.js +122 -0
  8. package/dist/commands/workflow/activate.js +5 -18
  9. package/dist/commands/workflow/new.js +3 -3
  10. package/dist/commands/workflow/pull.js +70 -17
  11. package/dist/commands/workflow/push.js +3 -3
  12. package/dist/commands/workflow/validate.js +3 -3
  13. package/dist/lib/api-v1.js +38 -2
  14. package/dist/lib/base-command.js +2 -2
  15. package/dist/lib/helpers/error.js +16 -8
  16. package/dist/lib/helpers/flag.js +63 -3
  17. package/dist/lib/helpers/fs.js +52 -0
  18. package/dist/lib/helpers/json.js +6 -2
  19. package/dist/lib/helpers/object.js +43 -0
  20. package/dist/lib/helpers/page.js +3 -1
  21. package/dist/lib/helpers/request.js +17 -49
  22. package/dist/lib/helpers/ux.js +42 -0
  23. package/dist/lib/marshal/translation/helpers.js +185 -0
  24. package/dist/lib/marshal/translation/index.js +19 -0
  25. package/dist/lib/marshal/translation/reader.js +118 -0
  26. package/dist/lib/marshal/translation/types.js +4 -0
  27. package/dist/lib/marshal/translation/writer.js +86 -0
  28. package/dist/lib/marshal/workflow/generator.js +46 -5
  29. package/dist/lib/marshal/workflow/helpers.js +2 -0
  30. package/dist/lib/marshal/workflow/reader.js +136 -117
  31. package/dist/lib/marshal/workflow/writer.js +235 -98
  32. package/dist/lib/{helpers/dir-context.js → run-context/helpers.js} +1 -1
  33. package/dist/lib/run-context/index.js +22 -0
  34. package/dist/lib/{run-context.js → run-context/loader.js} +22 -7
  35. package/dist/lib/run-context/types.js +4 -0
  36. package/oclif.manifest.json +253 -1
  37. package/package.json +11 -10
  38. package/dist/lib/helpers/spinner.js +0 -20
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.2 linux-x64 node-v16.4.2
19
+ @knocklabs/cli/0.1.0-rc.4 linux-x64 node-v16.4.2
20
20
  $ knock --help [COMMAND]
21
21
  USAGE
22
22
  $ knock COMMAND
@@ -40,6 +40,10 @@ USAGE
40
40
  * [`knock plugins:uninstall PLUGIN...`](#knock-pluginsuninstall-plugin-1)
41
41
  * [`knock plugins:uninstall PLUGIN...`](#knock-pluginsuninstall-plugin-2)
42
42
  * [`knock plugins update`](#knock-plugins-update)
43
+ * [`knock translation list`](#knock-translation-list)
44
+ * [`knock translation pull`](#knock-translation-pull)
45
+ * [`knock translation push [TRANSLATIONREF]`](#knock-translation-push-translationref)
46
+ * [`knock translation validate [TRANSLATIONREF]`](#knock-translation-validate-translationref)
43
47
  * [`knock workflow activate WORKFLOWKEY`](#knock-workflow-activate-workflowkey)
44
48
  * [`knock workflow get WORKFLOWKEY`](#knock-workflow-get-workflowkey)
45
49
  * [`knock workflow list`](#knock-workflow-list)
@@ -62,7 +66,7 @@ FLAGS
62
66
  --service-token=<value> (required) The service token to authenticate with
63
67
  ```
64
68
 
65
- _See code: [dist/commands/commit/index.ts](https://github.com/knocklabs/knock-cli/blob/v0.1.0-rc.2/dist/commands/commit/index.ts)_
69
+ _See code: [dist/commands/commit/index.ts](https://github.com/knocklabs/knock-cli/blob/v0.1.0-rc.4/dist/commands/commit/index.ts)_
66
70
 
67
71
  ## `knock commit promote`
68
72
 
@@ -94,7 +98,7 @@ DESCRIPTION
94
98
  Display help for knock.
95
99
  ```
96
100
 
97
- _See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v5.2.6/src/commands/help.ts)_
101
+ _See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v5.2.9/src/commands/help.ts)_
98
102
 
99
103
  ## `knock ping`
100
104
 
@@ -114,7 +118,7 @@ EXAMPLES
114
118
  $ knock ping
115
119
  ```
116
120
 
117
- _See code: [dist/commands/ping.ts](https://github.com/knocklabs/knock-cli/blob/v0.1.0-rc.2/dist/commands/ping.ts)_
121
+ _See code: [dist/commands/ping.ts](https://github.com/knocklabs/knock-cli/blob/v0.1.0-rc.4/dist/commands/ping.ts)_
118
122
 
119
123
  ## `knock plugins`
120
124
 
@@ -134,7 +138,7 @@ EXAMPLES
134
138
  $ knock plugins
135
139
  ```
136
140
 
137
- _See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v2.3.2/src/commands/plugins/index.ts)_
141
+ _See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v2.4.7/src/commands/plugins/index.ts)_
138
142
 
139
143
  ## `knock plugins:install PLUGIN...`
140
144
 
@@ -349,6 +353,74 @@ DESCRIPTION
349
353
  Update installed plugins.
350
354
  ```
351
355
 
356
+ ## `knock translation list`
357
+
358
+ ```
359
+ USAGE
360
+ $ knock translation list --service-token <value> [--environment <value>] [--hide-uncommitted-changes] [--after
361
+ <value>] [--before <value>] [--limit <value>] [--json]
362
+
363
+ FLAGS
364
+ --after=<value>
365
+ --before=<value>
366
+ --environment=<value> [default: development]
367
+ --hide-uncommitted-changes
368
+ --limit=<value>
369
+ --service-token=<value> (required) The service token to authenticate with
370
+
371
+ GLOBAL FLAGS
372
+ --json Format output as json.
373
+ ```
374
+
375
+ ## `knock translation pull`
376
+
377
+ ```
378
+ USAGE
379
+ $ knock translation pull --service-token <value> [--environment <value>] [--translations-dir <value> --all]
380
+ [--hide-uncommitted-changes] [--force]
381
+
382
+ FLAGS
383
+ --all
384
+ --environment=<value> [default: development]
385
+ --force
386
+ --hide-uncommitted-changes
387
+ --service-token=<value> (required) The service token to authenticate with
388
+ --translations-dir=<value>
389
+ ```
390
+
391
+ ## `knock translation push [TRANSLATIONREF]`
392
+
393
+ ```
394
+ USAGE
395
+ $ knock translation push [TRANSLATIONREF] --service-token <value> [--environment development] [--translations-dir
396
+ <value> --all] [-m <value> --commit]
397
+
398
+ FLAGS
399
+ -m, --commit-message=<value> Use the given value as the commit message
400
+ --all
401
+ --commit Push and commit the translation(s) at the same time
402
+ --environment=<option> [default: development] Pushing a translation is only allowed in the development
403
+ environment
404
+ <options: development>
405
+ --service-token=<value> (required) The service token to authenticate with
406
+ --translations-dir=<value>
407
+ ```
408
+
409
+ ## `knock translation validate [TRANSLATIONREF]`
410
+
411
+ ```
412
+ USAGE
413
+ $ knock translation validate [TRANSLATIONREF] --service-token <value> [--environment development] [--translations-dir
414
+ <value> --all]
415
+
416
+ FLAGS
417
+ --all
418
+ --environment=<option> [default: development] Validating a workflow is only done in the development environment
419
+ <options: development>
420
+ --service-token=<value> (required) The service token to authenticate with
421
+ --translations-dir=<value>
422
+ ```
423
+
352
424
  ## `knock workflow activate WORKFLOWKEY`
353
425
 
354
426
  ```
@@ -402,12 +474,16 @@ GLOBAL FLAGS
402
474
 
403
475
  ```
404
476
  USAGE
405
- $ knock workflow pull [WORKFLOWKEY] --service-token <value> [--environment <value>] [--hide-uncommitted-changes]
477
+ $ knock workflow pull [WORKFLOWKEY] --service-token <value> [--environment <value>] [--workflows-dir <value>
478
+ --all] [--hide-uncommitted-changes] [--force]
406
479
 
407
480
  FLAGS
481
+ --all
408
482
  --environment=<value> [default: development]
483
+ --force
409
484
  --hide-uncommitted-changes
410
485
  --service-token=<value> (required) The service token to authenticate with
486
+ --workflows-dir=<value>
411
487
  ```
412
488
 
413
489
  ## `knock workflow push [WORKFLOWKEY]`
@@ -7,37 +7,23 @@ Object.defineProperty(exports, "default", {
7
7
  get: ()=>Commit
8
8
  });
9
9
  const _core = require("@oclif/core");
10
- const _enquirer = /*#__PURE__*/ _interopRequireDefault(require("enquirer"));
11
10
  const _baseCommand = /*#__PURE__*/ _interopRequireDefault(require("../../lib/base-command"));
12
11
  const _const = require("../../lib/helpers/const");
13
12
  const _request = require("../../lib/helpers/request");
13
+ const _ux = require("../../lib/helpers/ux");
14
14
  function _interopRequireDefault(obj) {
15
15
  return obj && obj.__esModule ? obj : {
16
16
  default: obj
17
17
  };
18
18
  }
19
- // TODO(KNO-2647): Abstract this out as a helper.
20
- const promptToConfirm = async ()=>{
21
- try {
22
- const { input } = await _enquirer.default.prompt({
23
- type: "confirm",
24
- name: "input",
25
- message: "Commit all changes in the development environment?"
26
- });
27
- return input;
28
- } catch (error) {
29
- console.log(error);
30
- }
31
- };
32
19
  class Commit extends _baseCommand.default {
33
20
  async run() {
34
21
  const { flags } = this.props;
35
22
  // Confirm first as we are about to commit changes to go live in the
36
23
  // development environment, unless forced.
37
- if (!flags.force) {
38
- const input = await promptToConfirm();
39
- if (!input) return;
40
- }
24
+ const prompt = "Commit all changes in the development environment?";
25
+ const input = flags.force || await (0, _ux.promptToConfirm)(prompt);
26
+ if (!input) return;
41
27
  await (0, _request.withSpinner)(()=>this.apiV1.commitAllChanges(this.props));
42
28
  this.log(`‣ Successfully committed all changes in \`${flags.environment}\` environment`);
43
29
  }
@@ -7,35 +7,22 @@ Object.defineProperty(exports, "default", {
7
7
  get: ()=>CommitPromote
8
8
  });
9
9
  const _core = require("@oclif/core");
10
- const _enquirer = /*#__PURE__*/ _interopRequireDefault(require("enquirer"));
11
10
  const _baseCommand = /*#__PURE__*/ _interopRequireDefault(require("../../lib/base-command"));
12
11
  const _request = require("../../lib/helpers/request");
12
+ const _ux = require("../../lib/helpers/ux");
13
13
  function _interopRequireDefault(obj) {
14
14
  return obj && obj.__esModule ? obj : {
15
15
  default: obj
16
16
  };
17
17
  }
18
- const promptToConfirm = async ({ flags })=>{
19
- try {
20
- const { input } = await _enquirer.default.prompt({
21
- type: "confirm",
22
- name: "input",
23
- message: `Promote all changes to \`${flags.to}\` environment?`
24
- });
25
- return input;
26
- } catch (error) {
27
- console.log(error);
28
- }
29
- };
30
18
  class CommitPromote extends _baseCommand.default {
31
19
  async run() {
32
20
  const { flags } = this.props;
33
21
  // Confirm first as we are about to promote changes to go live in the target
34
22
  // environment, unless forced.
35
- if (!flags.force) {
36
- const input = await promptToConfirm(this.props);
37
- if (!input) return;
38
- }
23
+ const prompt = `Promote all changes to \`${flags.to}\` environment?`;
24
+ const input = flags.force || await (0, _ux.promptToConfirm)(prompt);
25
+ if (!input) return;
39
26
  await (0, _request.withSpinner)(()=>this.apiV1.promoteAllChanges(this.props));
40
27
  this.log(`‣ Successfully promoted all changes to \`${flags.to}\` environment`);
41
28
  }
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "default", {
6
+ enumerable: true,
7
+ get: ()=>TranslationList
8
+ });
9
+ const _core = require("@oclif/core");
10
+ const _localeCodes = /*#__PURE__*/ _interopRequireDefault(require("locale-codes"));
11
+ const _baseCommand = /*#__PURE__*/ _interopRequireDefault(require("../../lib/base-command"));
12
+ const _date = require("../../lib/helpers/date");
13
+ const _object = require("../../lib/helpers/object");
14
+ const _page = require("../../lib/helpers/page");
15
+ const _request = require("../../lib/helpers/request");
16
+ function _interopRequireDefault(obj) {
17
+ return obj && obj.__esModule ? obj : {
18
+ default: obj
19
+ };
20
+ }
21
+ class TranslationList extends _baseCommand.default {
22
+ async run() {
23
+ const resp = await this.request();
24
+ const { flags } = this.props;
25
+ if (flags.json) return resp.data;
26
+ this.render(resp.data);
27
+ }
28
+ async request(pageParams = {}) {
29
+ const props = (0, _object.merge)(this.props, {
30
+ flags: {
31
+ ...pageParams
32
+ }
33
+ });
34
+ return (0, _request.withSpinner)(()=>this.apiV1.listTranslations(props));
35
+ }
36
+ async render(data) {
37
+ const { entries } = data;
38
+ const { environment: env , "hide-uncommitted-changes": committedOnly } = this.props.flags;
39
+ const qualifier = env === "development" && !committedOnly ? "(including uncommitted)" : "";
40
+ this.log(`‣ Showing ${entries.length} translations in \`${env}\` environment ${qualifier}\n`);
41
+ /*
42
+ * Translations list table
43
+ */ _core.CliUx.ux.table(entries, {
44
+ language_name: {
45
+ 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
+ }
50
+ },
51
+ locale_code: {
52
+ header: "Locale code"
53
+ },
54
+ namespace: {
55
+ header: "Namespace"
56
+ },
57
+ updated_at: {
58
+ header: "Updated at",
59
+ get: (entry)=>(0, _date.formatDate)(entry.updated_at)
60
+ }
61
+ });
62
+ return this.prompt(data);
63
+ }
64
+ async prompt(data) {
65
+ const { page_info } = data;
66
+ const pageAction = await (0, _page.maybePromptPageAction)(page_info);
67
+ const pageParams = pageAction && (0, _page.paramsForPageAction)(pageAction, page_info);
68
+ if (pageParams) {
69
+ this.log("\n");
70
+ const resp = await this.request(pageParams);
71
+ return this.render(resp.data);
72
+ }
73
+ }
74
+ }
75
+ TranslationList.flags = {
76
+ environment: _core.Flags.string({
77
+ default: "development"
78
+ }),
79
+ "hide-uncommitted-changes": _core.Flags.boolean(),
80
+ ..._page.pageFlags
81
+ };
82
+ TranslationList.enableJsonFlag = true;
@@ -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: ()=>TranslationPull
8
+ });
9
+ const _core = require("@oclif/core");
10
+ const _baseCommand = /*#__PURE__*/ _interopRequireDefault(require("../../lib/base-command"));
11
+ const _error = require("../../lib/helpers/error");
12
+ const _flag = /*#__PURE__*/ _interopRequireWildcard(require("../../lib/helpers/flag"));
13
+ const _object = require("../../lib/helpers/object");
14
+ const _page = require("../../lib/helpers/page");
15
+ const _request = require("../../lib/helpers/request");
16
+ const _ux = require("../../lib/helpers/ux");
17
+ const _translation = /*#__PURE__*/ _interopRequireWildcard(require("../../lib/marshal/translation"));
18
+ function _interopRequireDefault(obj) {
19
+ return obj && obj.__esModule ? obj : {
20
+ default: obj
21
+ };
22
+ }
23
+ function _getRequireWildcardCache(nodeInterop) {
24
+ if (typeof WeakMap !== "function") return null;
25
+ var cacheBabelInterop = new WeakMap();
26
+ var cacheNodeInterop = new WeakMap();
27
+ return (_getRequireWildcardCache = function(nodeInterop) {
28
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
29
+ })(nodeInterop);
30
+ }
31
+ function _interopRequireWildcard(obj, nodeInterop) {
32
+ if (!nodeInterop && obj && obj.__esModule) {
33
+ return obj;
34
+ }
35
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
36
+ return {
37
+ default: obj
38
+ };
39
+ }
40
+ var cache = _getRequireWildcardCache(nodeInterop);
41
+ if (cache && cache.has(obj)) {
42
+ return cache.get(obj);
43
+ }
44
+ var newObj = {};
45
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
46
+ for(var key in obj){
47
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
48
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
49
+ if (desc && (desc.get || desc.set)) {
50
+ Object.defineProperty(newObj, key, desc);
51
+ } else {
52
+ newObj[key] = obj[key];
53
+ }
54
+ }
55
+ }
56
+ newObj.default = obj;
57
+ if (cache) {
58
+ cache.set(obj, newObj);
59
+ }
60
+ return newObj;
61
+ }
62
+ class TranslationPull extends _baseCommand.default {
63
+ async run() {
64
+ 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");
67
+ }
68
+ /*
69
+ * Pull all translations
70
+ */ async pullAllTranslations() {
71
+ 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
77
+ };
78
+ const targetDirCtx = flags["translations-dir"] || defaultToCwd;
79
+ const prompt = targetDirCtx.exists ? `Pull latest translations into ${targetDirCtx.abspath}?\n This will overwrite the contents of this directory.` : `Create a new translations directory at ${targetDirCtx.abspath}?`;
80
+ const input = flags.force || await (0, _ux.promptToConfirm)(prompt);
81
+ if (!input) return;
82
+ // Fetch all translations then write them to the local file system.
83
+ _ux.spinner.start(`‣ Loading`);
84
+ const translations = await this.listAllTranslations();
85
+ await _translation.writeTranslationsIndexDir(targetDirCtx, translations);
86
+ _ux.spinner.stop();
87
+ const action = targetDirCtx.exists ? "updated" : "created";
88
+ this.log(`‣ Successfully ${action} the translations directory at ${targetDirCtx.abspath}`);
89
+ }
90
+ async listAllTranslations(pageParams = {}, translationsFetchedSoFar = []) {
91
+ const props = (0, _object.merge)(this.props, {
92
+ flags: {
93
+ ...pageParams,
94
+ limit: _page.MAX_PAGINATION_LIMIT
95
+ }
96
+ });
97
+ const resp = await this.apiV1.listTranslations(props);
98
+ if (!(0, _request.isSuccessResp)(resp)) {
99
+ const message = (0, _request.formatErrorRespMessage)(resp);
100
+ this.error(new _error.ApiError(message));
101
+ }
102
+ const { entries , page_info: pageInfo } = resp.data;
103
+ const translations = [
104
+ ...translationsFetchedSoFar,
105
+ ...entries
106
+ ];
107
+ return pageInfo.after ? this.listAllTranslations({
108
+ after: pageInfo.after
109
+ }, translations) : translations;
110
+ }
111
+ }
112
+ TranslationPull.flags = {
113
+ environment: _core.Flags.string({
114
+ default: "development"
115
+ }),
116
+ all: _core.Flags.boolean(),
117
+ "translations-dir": _flag.dirPath({
118
+ dependsOn: [
119
+ "all"
120
+ ]
121
+ }),
122
+ "hide-uncommitted-changes": _core.Flags.boolean(),
123
+ force: _core.Flags.boolean()
124
+ };
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "default", {
6
+ enumerable: true,
7
+ get: ()=>TranslationPush
8
+ });
9
+ const _core = require("@oclif/core");
10
+ const _baseCommand = /*#__PURE__*/ _interopRequireDefault(require("../../lib/base-command"));
11
+ const _const = require("../../lib/helpers/const");
12
+ const _error = require("../../lib/helpers/error");
13
+ const _flag = /*#__PURE__*/ _interopRequireWildcard(require("../../lib/helpers/flag"));
14
+ const _request = require("../../lib/helpers/request");
15
+ const _string = require("../../lib/helpers/string");
16
+ const _ux = require("../../lib/helpers/ux");
17
+ const _translation = /*#__PURE__*/ _interopRequireWildcard(require("../../lib/marshal/translation"));
18
+ const _validate = /*#__PURE__*/ _interopRequireDefault(require("./validate"));
19
+ function _interopRequireDefault(obj) {
20
+ return obj && obj.__esModule ? obj : {
21
+ default: obj
22
+ };
23
+ }
24
+ function _getRequireWildcardCache(nodeInterop) {
25
+ if (typeof WeakMap !== "function") return null;
26
+ var cacheBabelInterop = new WeakMap();
27
+ var cacheNodeInterop = new WeakMap();
28
+ return (_getRequireWildcardCache = function(nodeInterop) {
29
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
30
+ })(nodeInterop);
31
+ }
32
+ function _interopRequireWildcard(obj, nodeInterop) {
33
+ if (!nodeInterop && obj && obj.__esModule) {
34
+ return obj;
35
+ }
36
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
37
+ return {
38
+ default: obj
39
+ };
40
+ }
41
+ var cache = _getRequireWildcardCache(nodeInterop);
42
+ if (cache && cache.has(obj)) {
43
+ return cache.get(obj);
44
+ }
45
+ var newObj = {};
46
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
47
+ for(var key in obj){
48
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
49
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
50
+ if (desc && (desc.get || desc.set)) {
51
+ Object.defineProperty(newObj, key, desc);
52
+ } else {
53
+ newObj[key] = obj[key];
54
+ }
55
+ }
56
+ }
57
+ newObj.default = obj;
58
+ if (cache) {
59
+ cache.set(obj, newObj);
60
+ }
61
+ return newObj;
62
+ }
63
+ class TranslationPush extends _baseCommand.default {
64
+ async run() {
65
+ // First read all translation files found for the given command.
66
+ const target = await _translation.ensureValidCommandTarget(this.props, this.runContext);
67
+ const [translations, readErrors] = await _translation.readTranslationFilesForCommandTarget(target);
68
+ if (readErrors.length > 0) {
69
+ this.error((0, _error.formatErrors)(readErrors, {
70
+ prependBy: "\n\n"
71
+ }));
72
+ }
73
+ if (translations.length === 0) {
74
+ this.error(`No translation files found in ${target.context.abspath}`);
75
+ }
76
+ // Then validate them all ahead of pushing them.
77
+ _ux.spinner.start(`‣ Validating`);
78
+ const apiErrors = await _validate.default.validateAll(this.apiV1, this.props, translations);
79
+ if (apiErrors.length > 0) {
80
+ this.error((0, _error.formatErrors)(apiErrors));
81
+ }
82
+ // Finally push up each translation file, abort on the first error.
83
+ for (const translation of translations){
84
+ // eslint-disable-next-line no-await-in-loop
85
+ const resp = await this.apiV1.upsertTranslation(this.props, {
86
+ locale_code: translation.localeCode,
87
+ namespace: translation.namespace,
88
+ content: translation.content
89
+ });
90
+ if ((0, _request.isSuccessResp)(resp)) continue;
91
+ const message = (0, _request.formatErrorRespMessage)(resp);
92
+ const error = new _error.SourceError(message, translation.abspath, "ApiError");
93
+ this.error((0, _error.formatError)(error));
94
+ }
95
+ _ux.spinner.stop();
96
+ const handledRefs = translations.map((t)=>t.ref);
97
+ this.log(`‣ Successfully pushed ${translations.length} translation(s):\n` + (0, _string.indentString)(handledRefs.join("\n"), 4));
98
+ }
99
+ }
100
+ TranslationPush.flags = {
101
+ environment: _core.Flags.string({
102
+ summary: "Pushing a translation is only allowed in the development environment",
103
+ default: _const.KnockEnv.Development,
104
+ options: [
105
+ _const.KnockEnv.Development
106
+ ]
107
+ }),
108
+ all: _core.Flags.boolean(),
109
+ "translations-dir": _flag.dirPath({
110
+ dependsOn: [
111
+ "all"
112
+ ]
113
+ }),
114
+ commit: _core.Flags.boolean({
115
+ summary: "Push and commit the translation(s) at the same time"
116
+ }),
117
+ "commit-message": _core.Flags.string({
118
+ summary: "Use the given value as the commit message",
119
+ char: "m",
120
+ dependsOn: [
121
+ "commit"
122
+ ]
123
+ })
124
+ };
125
+ TranslationPush.args = [
126
+ {
127
+ name: "translationRef",
128
+ required: false
129
+ }
130
+ ];
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "default", {
6
+ enumerable: true,
7
+ get: ()=>TranslationValidate
8
+ });
9
+ const _core = require("@oclif/core");
10
+ const _baseCommand = /*#__PURE__*/ _interopRequireDefault(require("../../lib/base-command"));
11
+ const _const = require("../../lib/helpers/const");
12
+ const _error = require("../../lib/helpers/error");
13
+ const _flag = /*#__PURE__*/ _interopRequireWildcard(require("../../lib/helpers/flag"));
14
+ const _request = require("../../lib/helpers/request");
15
+ const _string = require("../../lib/helpers/string");
16
+ const _ux = require("../../lib/helpers/ux");
17
+ const _translation = /*#__PURE__*/ _interopRequireWildcard(require("../../lib/marshal/translation"));
18
+ function _interopRequireDefault(obj) {
19
+ return obj && obj.__esModule ? obj : {
20
+ default: obj
21
+ };
22
+ }
23
+ function _getRequireWildcardCache(nodeInterop) {
24
+ if (typeof WeakMap !== "function") return null;
25
+ var cacheBabelInterop = new WeakMap();
26
+ var cacheNodeInterop = new WeakMap();
27
+ return (_getRequireWildcardCache = function(nodeInterop) {
28
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
29
+ })(nodeInterop);
30
+ }
31
+ function _interopRequireWildcard(obj, nodeInterop) {
32
+ if (!nodeInterop && obj && obj.__esModule) {
33
+ return obj;
34
+ }
35
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
36
+ return {
37
+ default: obj
38
+ };
39
+ }
40
+ var cache = _getRequireWildcardCache(nodeInterop);
41
+ if (cache && cache.has(obj)) {
42
+ return cache.get(obj);
43
+ }
44
+ var newObj = {};
45
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
46
+ for(var key in obj){
47
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
48
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
49
+ if (desc && (desc.get || desc.set)) {
50
+ Object.defineProperty(newObj, key, desc);
51
+ } else {
52
+ newObj[key] = obj[key];
53
+ }
54
+ }
55
+ }
56
+ newObj.default = obj;
57
+ if (cache) {
58
+ cache.set(obj, newObj);
59
+ }
60
+ return newObj;
61
+ }
62
+ class TranslationValidate extends _baseCommand.default {
63
+ async run() {
64
+ const target = await _translation.ensureValidCommandTarget(this.props, this.runContext);
65
+ const [translations, readErrors] = await _translation.readTranslationFilesForCommandTarget(target);
66
+ if (readErrors.length > 0) {
67
+ this.error((0, _error.formatErrors)(readErrors, {
68
+ prependBy: "\n\n"
69
+ }));
70
+ }
71
+ if (translations.length === 0) {
72
+ this.error(`No translation files found in ${target.context.abspath}`);
73
+ }
74
+ _ux.spinner.start(`‣ Validating`);
75
+ const apiErrors = await TranslationValidate.validateAll(this.apiV1, this.props, translations);
76
+ if (apiErrors.length > 0) {
77
+ this.error((0, _error.formatErrors)(apiErrors, {
78
+ prependBy: "\n\n"
79
+ }));
80
+ }
81
+ _ux.spinner.stop();
82
+ const handledRefs = translations.map((t)=>t.ref);
83
+ this.log(`‣ Successfully validated ${translations.length} translation(s):\n` + (0, _string.indentString)(handledRefs.join("\n"), 4));
84
+ }
85
+ static async validateAll(api, props, translations) {
86
+ // TODO: Throw if a non validation error (e.g. authentication error) instead
87
+ // of printing out same error messages repeatedly.
88
+ const errorPromises = translations.map(async (translation)=>{
89
+ const resp = await api.validateTranslation(props, {
90
+ locale_code: translation.localeCode,
91
+ namespace: translation.namespace,
92
+ content: translation.content
93
+ });
94
+ if ((0, _request.isSuccessResp)(resp)) return;
95
+ const message = (0, _request.formatErrorRespMessage)(resp);
96
+ return new _error.SourceError(message, translation.abspath, "ApiError");
97
+ });
98
+ const errors = (await Promise.all(errorPromises)).filter((e)=>Boolean(e));
99
+ return errors;
100
+ }
101
+ }
102
+ TranslationValidate.flags = {
103
+ environment: _core.Flags.string({
104
+ summary: "Validating a workflow is only done in the development environment",
105
+ default: _const.KnockEnv.Development,
106
+ options: [
107
+ _const.KnockEnv.Development
108
+ ]
109
+ }),
110
+ all: _core.Flags.boolean(),
111
+ "translations-dir": _flag.dirPath({
112
+ dependsOn: [
113
+ "all"
114
+ ]
115
+ })
116
+ };
117
+ TranslationValidate.args = [
118
+ {
119
+ name: "translationRef",
120
+ required: false
121
+ }
122
+ ];