@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
@@ -11,6 +11,7 @@ Object.defineProperty(exports, "default", {
11
11
  const _core = require("@oclif/core");
12
12
  const _basecommand = /*#__PURE__*/ _interop_require_default(require("../../lib/base-command"));
13
13
  const _arg = require("../../lib/helpers/arg");
14
+ const _const = require("../../lib/helpers/const");
14
15
  const _request = require("../../lib/helpers/request");
15
16
  const _ux = require("../../lib/helpers/ux");
16
17
  function _define_property(obj, key, value) {
@@ -38,7 +39,9 @@ class BranchDelete extends _basecommand.default {
38
39
  const prompt = `Delete branch \`${args.slug}\`?`;
39
40
  const input = flags.force || await (0, _ux.promptToConfirm)(prompt);
40
41
  if (!input) return;
41
- await (0, _request.withSpinnerV2)(()=>this.apiV1.mgmtClient.delete(`/v1/branches/${args.slug}`), {
42
+ await (0, _request.withSpinnerV2)(()=>this.apiV1.mgmtClient.branches.delete(args.slug, {
43
+ environment: _const.KnockEnv.Development
44
+ }), {
42
45
  action: "‣ Deleting branch"
43
46
  });
44
47
  this.log(`‣ Successfully deleted branch \`${args.slug}\``);
@@ -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: function() {
8
+ return BranchMerge;
9
+ }
10
+ });
11
+ const _core = require("@oclif/core");
12
+ const _basecommand = /*#__PURE__*/ _interop_require_default(require("../../lib/base-command"));
13
+ const _arg = require("../../lib/helpers/arg");
14
+ const _const = require("../../lib/helpers/const");
15
+ const _request = require("../../lib/helpers/request");
16
+ const _ux = require("../../lib/helpers/ux");
17
+ function _define_property(obj, key, value) {
18
+ if (key in obj) {
19
+ Object.defineProperty(obj, key, {
20
+ value: value,
21
+ enumerable: true,
22
+ configurable: true,
23
+ writable: true
24
+ });
25
+ } else {
26
+ obj[key] = value;
27
+ }
28
+ return obj;
29
+ }
30
+ function _interop_require_default(obj) {
31
+ return obj && obj.__esModule ? obj : {
32
+ default: obj
33
+ };
34
+ }
35
+ class BranchMerge extends _basecommand.default {
36
+ async run() {
37
+ const { args, flags } = this.props;
38
+ const promotePrompt = `Merge all changes from branch \`${args.slug}\` into the development environment?`;
39
+ const shouldPromote = flags.force || await (0, _ux.promptToConfirm)(promotePrompt);
40
+ if (!shouldPromote) return;
41
+ await this.promoteBranchCommits();
42
+ if (!flags.delete) return;
43
+ const deletePrompt = `Delete branch \`${args.slug}\`?`;
44
+ const shouldDelete = flags.force || await (0, _ux.promptToConfirm)(deletePrompt);
45
+ if (!shouldDelete) return;
46
+ await this.deleteBranch();
47
+ }
48
+ async promoteBranchCommits() {
49
+ const { args } = this.props;
50
+ await (0, _request.withSpinnerV2)(()=>this.apiV1.mgmtClient.commits.promoteAll({
51
+ branch: args.slug,
52
+ to_environment: _const.KnockEnv.Development
53
+ }));
54
+ this.log(`‣ Successfully merged all changes into the development environment`);
55
+ }
56
+ async deleteBranch() {
57
+ const { args } = this.props;
58
+ await (0, _request.withSpinnerV2)(()=>this.apiV1.mgmtClient.branches.delete(args.slug, {
59
+ environment: _const.KnockEnv.Development
60
+ }), {
61
+ action: "‣ Deleting branch"
62
+ });
63
+ this.log(`‣ Successfully deleted branch \`${args.slug}\``);
64
+ }
65
+ }
66
+ _define_property(BranchMerge, "summary", "Merges a branch into the development environment.");
67
+ _define_property(BranchMerge, "args", {
68
+ slug: _arg.CustomArgs.slug({
69
+ required: true,
70
+ description: "The slug of the branch to merge"
71
+ })
72
+ });
73
+ _define_property(BranchMerge, "flags", {
74
+ force: _core.Flags.boolean({
75
+ summary: "Remove the confirmation prompt."
76
+ }),
77
+ delete: _core.Flags.boolean({
78
+ summary: "Delete the branch after merging.",
79
+ default: true,
80
+ allowNo: true
81
+ })
82
+ });
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "default", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return ChannelList;
9
+ }
10
+ });
11
+ const _core = require("@oclif/core");
12
+ const _basecommand = /*#__PURE__*/ _interop_require_default(require("../../lib/base-command"));
13
+ const _date = require("../../lib/helpers/date");
14
+ function _define_property(obj, key, value) {
15
+ if (key in obj) {
16
+ Object.defineProperty(obj, key, {
17
+ value: value,
18
+ enumerable: true,
19
+ configurable: true,
20
+ writable: true
21
+ });
22
+ } else {
23
+ obj[key] = value;
24
+ }
25
+ return obj;
26
+ }
27
+ function _interop_require_default(obj) {
28
+ return obj && obj.__esModule ? obj : {
29
+ default: obj
30
+ };
31
+ }
32
+ class ChannelList extends _basecommand.default {
33
+ async run() {
34
+ const channels = await this.request();
35
+ const { flags } = this.props;
36
+ if (flags.json) return channels;
37
+ await this.render(channels);
38
+ }
39
+ async request() {
40
+ return this.apiV1.listAllChannels();
41
+ }
42
+ async render(channels) {
43
+ this.log(`‣ Showing ${channels.length} channels\n`);
44
+ /*
45
+ * Channels list table
46
+ */ const formattedChannels = channels.map((channel)=>({
47
+ key: channel.key,
48
+ name: channel.name,
49
+ type: channel.type,
50
+ provider: channel.provider,
51
+ updated_at: (0, _date.formatDate)(channel.updated_at)
52
+ }));
53
+ _core.ux.table(formattedChannels, {
54
+ key: {
55
+ header: "Key"
56
+ },
57
+ name: {
58
+ header: "Name"
59
+ },
60
+ type: {
61
+ header: "Type"
62
+ },
63
+ provider: {
64
+ header: "Provider"
65
+ },
66
+ updated_at: {
67
+ header: "Updated at"
68
+ }
69
+ });
70
+ }
71
+ }
72
+ _define_property(ChannelList, "summary", "Display all channels configured for the account.");
73
+ _define_property(ChannelList, "enableJsonFlag", true);
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "default", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return EnvironmentList;
9
+ }
10
+ });
11
+ const _core = require("@oclif/core");
12
+ const _basecommand = /*#__PURE__*/ _interop_require_default(require("../../lib/base-command"));
13
+ const _date = require("../../lib/helpers/date");
14
+ function _define_property(obj, key, value) {
15
+ if (key in obj) {
16
+ Object.defineProperty(obj, key, {
17
+ value: value,
18
+ enumerable: true,
19
+ configurable: true,
20
+ writable: true
21
+ });
22
+ } else {
23
+ obj[key] = value;
24
+ }
25
+ return obj;
26
+ }
27
+ function _interop_require_default(obj) {
28
+ return obj && obj.__esModule ? obj : {
29
+ default: obj
30
+ };
31
+ }
32
+ class EnvironmentList extends _basecommand.default {
33
+ async run() {
34
+ const environments = await this.request();
35
+ const { flags } = this.props;
36
+ if (flags.json) return environments;
37
+ await this.render(environments);
38
+ }
39
+ async request() {
40
+ return this.apiV1.listAllEnvironments();
41
+ }
42
+ async render(environments) {
43
+ this.log(`‣ Showing ${environments.length} environments\n`);
44
+ /*
45
+ * Environments list table
46
+ */ const formattedEnvironments = environments.map((environment)=>({
47
+ slug: environment.slug,
48
+ name: environment.name,
49
+ order: environment.order,
50
+ owner: environment.owner,
51
+ updated_at: (0, _date.formatDate)(environment.updated_at)
52
+ }));
53
+ _core.ux.table(formattedEnvironments, {
54
+ slug: {
55
+ header: "Slug"
56
+ },
57
+ name: {
58
+ header: "Name"
59
+ },
60
+ order: {
61
+ header: "Order"
62
+ },
63
+ owner: {
64
+ header: "Owner"
65
+ },
66
+ updated_at: {
67
+ header: "Updated at"
68
+ }
69
+ });
70
+ }
71
+ }
72
+ _define_property(EnvironmentList, "summary", "Display all environments configured for the account.");
73
+ _define_property(EnvironmentList, "enableJsonFlag", true);
@@ -0,0 +1,276 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "default", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return GuideNew;
9
+ }
10
+ });
11
+ const _nodepath = /*#__PURE__*/ _interop_require_wildcard(require("node:path"));
12
+ const _core = require("@oclif/core");
13
+ const _enquirer = require("enquirer");
14
+ const _basecommand = /*#__PURE__*/ _interop_require_default(require("../../lib/base-command"));
15
+ const _const = require("../../lib/helpers/const");
16
+ const _flag = /*#__PURE__*/ _interop_require_wildcard(require("../../lib/helpers/flag"));
17
+ const _projectconfig = require("../../lib/helpers/project-config");
18
+ const _string = require("../../lib/helpers/string");
19
+ const _ux = require("../../lib/helpers/ux");
20
+ const _guide = /*#__PURE__*/ _interop_require_wildcard(require("../../lib/marshal/guide"));
21
+ const _runcontext = require("../../lib/run-context");
22
+ const _push = /*#__PURE__*/ _interop_require_default(require("./push"));
23
+ function _define_property(obj, key, value) {
24
+ if (key in obj) {
25
+ Object.defineProperty(obj, key, {
26
+ value: value,
27
+ enumerable: true,
28
+ configurable: true,
29
+ writable: true
30
+ });
31
+ } else {
32
+ obj[key] = value;
33
+ }
34
+ return obj;
35
+ }
36
+ function _interop_require_default(obj) {
37
+ return obj && obj.__esModule ? obj : {
38
+ default: obj
39
+ };
40
+ }
41
+ function _getRequireWildcardCache(nodeInterop) {
42
+ if (typeof WeakMap !== "function") return null;
43
+ var cacheBabelInterop = new WeakMap();
44
+ var cacheNodeInterop = new WeakMap();
45
+ return (_getRequireWildcardCache = function(nodeInterop) {
46
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
47
+ })(nodeInterop);
48
+ }
49
+ function _interop_require_wildcard(obj, nodeInterop) {
50
+ if (!nodeInterop && obj && obj.__esModule) {
51
+ return obj;
52
+ }
53
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
54
+ return {
55
+ default: obj
56
+ };
57
+ }
58
+ var cache = _getRequireWildcardCache(nodeInterop);
59
+ if (cache && cache.has(obj)) {
60
+ return cache.get(obj);
61
+ }
62
+ var newObj = {
63
+ __proto__: null
64
+ };
65
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
66
+ for(var key in obj){
67
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
68
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
69
+ if (desc && (desc.get || desc.set)) {
70
+ Object.defineProperty(newObj, key, desc);
71
+ } else {
72
+ newObj[key] = obj[key];
73
+ }
74
+ }
75
+ }
76
+ newObj.default = obj;
77
+ if (cache) {
78
+ cache.set(obj, newObj);
79
+ }
80
+ return newObj;
81
+ }
82
+ class GuideNew extends _basecommand.default {
83
+ async run() {
84
+ const { flags } = this.props;
85
+ const { resourceDir } = this.runContext;
86
+ // 1. Ensure we aren't in any existing resource directory already.
87
+ if (resourceDir) {
88
+ return this.error(`Cannot create a new guide inside an existing ${resourceDir.type} directory`);
89
+ }
90
+ // 2. Validate that template and message-type flags are not used together
91
+ if (flags.template && flags["message-type"]) {
92
+ return this.error("Cannot use both --template and --message-type flags together");
93
+ }
94
+ // 3. Prompt for name and key if not provided
95
+ let name = flags.name;
96
+ let key = flags.key;
97
+ if (!name) {
98
+ const nameResponse = await (0, _enquirer.prompt)({
99
+ type: "input",
100
+ name: "name",
101
+ message: "Guide name",
102
+ validate: (value)=>{
103
+ if (!value || value.trim().length === 0) {
104
+ return "Guide name is required";
105
+ }
106
+ return true;
107
+ }
108
+ });
109
+ name = nameResponse.name;
110
+ }
111
+ if (!key) {
112
+ const keyResponse = await (0, _enquirer.prompt)({
113
+ type: "input",
114
+ name: "key",
115
+ message: "Guide key (immutable slug)",
116
+ initial: (0, _string.slugify)(name),
117
+ validate: (value)=>{
118
+ if (!value || value.trim().length === 0) {
119
+ return "Guide key is required";
120
+ }
121
+ const keyError = _guide.validateGuideKey(value);
122
+ if (keyError) {
123
+ return `Invalid guide key: ${keyError}`;
124
+ }
125
+ return true;
126
+ }
127
+ });
128
+ key = keyResponse.key;
129
+ }
130
+ // Validate the guide key
131
+ const guideKeyError = _guide.validateGuideKey(key);
132
+ if (guideKeyError) {
133
+ return this.error(`Invalid guide key \`${key}\` (${guideKeyError})`);
134
+ }
135
+ const guideDirCtx = await this.getGuideDirContext(key);
136
+ const promptMessage = guideDirCtx.exists ? `Found \`${guideDirCtx.key}\` at ${guideDirCtx.abspath}, overwrite?` : `Create a new guide directory \`${guideDirCtx.key}\` at ${guideDirCtx.abspath}?`;
137
+ // Check if the guide directory already exists, and prompt to confirm if not. Prompt to overwrite if it does.
138
+ const input = flags.force || await (0, _ux.promptToConfirm)(promptMessage);
139
+ if (!input) return;
140
+ // Generate the guide either from a template or from scratch
141
+ await (flags.template ? this.fromTemplate(guideDirCtx, name, flags.template) : this.fromMessageType(guideDirCtx, name, flags["message-type"]));
142
+ if (flags.push) {
143
+ _ux.spinner.start("‣ Pushing guide to Knock");
144
+ try {
145
+ await _push.default.run([
146
+ key
147
+ ]);
148
+ } catch (error) {
149
+ this.error(`Failed to push guide to Knock: ${error}`);
150
+ } finally{
151
+ _ux.spinner.stop();
152
+ }
153
+ }
154
+ this.log(`‣ Successfully created guide \`${key}\``);
155
+ }
156
+ async fromTemplate(guideDirCtx, name, templateString) {
157
+ // When being called from the template string, we want to try and generate
158
+ // the guide from the provided template.
159
+ _ux.spinner.start(`‣ Generating guide from template \`${templateString}\``);
160
+ try {
161
+ await _guide.generateGuideFromTemplate(guideDirCtx, templateString, {
162
+ name
163
+ });
164
+ } catch (error) {
165
+ this.error(`Failed to generate guide from template: ${error}`);
166
+ } finally{
167
+ _ux.spinner.stop();
168
+ }
169
+ }
170
+ async fromMessageType(guideDirCtx, name, messageTypeKey) {
171
+ const { flags } = this.props;
172
+ _ux.spinner.start(`‣ Fetching message types`);
173
+ // Fetch all message types from the API
174
+ const messageTypes = await this.apiV1.listAllMessageTypes({
175
+ environment: flags.environment,
176
+ hide_uncommitted_changes: true
177
+ });
178
+ _ux.spinner.stop();
179
+ if (messageTypes.length === 0) {
180
+ return this.error("No message types found. Please create a message type first.");
181
+ }
182
+ let selectedMessageType;
183
+ // Determine message type from flag or prompt
184
+ if (messageTypeKey) {
185
+ const messageType = messageTypes.find((mt)=>mt.key === messageTypeKey);
186
+ if (!messageType) {
187
+ return this.error(`Message type \`${messageTypeKey}\` not found`);
188
+ }
189
+ selectedMessageType = messageType;
190
+ } else {
191
+ // Prompt for message type with select
192
+ const messageTypeChoices = messageTypes.map((mt)=>({
193
+ name: mt.key,
194
+ message: `${mt.name} (${mt.key})`
195
+ }));
196
+ const messageTypeResponse = await (0, _enquirer.prompt)({
197
+ type: "select",
198
+ name: "messageType",
199
+ message: "Select message type",
200
+ choices: messageTypeChoices
201
+ });
202
+ const messageType = messageTypes.find((mt)=>mt.key === messageTypeResponse.messageType);
203
+ if (!messageType) {
204
+ return this.error("Message type selection failed");
205
+ }
206
+ selectedMessageType = messageType;
207
+ }
208
+ // Generate the guide directory with scaffolded content
209
+ await _guide.generateGuideDir(guideDirCtx, {
210
+ name,
211
+ messageType: selectedMessageType,
212
+ variantKey: "default"
213
+ });
214
+ }
215
+ async getGuideDirContext(guideKey) {
216
+ const { resourceDir, cwd: runCwd } = this.runContext;
217
+ // Inside an existing resource dir, use it if valid for the target guide.
218
+ if (resourceDir) {
219
+ const target = {
220
+ commandId: _basecommand.default.id,
221
+ type: "guide",
222
+ key: guideKey
223
+ };
224
+ return (0, _runcontext.ensureResourceDirForTarget)(resourceDir, target);
225
+ }
226
+ // Default to knock project config first if present, otherwise cwd.
227
+ const dirCtx = await (0, _projectconfig.resolveResourceDir)(this.projectConfig, "guide", runCwd);
228
+ // Not inside any existing guide directory, which means either create a
229
+ // new guide directory in the cwd, or update it if there is one already.
230
+ if (guideKey) {
231
+ const dirPath = _nodepath.resolve(dirCtx.abspath, guideKey);
232
+ const exists = await _guide.isGuideDir(dirPath);
233
+ return {
234
+ type: "guide",
235
+ key: guideKey,
236
+ abspath: dirPath,
237
+ exists
238
+ };
239
+ }
240
+ // Not in any guide directory, nor a guide key arg was given so error.
241
+ return this.error("Missing 1 required arg:\nguideKey");
242
+ }
243
+ }
244
+ _define_property(GuideNew, "summary", "Create a new guide with a minimal configuration.");
245
+ _define_property(GuideNew, "flags", {
246
+ name: _core.Flags.string({
247
+ summary: "The name of the guide",
248
+ char: "n"
249
+ }),
250
+ key: _core.Flags.string({
251
+ summary: "The key of the guide",
252
+ char: "k"
253
+ }),
254
+ "message-type": _core.Flags.string({
255
+ summary: "The message type key to use for the guide. You cannot use this flag with --template.",
256
+ char: "m"
257
+ }),
258
+ environment: _core.Flags.string({
259
+ summary: "The environment to create the guide in. Defaults to development.",
260
+ default: _const.KnockEnv.Development
261
+ }),
262
+ branch: _flag.branch,
263
+ force: _core.Flags.boolean({
264
+ summary: "Force the creation of the guide directory without confirmation."
265
+ }),
266
+ push: _core.Flags.boolean({
267
+ summary: "Whether or not to push the guide to Knock after creation.",
268
+ default: false,
269
+ char: "p"
270
+ }),
271
+ template: _core.Flags.string({
272
+ summary: "The template to use for the guide. Should be `guides/{key}`. You cannot use this flag with --message-type.",
273
+ char: "t"
274
+ })
275
+ });
276
+ _define_property(GuideNew, "args", {});
@@ -16,6 +16,7 @@ const _error = require("../../lib/helpers/error");
16
16
  const _flag = /*#__PURE__*/ _interop_require_wildcard(require("../../lib/helpers/flag"));
17
17
  const _objectisomorphic = require("../../lib/helpers/object.isomorphic");
18
18
  const _page = require("../../lib/helpers/page");
19
+ const _projectconfig = require("../../lib/helpers/project-config");
19
20
  const _request = require("../../lib/helpers/request");
20
21
  const _ux = require("../../lib/helpers/ux");
21
22
  const _guide = /*#__PURE__*/ _interop_require_wildcard(require("../../lib/marshal/guide"));
@@ -117,11 +118,8 @@ class GuidePull extends _basecommand.default {
117
118
  }
118
119
  async pullAllGuides() {
119
120
  const { flags } = this.props;
120
- const defaultToCwd = {
121
- abspath: this.runContext.cwd,
122
- exists: true
123
- };
124
- const targetDirCtx = flags["guides-dir"] || defaultToCwd;
121
+ const guidesIndexDirCtx = await (0, _projectconfig.resolveResourceDir)(this.projectConfig, "guide", this.runContext.cwd);
122
+ const targetDirCtx = flags["guides-dir"] || guidesIndexDirCtx;
125
123
  const prompt = targetDirCtx.exists ? `Pull latest guides into ${targetDirCtx.abspath}?\n This will overwrite the contents of this directory.` : `Create a new guides directory at ${targetDirCtx.abspath}?`;
126
124
  const input = flags.force || await (0, _ux.promptToConfirm)(prompt);
127
125
  if (!input) return;
@@ -169,10 +167,11 @@ class GuidePull extends _basecommand.default {
169
167
  };
170
168
  return (0, _runcontext.ensureResourceDirForTarget)(resourceDir, target);
171
169
  }
170
+ const guidesIndexDirCtx = await (0, _projectconfig.resolveResourceDir)(this.projectConfig, "guide", runCwd);
172
171
  // Not inside any existing guide directory, which means either create a
173
172
  // new guide directory in the cwd, or update it if there is one already.
174
173
  if (guideKey) {
175
- const dirPath = _nodepath.resolve(runCwd, guideKey);
174
+ const dirPath = _nodepath.resolve(guidesIndexDirCtx.abspath, guideKey);
176
175
  const exists = await _guide.isGuideDir(dirPath);
177
176
  return {
178
177
  type: "guide",
@@ -83,7 +83,7 @@ class GuidePush extends _basecommand.default {
83
83
  async run() {
84
84
  const { flags } = this.props;
85
85
  // 1. First read all guide directories found for the given command.
86
- const target = await _guide.ensureValidCommandTarget(this.props, this.runContext);
86
+ const target = await _guide.ensureValidCommandTarget(this.props, this.runContext, this.projectConfig);
87
87
  const [guides, readErrors] = await _guide.readAllForCommandTarget(target, {
88
88
  withExtractedFiles: true
89
89
  });
@@ -80,7 +80,7 @@ function _interop_require_wildcard(obj, nodeInterop) {
80
80
  class GuideValidate extends _basecommand.default {
81
81
  async run() {
82
82
  // 1. Read all guide directories found for the given command.
83
- const target = await _guide.ensureValidCommandTarget(this.props, this.runContext);
83
+ const target = await _guide.ensureValidCommandTarget(this.props, this.runContext, this.projectConfig);
84
84
  const [guides, readErrors] = await _guide.readAllForCommandTarget(target, {
85
85
  withExtractedFiles: true
86
86
  });
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "default", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return Init;
9
+ }
10
+ });
11
+ const _nodepath = /*#__PURE__*/ _interop_require_wildcard(require("node:path"));
12
+ const _enquirer = /*#__PURE__*/ _interop_require_default(require("enquirer"));
13
+ const _fsextra = /*#__PURE__*/ _interop_require_wildcard(require("fs-extra"));
14
+ const _basecommand = /*#__PURE__*/ _interop_require_default(require("../lib/base-command"));
15
+ const _projectconfig = require("../lib/helpers/project-config");
16
+ function _define_property(obj, key, value) {
17
+ if (key in obj) {
18
+ Object.defineProperty(obj, key, {
19
+ value: value,
20
+ enumerable: true,
21
+ configurable: true,
22
+ writable: true
23
+ });
24
+ } else {
25
+ obj[key] = value;
26
+ }
27
+ return obj;
28
+ }
29
+ function _interop_require_default(obj) {
30
+ return obj && obj.__esModule ? obj : {
31
+ default: obj
32
+ };
33
+ }
34
+ function _getRequireWildcardCache(nodeInterop) {
35
+ if (typeof WeakMap !== "function") return null;
36
+ var cacheBabelInterop = new WeakMap();
37
+ var cacheNodeInterop = new WeakMap();
38
+ return (_getRequireWildcardCache = function(nodeInterop) {
39
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
40
+ })(nodeInterop);
41
+ }
42
+ function _interop_require_wildcard(obj, nodeInterop) {
43
+ if (!nodeInterop && obj && obj.__esModule) {
44
+ return obj;
45
+ }
46
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
47
+ return {
48
+ default: obj
49
+ };
50
+ }
51
+ var cache = _getRequireWildcardCache(nodeInterop);
52
+ if (cache && cache.has(obj)) {
53
+ return cache.get(obj);
54
+ }
55
+ var newObj = {
56
+ __proto__: null
57
+ };
58
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
59
+ for(var key in obj){
60
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
61
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
62
+ if (desc && (desc.get || desc.set)) {
63
+ Object.defineProperty(newObj, key, desc);
64
+ } else {
65
+ newObj[key] = obj[key];
66
+ }
67
+ }
68
+ }
69
+ newObj.default = obj;
70
+ if (cache) {
71
+ cache.set(obj, newObj);
72
+ }
73
+ return newObj;
74
+ }
75
+ class Init extends _basecommand.default {
76
+ async run() {
77
+ const configPath = _nodepath.resolve(process.cwd(), _projectconfig.PROJECT_CONFIG_FILE_NAME);
78
+ // 1. Check if knock.json already exists
79
+ const configExists = await _fsextra.pathExists(configPath);
80
+ if (configExists) {
81
+ this.error(`A ${_projectconfig.PROJECT_CONFIG_FILE_NAME} file already exists in this directory. Aborting.`);
82
+ }
83
+ // 2. Prompt user for the knock directory location
84
+ const { knockDir } = await _enquirer.default.prompt({
85
+ type: "input",
86
+ name: "knockDir",
87
+ message: "Where do you want to store your Knock resources?",
88
+ initial: ".knock"
89
+ });
90
+ // 3. Create the knock directory and resource subdirectories
91
+ const knockDirPath = _nodepath.resolve(process.cwd(), knockDir);
92
+ await _fsextra.ensureDir(knockDirPath);
93
+ // 4. Write the knock.json configuration file
94
+ await _fsextra.outputJson(configPath, {
95
+ $schema: "https://schemas.knock.app/cli/knock.json",
96
+ knockDir
97
+ }, {
98
+ spaces: 2
99
+ });
100
+ this.log(`‣ Successfully initialized Knock project at ${process.cwd()}`);
101
+ this.log(`‣ Resources directory: ${knockDir}`);
102
+ }
103
+ constructor(...args){
104
+ super(...args), _define_property(this, "requiresAuth", false);
105
+ }
106
+ }
107
+ _define_property(Init, "summary", "Initialize a new Knock project with a knock.json configuration file.");
108
+ _define_property(Init, "description", "Creates a knock.json configuration file in the current directory " + "to store project-level settings like the knock resources directory.");