@knocklabs/cli 0.3.1 → 1.0.0-rc.1

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 (63) hide show
  1. package/README.md +258 -55
  2. package/dist/commands/branch/delete.js +4 -1
  3. package/dist/commands/branch/merge.js +82 -0
  4. package/dist/commands/channel/list.js +73 -0
  5. package/dist/commands/environment/list.js +73 -0
  6. package/dist/commands/guide/new.js +276 -0
  7. package/dist/commands/guide/pull.js +5 -6
  8. package/dist/commands/guide/push.js +1 -1
  9. package/dist/commands/guide/validate.js +1 -1
  10. package/dist/commands/init.js +108 -0
  11. package/dist/commands/layout/new.js +228 -0
  12. package/dist/commands/layout/pull.js +5 -6
  13. package/dist/commands/layout/push.js +1 -1
  14. package/dist/commands/layout/validate.js +1 -1
  15. package/dist/commands/message-type/new.js +228 -0
  16. package/dist/commands/message-type/pull.js +5 -6
  17. package/dist/commands/message-type/push.js +1 -1
  18. package/dist/commands/message-type/validate.js +1 -1
  19. package/dist/commands/partial/new.js +274 -0
  20. package/dist/commands/partial/pull.js +5 -6
  21. package/dist/commands/partial/push.js +1 -1
  22. package/dist/commands/partial/validate.js +1 -1
  23. package/dist/commands/pull.js +7 -2
  24. package/dist/commands/push.js +6 -4
  25. package/dist/commands/translation/pull.js +1 -1
  26. package/dist/commands/translation/push.js +1 -1
  27. package/dist/commands/translation/validate.js +1 -1
  28. package/dist/commands/workflow/new.js +179 -54
  29. package/dist/commands/workflow/pull.js +6 -8
  30. package/dist/commands/workflow/push.js +1 -1
  31. package/dist/commands/workflow/validate.js +1 -1
  32. package/dist/lib/api-v1.js +23 -2
  33. package/dist/lib/auth.js +1 -1
  34. package/dist/lib/base-command.js +18 -15
  35. package/dist/lib/helpers/project-config.js +158 -0
  36. package/dist/lib/helpers/request.js +1 -2
  37. package/dist/lib/helpers/string.js +4 -4
  38. package/dist/lib/helpers/typegen.js +1 -1
  39. package/dist/lib/marshal/email-layout/generator.js +152 -0
  40. package/dist/lib/marshal/email-layout/helpers.js +6 -9
  41. package/dist/lib/marshal/email-layout/index.js +1 -0
  42. package/dist/lib/marshal/email-layout/writer.js +15 -3
  43. package/dist/lib/marshal/guide/generator.js +163 -0
  44. package/dist/lib/marshal/guide/helpers.js +6 -10
  45. package/dist/lib/marshal/guide/index.js +1 -0
  46. package/dist/lib/marshal/guide/writer.js +5 -9
  47. package/dist/lib/marshal/message-type/generator.js +139 -0
  48. package/dist/lib/marshal/message-type/helpers.js +6 -10
  49. package/dist/lib/marshal/message-type/index.js +1 -0
  50. package/dist/lib/marshal/message-type/writer.js +5 -1
  51. package/dist/lib/marshal/partial/generator.js +159 -0
  52. package/dist/lib/marshal/partial/helpers.js +6 -10
  53. package/dist/lib/marshal/partial/index.js +1 -0
  54. package/dist/lib/marshal/partial/writer.js +3 -0
  55. package/dist/lib/marshal/translation/helpers.js +6 -10
  56. package/dist/lib/marshal/translation/processor.isomorphic.js +4 -4
  57. package/dist/lib/marshal/translation/writer.js +2 -2
  58. package/dist/lib/marshal/workflow/generator.js +175 -19
  59. package/dist/lib/marshal/workflow/helpers.js +7 -10
  60. package/dist/lib/run-context/loader.js +5 -0
  61. package/dist/lib/templates.js +131 -0
  62. package/oclif.manifest.json +1075 -471
  63. package/package.json +10 -8
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: Object.getOwnPropertyDescriptor(all, name).get
9
+ });
10
+ }
11
+ _export(exports, {
12
+ get generateMessageTypeDir () {
13
+ return generateMessageTypeDir;
14
+ },
15
+ get generateMessageTypeFromTemplate () {
16
+ return generateMessageTypeFromTemplate;
17
+ },
18
+ get scaffoldMessageTypeDirBundle () {
19
+ return scaffoldMessageTypeDirBundle;
20
+ },
21
+ get validateMessageTypeKey () {
22
+ return validateMessageTypeKey;
23
+ }
24
+ });
25
+ const _lodash = require("lodash");
26
+ const _string = require("../../helpers/string");
27
+ const _templates = /*#__PURE__*/ _interop_require_wildcard(require("../../templates"));
28
+ const _constisomorphic = require("../shared/const.isomorphic");
29
+ const _processorisomorphic = require("./processor.isomorphic");
30
+ const _reader = require("./reader");
31
+ const _writer = require("./writer");
32
+ function _getRequireWildcardCache(nodeInterop) {
33
+ if (typeof WeakMap !== "function") return null;
34
+ var cacheBabelInterop = new WeakMap();
35
+ var cacheNodeInterop = new WeakMap();
36
+ return (_getRequireWildcardCache = function(nodeInterop) {
37
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
38
+ })(nodeInterop);
39
+ }
40
+ function _interop_require_wildcard(obj, nodeInterop) {
41
+ if (!nodeInterop && obj && obj.__esModule) {
42
+ return obj;
43
+ }
44
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
45
+ return {
46
+ default: obj
47
+ };
48
+ }
49
+ var cache = _getRequireWildcardCache(nodeInterop);
50
+ if (cache && cache.has(obj)) {
51
+ return cache.get(obj);
52
+ }
53
+ var newObj = {
54
+ __proto__: null
55
+ };
56
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
57
+ for(var key in obj){
58
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
59
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
60
+ if (desc && (desc.get || desc.set)) {
61
+ Object.defineProperty(newObj, key, desc);
62
+ } else {
63
+ newObj[key] = obj[key];
64
+ }
65
+ }
66
+ }
67
+ newObj.default = obj;
68
+ if (cache) {
69
+ cache.set(obj, newObj);
70
+ }
71
+ return newObj;
72
+ }
73
+ const validateMessageTypeKey = (input)=>{
74
+ if (!(0, _string.checkSlugifiedFormat)(input, {
75
+ onlyLowerCase: true
76
+ })) {
77
+ return "must include only lowercase alphanumeric, dash, or underscore characters";
78
+ }
79
+ return undefined;
80
+ };
81
+ /*
82
+ * Returns the default scaffolded preview content.
83
+ */ const defaultPreviewContent = ()=>{
84
+ return `{{ name }}`;
85
+ };
86
+ /*
87
+ * Scaffolds a new message type directory bundle with default content.
88
+ */ const scaffoldMessageTypeDirBundle = (attrs)=>{
89
+ const previewFilePath = "preview.txt";
90
+ const defaultPreview = defaultPreviewContent();
91
+ const messageTypeJson = {
92
+ name: attrs.name,
93
+ description: "",
94
+ variants: [
95
+ {
96
+ key: "default",
97
+ name: "Default",
98
+ fields: []
99
+ }
100
+ ],
101
+ [`preview${_constisomorphic.FILEPATH_MARKER}`]: previewFilePath
102
+ };
103
+ return {
104
+ [_processorisomorphic.MESSAGE_TYPE_JSON]: messageTypeJson,
105
+ [previewFilePath]: defaultPreview
106
+ };
107
+ };
108
+ const generateMessageTypeDir = async (messageTypeDirCtx, attrs)=>{
109
+ const bundle = scaffoldMessageTypeDirBundle(attrs);
110
+ return (0, _writer.writeMessageTypeDirFromBundle)(messageTypeDirCtx, bundle);
111
+ };
112
+ const generateMessageTypeFromTemplate = async (messageTypeDirCtx, templateString, attrs)=>{
113
+ let tempDir;
114
+ try {
115
+ // Download the template directory into a temp directory
116
+ tempDir = await _templates.downloadTemplate(templateString);
117
+ // Create a message type directory context for the temp directory
118
+ const tempMessageTypeDirCtx = {
119
+ type: "message_type",
120
+ key: "temp",
121
+ abspath: tempDir,
122
+ exists: true
123
+ };
124
+ // Read the message_type.json from the temp directory we downloaded
125
+ const [messageType, errors] = await (0, _reader.readMessageTypeDir)(tempMessageTypeDirCtx, {
126
+ withExtractedFiles: true
127
+ });
128
+ if (errors.length > 0 || !messageType) {
129
+ throw new Error(`Invalid message type template: ${errors.join(", ")}`);
130
+ }
131
+ // Modify the message type data with the new attributes
132
+ const messageTypeData = (0, _lodash.cloneDeep)(messageType);
133
+ messageTypeData.name = attrs.name;
134
+ // Finally, we write the message type into the target message type directory
135
+ await (0, _writer.writeMessageTypeDirFromData)(messageTypeDirCtx, messageTypeData);
136
+ } finally{
137
+ await _templates.cleanupTempDir(tempDir);
138
+ }
139
+ };
@@ -25,6 +25,7 @@ _export(exports, {
25
25
  const _nodepath = /*#__PURE__*/ _interop_require_wildcard(require("node:path"));
26
26
  const _core = require("@oclif/core");
27
27
  const _fsextra = /*#__PURE__*/ _interop_require_wildcard(require("fs-extra"));
28
+ const _projectconfig = require("../../helpers/project-config");
28
29
  const _processorisomorphic = require("./processor.isomorphic");
29
30
  function _getRequireWildcardCache(nodeInterop) {
30
31
  if (typeof WeakMap !== "function") return null;
@@ -74,7 +75,7 @@ const lsMessageTypeJson = async (dirPath)=>{
74
75
  return exists ? messageTypeJsonPath : undefined;
75
76
  };
76
77
  const isMessageTypeDir = async (dirPath)=>Boolean(await lsMessageTypeJson(dirPath));
77
- const ensureValidCommandTarget = async (props, runContext)=>{
78
+ const ensureValidCommandTarget = async (props, runContext, projectConfig)=>{
78
79
  const { args, flags } = props;
79
80
  const { commandId, resourceDir: resourceDirCtx, cwd: runCwd } = runContext;
80
81
  // If the target resource is a different type than the current resource dir
@@ -86,6 +87,8 @@ const ensureValidCommandTarget = async (props, runContext)=>{
86
87
  if (flags.all && args.messageTypeKey) {
87
88
  return _core.ux.error(`messageTypeKey arg \`${args.messageTypeKey}\` cannot also be provided when using --all`);
88
89
  }
90
+ // Default to knock project config first if present, otherwise cwd.
91
+ const messageTypesIndexDirCtx = await (0, _projectconfig.resolveResourceDir)(projectConfig, "message_type", runCwd);
89
92
  // --all flag is given, which means no message type key arg.
90
93
  if (flags.all) {
91
94
  // If --all flag used inside a message type directory, then require a message
@@ -93,16 +96,9 @@ const ensureValidCommandTarget = async (props, runContext)=>{
93
96
  if (resourceDirCtx && !flags["message-types-dir"]) {
94
97
  return _core.ux.error("Missing required flag message-types-dir");
95
98
  }
96
- // Targeting all message type dirs in the message types index dir.
97
- // TODO: Default to the knock project config first if present before cwd.
98
- const defaultToCwd = {
99
- abspath: runCwd,
100
- exists: true
101
- };
102
- const indexDirCtx = flags["message-types-dir"] || defaultToCwd;
103
99
  return {
104
100
  type: "messageTypesIndexDir",
105
- context: indexDirCtx
101
+ context: flags["message-types-dir"] || messageTypesIndexDirCtx
106
102
  };
107
103
  }
108
104
  // Message type key arg is given, which means no --all flag.
@@ -110,7 +106,7 @@ const ensureValidCommandTarget = async (props, runContext)=>{
110
106
  if (resourceDirCtx && resourceDirCtx.key !== args.messageTypeKey) {
111
107
  return _core.ux.error(`Cannot run ${commandId} \`${args.messageTypeKey}\` inside another message type directory:\n${resourceDirCtx.key}`);
112
108
  }
113
- const targetDirPath = resourceDirCtx ? resourceDirCtx.abspath : _nodepath.resolve(runCwd, args.messageTypeKey);
109
+ const targetDirPath = resourceDirCtx ? resourceDirCtx.abspath : _nodepath.resolve(messageTypesIndexDirCtx.abspath, args.messageTypeKey);
114
110
  const messageTypeDirCtx = {
115
111
  type: "message_type",
116
112
  key: args.messageTypeKey,
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
+ _export_star(require("./generator"), exports);
5
6
  _export_star(require("./helpers"), exports);
6
7
  _export_star(require("./processor.isomorphic"), exports);
7
8
  _export_star(require("./reader"), exports);
@@ -12,6 +12,9 @@ _export(exports, {
12
12
  get pruneMessageTypesIndexDir () {
13
13
  return pruneMessageTypesIndexDir;
14
14
  },
15
+ get writeMessageTypeDirFromBundle () {
16
+ return writeMessageTypeDirFromBundle;
17
+ },
15
18
  get writeMessageTypeDirFromData () {
16
19
  return writeMessageTypeDirFromData;
17
20
  },
@@ -94,10 +97,11 @@ const writeMessageTypeDirFromData = async (messageTypeDirCtx, remoteMessageType,
94
97
  await _fsextra.emptyDir(messageTypeDirCtx.abspath);
95
98
  }
96
99
  const promises = Object.entries(messageTypeDirBundle).map(([relpath, fileContent])=>{
100
+ var _fileContent_toString;
97
101
  const filePath = _nodepath.resolve(messageTypeDirCtx.abspath, relpath);
98
102
  return relpath === _processorisomorphic.MESSAGE_TYPE_JSON ? _fsextra.outputJson(filePath, fileContent, {
99
103
  spaces: _json.DOUBLE_SPACES
100
- }) : _fsextra.outputFile(filePath, fileContent !== null && fileContent !== void 0 ? fileContent : "");
104
+ }) : _fsextra.outputFile(filePath, (_fileContent_toString = fileContent.toString()) !== null && _fileContent_toString !== void 0 ? _fileContent_toString : "");
101
105
  });
102
106
  await Promise.all(promises);
103
107
  } catch (error) {
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: Object.getOwnPropertyDescriptor(all, name).get
9
+ });
10
+ }
11
+ _export(exports, {
12
+ get generatePartialDir () {
13
+ return generatePartialDir;
14
+ },
15
+ get generatePartialFromTemplate () {
16
+ return generatePartialFromTemplate;
17
+ },
18
+ get scaffoldPartialDirBundle () {
19
+ return scaffoldPartialDirBundle;
20
+ },
21
+ get validatePartialKey () {
22
+ return validatePartialKey;
23
+ }
24
+ });
25
+ const _lodash = require("lodash");
26
+ const _string = require("../../helpers/string");
27
+ const _templates = /*#__PURE__*/ _interop_require_wildcard(require("../../templates"));
28
+ const _constisomorphic = require("../shared/const.isomorphic");
29
+ const _processorisomorphic = require("./processor.isomorphic");
30
+ const _reader = require("./reader");
31
+ const _types = require("./types");
32
+ const _writer = require("./writer");
33
+ function _getRequireWildcardCache(nodeInterop) {
34
+ if (typeof WeakMap !== "function") return null;
35
+ var cacheBabelInterop = new WeakMap();
36
+ var cacheNodeInterop = new WeakMap();
37
+ return (_getRequireWildcardCache = function(nodeInterop) {
38
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
39
+ })(nodeInterop);
40
+ }
41
+ function _interop_require_wildcard(obj, nodeInterop) {
42
+ if (!nodeInterop && obj && obj.__esModule) {
43
+ return obj;
44
+ }
45
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
46
+ return {
47
+ default: obj
48
+ };
49
+ }
50
+ var cache = _getRequireWildcardCache(nodeInterop);
51
+ if (cache && cache.has(obj)) {
52
+ return cache.get(obj);
53
+ }
54
+ var newObj = {
55
+ __proto__: null
56
+ };
57
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
58
+ for(var key in obj){
59
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
60
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
61
+ if (desc && (desc.get || desc.set)) {
62
+ Object.defineProperty(newObj, key, desc);
63
+ } else {
64
+ newObj[key] = obj[key];
65
+ }
66
+ }
67
+ }
68
+ newObj.default = obj;
69
+ if (cache) {
70
+ cache.set(obj, newObj);
71
+ }
72
+ return newObj;
73
+ }
74
+ const validatePartialKey = (input)=>{
75
+ if (!(0, _string.checkSlugifiedFormat)(input, {
76
+ onlyLowerCase: true
77
+ })) {
78
+ return "must include only lowercase alphanumeric, dash, or underscore characters";
79
+ }
80
+ return undefined;
81
+ };
82
+ /*
83
+ * Maps the partial type to the correct file extension.
84
+ */ const partialTypeToFileExt = (type)=>{
85
+ switch(type){
86
+ case _types.PartialType.Html:
87
+ return "html";
88
+ case _types.PartialType.Json:
89
+ return "json";
90
+ case _types.PartialType.Markdown:
91
+ return "md";
92
+ case _types.PartialType.Text:
93
+ default:
94
+ return "txt";
95
+ }
96
+ };
97
+ /*
98
+ * Returns the default scaffolded content for a partial based on its type.
99
+ */ const defaultContentForType = (type)=>{
100
+ switch(type){
101
+ case _types.PartialType.Html:
102
+ return "<div>{{ content }}</div>";
103
+ case _types.PartialType.Json:
104
+ return "{}";
105
+ case _types.PartialType.Markdown:
106
+ return "**{{ content }}**";
107
+ case _types.PartialType.Text:
108
+ default:
109
+ return "{{ content }}";
110
+ }
111
+ };
112
+ /*
113
+ * Scaffolds a new partial directory bundle with default content.
114
+ */ const scaffoldPartialDirBundle = (attrs)=>{
115
+ const fileExt = partialTypeToFileExt(attrs.type);
116
+ const contentFilePath = `content.${fileExt}`;
117
+ const defaultContent = defaultContentForType(attrs.type);
118
+ const partialJson = {
119
+ name: attrs.name,
120
+ type: attrs.type,
121
+ [`content${_constisomorphic.FILEPATH_MARKER}`]: contentFilePath
122
+ };
123
+ return {
124
+ [_processorisomorphic.PARTIAL_JSON]: partialJson,
125
+ [contentFilePath]: defaultContent
126
+ };
127
+ };
128
+ const generatePartialDir = async (partialDirCtx, attrs)=>{
129
+ const bundle = scaffoldPartialDirBundle(attrs);
130
+ return (0, _writer.writePartialDirFromBundle)(partialDirCtx, bundle);
131
+ };
132
+ const generatePartialFromTemplate = async (partialDirCtx, templateString, attrs)=>{
133
+ let tempDir;
134
+ try {
135
+ // Download the template directory into a temp directory
136
+ tempDir = await _templates.downloadTemplate(templateString);
137
+ // Create a partial directory context for the temp directory
138
+ const tempPartialDirCtx = {
139
+ type: "partial",
140
+ key: "temp",
141
+ abspath: tempDir,
142
+ exists: true
143
+ };
144
+ // Read the partial.json from the temp directory we downloaded
145
+ const [partial, errors] = await (0, _reader.readPartialDir)(tempPartialDirCtx, {
146
+ withExtractedFiles: true
147
+ });
148
+ if (errors.length > 0 || !partial) {
149
+ throw new Error(`Invalid partial template: ${errors.join(", ")}`);
150
+ }
151
+ // Modify the partial data with the new attributes
152
+ const partialData = (0, _lodash.cloneDeep)(partial);
153
+ partialData.name = attrs.name;
154
+ // Finally, we write the partial into the target partial directory
155
+ await (0, _writer.writePartialDirFromData)(partialDirCtx, partialData);
156
+ } finally{
157
+ await _templates.cleanupTempDir(tempDir);
158
+ }
159
+ };
@@ -25,6 +25,7 @@ _export(exports, {
25
25
  const _nodepath = /*#__PURE__*/ _interop_require_wildcard(require("node:path"));
26
26
  const _core = require("@oclif/core");
27
27
  const _fsextra = /*#__PURE__*/ _interop_require_wildcard(require("fs-extra"));
28
+ const _projectconfig = require("../../helpers/project-config");
28
29
  const _processorisomorphic = require("./processor.isomorphic");
29
30
  function _getRequireWildcardCache(nodeInterop) {
30
31
  if (typeof WeakMap !== "function") return null;
@@ -74,7 +75,7 @@ const lsPartialJson = async (dirPath)=>{
74
75
  return exists ? partialJsonPath : undefined;
75
76
  };
76
77
  const isPartialDir = async (dirPath)=>Boolean(await lsPartialJson(dirPath));
77
- const ensureValidCommandTarget = async (props, runContext)=>{
78
+ const ensureValidCommandTarget = async (props, runContext, projectConfig)=>{
78
79
  const { args, flags } = props;
79
80
  const { commandId, resourceDir: resourceDirCtx, cwd: runCwd } = runContext;
80
81
  // If the target resource is a different type than the current resource dir
@@ -86,6 +87,8 @@ const ensureValidCommandTarget = async (props, runContext)=>{
86
87
  if (flags.all && args.partialKey) {
87
88
  return _core.ux.error(`partialKey arg \`${args.partialKey}\` cannot also be provided when using --all`);
88
89
  }
90
+ // Default to knock project config first if present, otherwise cwd.
91
+ const partialsIndexDirCtx = await (0, _projectconfig.resolveResourceDir)(projectConfig, "partial", runCwd);
89
92
  // --all flag is given, which means no partial key arg.
90
93
  if (flags.all) {
91
94
  // If --all flag used inside a partial directory, then require a partials
@@ -93,16 +96,9 @@ const ensureValidCommandTarget = async (props, runContext)=>{
93
96
  if (resourceDirCtx && !flags["partials-dir"]) {
94
97
  return _core.ux.error("Missing required flag partials-dir");
95
98
  }
96
- // Targeting all partial dirs in the partials index dir.
97
- // TODO: Default to the knock project config first if present before cwd.
98
- const defaultToCwd = {
99
- abspath: runCwd,
100
- exists: true
101
- };
102
- const indexDirCtx = flags["partials-dir"] || defaultToCwd;
103
99
  return {
104
100
  type: "partialsIndexDir",
105
- context: indexDirCtx
101
+ context: flags["partials-dir"] || partialsIndexDirCtx
106
102
  };
107
103
  }
108
104
  // Partial key arg is given, which means no --all flag.
@@ -110,7 +106,7 @@ const ensureValidCommandTarget = async (props, runContext)=>{
110
106
  if (resourceDirCtx && resourceDirCtx.key !== args.partialKey) {
111
107
  return _core.ux.error(`Cannot run ${commandId} \`${args.partialKey}\` inside another partial directory:\n${resourceDirCtx.key}`);
112
108
  }
113
- const targetDirPath = resourceDirCtx ? resourceDirCtx.abspath : _nodepath.resolve(runCwd, args.partialKey);
109
+ const targetDirPath = resourceDirCtx ? resourceDirCtx.abspath : _nodepath.resolve(partialsIndexDirCtx.abspath, args.partialKey);
114
110
  const partialDirCtx = {
115
111
  type: "partial",
116
112
  key: args.partialKey,
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
+ _export_star(require("./generator"), exports);
5
6
  _export_star(require("./helpers"), exports);
6
7
  _export_star(require("./processor.isomorphic"), exports);
7
8
  _export_star(require("./reader"), exports);
@@ -12,6 +12,9 @@ _export(exports, {
12
12
  get prunePartialsIndexDir () {
13
13
  return prunePartialsIndexDir;
14
14
  },
15
+ get writePartialDirFromBundle () {
16
+ return writePartialDirFromBundle;
17
+ },
15
18
  get writePartialDirFromData () {
16
19
  return writePartialDirFromData;
17
20
  },
@@ -42,6 +42,7 @@ const _core = require("@oclif/core");
42
42
  const _fsextra = /*#__PURE__*/ _interop_require_wildcard(require("fs-extra"));
43
43
  const _localecodes = /*#__PURE__*/ _interop_require_default(require("locale-codes"));
44
44
  const _fs = require("../../helpers/fs");
45
+ const _projectconfig = require("../../helpers/project-config");
45
46
  const _processorisomorphic = require("./processor.isomorphic");
46
47
  function _interop_require_default(obj) {
47
48
  return obj && obj.__esModule ? obj : {
@@ -136,7 +137,7 @@ const parseTranslationRef = (reference)=>{
136
137
  // Invalid pattern.
137
138
  return undefined;
138
139
  };
139
- const ensureValidCommandTarget = async (props, runContext)=>{
140
+ const ensureValidCommandTarget = async (props, runContext, projectConfig)=>{
140
141
  const { flags, args } = props;
141
142
  const { commandId, resourceDir: resourceDirCtx, cwd: runCwd } = runContext;
142
143
  // Error, trying to run the command not in a translation directory.
@@ -147,6 +148,8 @@ const ensureValidCommandTarget = async (props, runContext)=>{
147
148
  if (!args.translationRef && !flags.all) {
148
149
  _core.ux.error("At least one of translation ref arg or --all flag must be given");
149
150
  }
151
+ // Default to knock project config first if present, otherwise cwd.
152
+ const translationsIndexDirCtx = await (0, _projectconfig.resolveResourceDir)(projectConfig, "translation", runCwd);
150
153
  // No translationRef arg, which means --all flag is used.
151
154
  if (!args.translationRef) {
152
155
  // Targeting all translation files in the current locale directory.
@@ -156,16 +159,9 @@ const ensureValidCommandTarget = async (props, runContext)=>{
156
159
  context: resourceDirCtx
157
160
  };
158
161
  }
159
- // Targeting all translation files in the translations index dir.
160
- // TODO: Default to the knock project config first if present before cwd.
161
- const defaultToCwd = {
162
- abspath: runCwd,
163
- exists: true
164
- };
165
- const indexDirCtx = flags["translations-dir"] || defaultToCwd;
166
162
  return {
167
163
  type: "translationsIndexDir",
168
- context: indexDirCtx
164
+ context: flags["translations-dir"] || translationsIndexDirCtx
169
165
  };
170
166
  }
171
167
  // From this point on, we have translationRef so parse and validate the format.
@@ -178,7 +174,7 @@ const ensureValidCommandTarget = async (props, runContext)=>{
178
174
  if (resourceDirCtx && resourceDirCtx.key !== localeCode) {
179
175
  return _core.ux.error(`Cannot run ${commandId} with \`${args.translationRef}\` inside a ${resourceDirCtx.key} directory`);
180
176
  }
181
- const targetDirPath = resourceDirCtx ? resourceDirCtx.abspath : flags["translations-dir"] ? _nodepath.resolve(flags["translations-dir"].abspath, localeCode) : _nodepath.resolve(runCwd, localeCode);
177
+ const targetDirPath = resourceDirCtx ? resourceDirCtx.abspath : flags["translations-dir"] ? _nodepath.resolve(flags["translations-dir"].abspath, localeCode) : _nodepath.resolve(translationsIndexDirCtx.abspath, localeCode);
182
178
  // Got translationRef arg but no --all flag, which means target only a single
183
179
  // translation file.
184
180
  if (!flags.all) {
@@ -32,14 +32,14 @@ const SUPPORTED_TRANSLATION_FORMATS = [
32
32
  const DEFAULT_TRANSLATION_FORMAT = "json";
33
33
  const formatRef = (localeCode, namespace)=>namespace ? `${namespace}.${localeCode}` : localeCode;
34
34
  const formatFileName = (input, options)=>{
35
- var _options_format;
36
- const extension = (_options_format = options === null || options === void 0 ? void 0 : options.format) !== null && _options_format !== void 0 ? _options_format : DEFAULT_TRANSLATION_FORMAT;
35
+ var _ref;
36
+ const extension = (_ref = options === null || options === void 0 ? void 0 : options.format) !== null && _ref !== void 0 ? _ref : DEFAULT_TRANSLATION_FORMAT;
37
37
  const ref = typeof input === "string" ? input : formatRef(input.locale_code, input.namespace);
38
38
  return `${ref}.${extension}`;
39
39
  };
40
40
  const buildTranslationDirBundle = (input, options)=>{
41
- var _options_format;
42
- const format = (_options_format = options === null || options === void 0 ? void 0 : options.format) !== null && _options_format !== void 0 ? _options_format : DEFAULT_TRANSLATION_FORMAT;
41
+ var _ref;
42
+ const format = (_ref = options === null || options === void 0 ? void 0 : options.format) !== null && _ref !== void 0 ? _ref : DEFAULT_TRANSLATION_FORMAT;
43
43
  if (Array.isArray(input)) {
44
44
  const translations = input;
45
45
  return Object.fromEntries(translations.map((translation)=>[
@@ -65,8 +65,8 @@ function _interop_require_wildcard(obj, nodeInterop) {
65
65
  return newObj;
66
66
  }
67
67
  const writeTranslationFile = async (translationFileCtx, translation, options)=>{
68
- var _options_format;
69
- const format = (_options_format = options === null || options === void 0 ? void 0 : options.format) !== null && _options_format !== void 0 ? _options_format : _processorisomorphic.DEFAULT_TRANSLATION_FORMAT;
68
+ var _ref;
69
+ const format = (_ref = options === null || options === void 0 ? void 0 : options.format) !== null && _ref !== void 0 ? _ref : _processorisomorphic.DEFAULT_TRANSLATION_FORMAT;
70
70
  switch(format){
71
71
  case "json":
72
72
  return _fsextra.outputJson(translationFileCtx.abspath, JSON.parse(translation.content), {