@knocklabs/cli 0.3.0 → 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.
- package/README.md +505 -162
- package/dist/commands/branch/create.js +0 -2
- package/dist/commands/branch/delete.js +4 -3
- package/dist/commands/branch/exit.js +0 -2
- package/dist/commands/branch/list.js +0 -2
- package/dist/commands/branch/merge.js +82 -0
- package/dist/commands/branch/switch.js +0 -2
- package/dist/commands/channel/list.js +73 -0
- package/dist/commands/environment/list.js +73 -0
- package/dist/commands/guide/new.js +276 -0
- package/dist/commands/guide/pull.js +5 -6
- package/dist/commands/guide/push.js +1 -1
- package/dist/commands/guide/validate.js +1 -1
- package/dist/commands/init.js +108 -0
- package/dist/commands/layout/new.js +228 -0
- package/dist/commands/layout/pull.js +5 -6
- package/dist/commands/layout/push.js +1 -1
- package/dist/commands/layout/validate.js +1 -1
- package/dist/commands/message-type/new.js +228 -0
- package/dist/commands/message-type/pull.js +5 -6
- package/dist/commands/message-type/push.js +1 -1
- package/dist/commands/message-type/validate.js +1 -1
- package/dist/commands/partial/new.js +274 -0
- package/dist/commands/partial/pull.js +5 -6
- package/dist/commands/partial/push.js +1 -1
- package/dist/commands/partial/validate.js +1 -1
- package/dist/commands/pull.js +7 -2
- package/dist/commands/push.js +6 -4
- package/dist/commands/translation/pull.js +1 -1
- package/dist/commands/translation/push.js +1 -1
- package/dist/commands/translation/validate.js +1 -1
- package/dist/commands/workflow/new.js +179 -54
- package/dist/commands/workflow/pull.js +6 -8
- package/dist/commands/workflow/push.js +1 -1
- package/dist/commands/workflow/validate.js +1 -1
- package/dist/lib/api-v1.js +23 -2
- package/dist/lib/auth.js +1 -1
- package/dist/lib/base-command.js +18 -15
- package/dist/lib/helpers/flag.js +0 -2
- package/dist/lib/helpers/project-config.js +158 -0
- package/dist/lib/helpers/request.js +1 -2
- package/dist/lib/helpers/string.js +4 -4
- package/dist/lib/helpers/typegen.js +1 -1
- package/dist/lib/marshal/email-layout/generator.js +152 -0
- package/dist/lib/marshal/email-layout/helpers.js +6 -9
- package/dist/lib/marshal/email-layout/index.js +1 -0
- package/dist/lib/marshal/email-layout/writer.js +15 -3
- package/dist/lib/marshal/guide/generator.js +163 -0
- package/dist/lib/marshal/guide/helpers.js +6 -10
- package/dist/lib/marshal/guide/index.js +1 -0
- package/dist/lib/marshal/guide/writer.js +5 -9
- package/dist/lib/marshal/message-type/generator.js +139 -0
- package/dist/lib/marshal/message-type/helpers.js +6 -10
- package/dist/lib/marshal/message-type/index.js +1 -0
- package/dist/lib/marshal/message-type/writer.js +5 -1
- package/dist/lib/marshal/partial/generator.js +159 -0
- package/dist/lib/marshal/partial/helpers.js +6 -10
- package/dist/lib/marshal/partial/index.js +1 -0
- package/dist/lib/marshal/partial/writer.js +3 -0
- package/dist/lib/marshal/translation/helpers.js +6 -10
- package/dist/lib/marshal/translation/processor.isomorphic.js +4 -4
- package/dist/lib/marshal/translation/writer.js +2 -2
- package/dist/lib/marshal/workflow/generator.js +175 -19
- package/dist/lib/marshal/workflow/helpers.js +7 -10
- package/dist/lib/run-context/loader.js +5 -0
- package/dist/lib/templates.js +131 -0
- package/oclif.manifest.json +826 -266
- package/package.json +14 -9
|
@@ -44,8 +44,6 @@ class BranchCreate extends _basecommand.default {
|
|
|
44
44
|
this.log(` Created at: ${data.created_at}`);
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
-
// Hide until branches are released in GA
|
|
48
|
-
_define_property(BranchCreate, "hidden", true);
|
|
49
47
|
_define_property(BranchCreate, "summary", "Creates a new branch off of the development environment.");
|
|
50
48
|
_define_property(BranchCreate, "enableJsonFlag", true);
|
|
51
49
|
_define_property(BranchCreate, "args", {
|
|
@@ -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,14 +39,14 @@ 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(
|
|
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}\``);
|
|
45
48
|
}
|
|
46
49
|
}
|
|
47
|
-
// Hide until branches are released in GA
|
|
48
|
-
_define_property(BranchDelete, "hidden", true);
|
|
49
50
|
_define_property(BranchDelete, "summary", "Deletes an existing branch with the given slug.");
|
|
50
51
|
_define_property(BranchDelete, "args", {
|
|
51
52
|
slug: _arg.CustomArgs.slug({
|
|
@@ -39,6 +39,4 @@ class BranchExit extends _basecommand.default {
|
|
|
39
39
|
this.log("‣ Successfully exited the branch");
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
|
-
// Hide until branches are released in GA
|
|
43
|
-
_define_property(BranchExit, "hidden", true);
|
|
44
42
|
_define_property(BranchExit, "summary", "Exits the current branch.");
|
|
@@ -80,8 +80,6 @@ class BranchList extends _basecommand.default {
|
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
|
-
// Hide until branches are released in GA
|
|
84
|
-
_define_property(BranchList, "hidden", true);
|
|
85
83
|
_define_property(BranchList, "summary", "Display all existing branches off of the development environment.");
|
|
86
84
|
_define_property(BranchList, "flags", {
|
|
87
85
|
..._page.pageFlags
|
|
@@ -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
|
+
});
|
|
@@ -142,8 +142,6 @@ class BranchSwitch extends _basecommand.default {
|
|
|
142
142
|
});
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
|
-
// Hide until branches are released in GA
|
|
146
|
-
_define_property(BranchSwitch, "hidden", true);
|
|
147
145
|
_define_property(BranchSwitch, "summary", "Switches to an existing branch with the given slug.");
|
|
148
146
|
_define_property(BranchSwitch, "flags", {
|
|
149
147
|
create: _core.Flags.boolean({
|
|
@@ -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
|
|
121
|
-
|
|
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(
|
|
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
|
});
|