@knocklabs/cli 0.3.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +343 -55
- package/dist/commands/branch/delete.js +4 -1
- package/dist/commands/branch/merge.js +82 -0
- 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/open.js +106 -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/open.js +106 -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/open.js +106 -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/open.js +106 -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/open.js +106 -0
- 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/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/dist/lib/urls.js +16 -0
- package/oclif.manifest.json +1446 -547
- package/package.json +11 -9
|
@@ -0,0 +1,228 @@
|
|
|
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 MessageTypeNew;
|
|
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 _messagetype = /*#__PURE__*/ _interop_require_wildcard(require("../../lib/marshal/message-type"));
|
|
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 MessageTypeNew 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 message type inside an existing ${resourceDir.type} directory`);
|
|
89
|
+
}
|
|
90
|
+
// 2. Prompt for name and key if not provided
|
|
91
|
+
let name = flags.name;
|
|
92
|
+
let key = flags.key;
|
|
93
|
+
if (!name) {
|
|
94
|
+
const nameResponse = await (0, _enquirer.prompt)({
|
|
95
|
+
type: "input",
|
|
96
|
+
name: "name",
|
|
97
|
+
message: "Message type name",
|
|
98
|
+
validate: (value)=>{
|
|
99
|
+
if (!value || value.trim().length === 0) {
|
|
100
|
+
return "Message type name is required";
|
|
101
|
+
}
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
name = nameResponse.name;
|
|
106
|
+
}
|
|
107
|
+
if (!key) {
|
|
108
|
+
const keyResponse = await (0, _enquirer.prompt)({
|
|
109
|
+
type: "input",
|
|
110
|
+
name: "key",
|
|
111
|
+
message: "Message type key (immutable slug)",
|
|
112
|
+
initial: (0, _string.slugify)(name),
|
|
113
|
+
validate: (value)=>{
|
|
114
|
+
if (!value || value.trim().length === 0) {
|
|
115
|
+
return "Message type key is required";
|
|
116
|
+
}
|
|
117
|
+
const keyError = _messagetype.validateMessageTypeKey(value);
|
|
118
|
+
if (keyError) {
|
|
119
|
+
return `Invalid message type key: ${keyError}`;
|
|
120
|
+
}
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
key = keyResponse.key;
|
|
125
|
+
}
|
|
126
|
+
// Validate the message type key
|
|
127
|
+
const messageTypeKeyError = _messagetype.validateMessageTypeKey(key);
|
|
128
|
+
if (messageTypeKeyError) {
|
|
129
|
+
return this.error(`Invalid message type key \`${key}\` (${messageTypeKeyError})`);
|
|
130
|
+
}
|
|
131
|
+
const messageTypeDirCtx = await this.getMessageTypeDirContext(key);
|
|
132
|
+
const promptMessage = messageTypeDirCtx.exists ? `Found \`${messageTypeDirCtx.key}\` at ${messageTypeDirCtx.abspath}, overwrite?` : `Create a new message type directory \`${messageTypeDirCtx.key}\` at ${messageTypeDirCtx.abspath}?`;
|
|
133
|
+
// Check if the message type directory already exists, and prompt to confirm if not.
|
|
134
|
+
const input = flags.force || await (0, _ux.promptToConfirm)(promptMessage);
|
|
135
|
+
if (!input) return;
|
|
136
|
+
// Generate the message type either from a template or from scratch
|
|
137
|
+
await (flags.template ? this.fromTemplate(messageTypeDirCtx, name, flags.template) : this.fromScratch(messageTypeDirCtx, name));
|
|
138
|
+
if (flags.push) {
|
|
139
|
+
_ux.spinner.start("‣ Pushing message type to Knock");
|
|
140
|
+
try {
|
|
141
|
+
await _push.default.run([
|
|
142
|
+
key
|
|
143
|
+
]);
|
|
144
|
+
} catch (error) {
|
|
145
|
+
this.error(`Failed to push message type to Knock: ${error}`);
|
|
146
|
+
} finally{
|
|
147
|
+
_ux.spinner.stop();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
this.log(`‣ Successfully created message type \`${key}\``);
|
|
151
|
+
}
|
|
152
|
+
async fromTemplate(messageTypeDirCtx, name, templateString) {
|
|
153
|
+
// When being called from the template string, we want to try and generate
|
|
154
|
+
// the message type from the provided template.
|
|
155
|
+
_ux.spinner.start(`‣ Generating message type from template \`${templateString}\``);
|
|
156
|
+
try {
|
|
157
|
+
await _messagetype.generateMessageTypeFromTemplate(messageTypeDirCtx, templateString, {
|
|
158
|
+
name
|
|
159
|
+
});
|
|
160
|
+
} catch (error) {
|
|
161
|
+
this.error(`Failed to generate message type from template: ${error}`);
|
|
162
|
+
} finally{
|
|
163
|
+
_ux.spinner.stop();
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
async fromScratch(messageTypeDirCtx, name) {
|
|
167
|
+
// Generate the message type directory with scaffolded content
|
|
168
|
+
await _messagetype.generateMessageTypeDir(messageTypeDirCtx, {
|
|
169
|
+
name
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
async getMessageTypeDirContext(messageTypeKey) {
|
|
173
|
+
const { resourceDir, cwd: runCwd } = this.runContext;
|
|
174
|
+
// Inside an existing resource dir, use it if valid for the target message type.
|
|
175
|
+
if (resourceDir) {
|
|
176
|
+
const target = {
|
|
177
|
+
commandId: _basecommand.default.id,
|
|
178
|
+
type: "message_type",
|
|
179
|
+
key: messageTypeKey
|
|
180
|
+
};
|
|
181
|
+
return (0, _runcontext.ensureResourceDirForTarget)(resourceDir, target);
|
|
182
|
+
}
|
|
183
|
+
// Default to knock project config first if present, otherwise cwd.
|
|
184
|
+
const dirCtx = await (0, _projectconfig.resolveResourceDir)(this.projectConfig, "message_type", runCwd);
|
|
185
|
+
// Not inside any existing message type directory, which means either create a
|
|
186
|
+
// new message type directory in the cwd, or update it if there is one already.
|
|
187
|
+
if (messageTypeKey) {
|
|
188
|
+
const dirPath = _nodepath.resolve(dirCtx.abspath, messageTypeKey);
|
|
189
|
+
const exists = await _messagetype.isMessageTypeDir(dirPath);
|
|
190
|
+
return {
|
|
191
|
+
type: "message_type",
|
|
192
|
+
key: messageTypeKey,
|
|
193
|
+
abspath: dirPath,
|
|
194
|
+
exists
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
// Not in any message type directory, nor a message type key arg was given so error.
|
|
198
|
+
return this.error("Missing 1 required arg:\nmessageTypeKey");
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
_define_property(MessageTypeNew, "summary", "Create a new message type with a minimal configuration.");
|
|
202
|
+
_define_property(MessageTypeNew, "flags", {
|
|
203
|
+
name: _core.Flags.string({
|
|
204
|
+
summary: "The name of the message type",
|
|
205
|
+
char: "n"
|
|
206
|
+
}),
|
|
207
|
+
key: _core.Flags.string({
|
|
208
|
+
summary: "The key of the message type",
|
|
209
|
+
char: "k"
|
|
210
|
+
}),
|
|
211
|
+
environment: _core.Flags.string({
|
|
212
|
+
summary: "The environment to create the message type in. Defaults to development.",
|
|
213
|
+
default: _const.KnockEnv.Development
|
|
214
|
+
}),
|
|
215
|
+
branch: _flag.branch,
|
|
216
|
+
force: _core.Flags.boolean({
|
|
217
|
+
summary: "Force the creation of the message type directory without confirmation."
|
|
218
|
+
}),
|
|
219
|
+
push: _core.Flags.boolean({
|
|
220
|
+
summary: "Whether or not to push the message type to Knock after creation.",
|
|
221
|
+
default: false,
|
|
222
|
+
char: "p"
|
|
223
|
+
}),
|
|
224
|
+
template: _core.Flags.string({
|
|
225
|
+
summary: "The template to use for the message type. Should be `message-types/{key}`."
|
|
226
|
+
})
|
|
227
|
+
});
|
|
228
|
+
_define_property(MessageTypeNew, "args", {});
|
|
@@ -0,0 +1,106 @@
|
|
|
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 MessageTypeOpen;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _core = require("@oclif/core");
|
|
12
|
+
const _basecommand = /*#__PURE__*/ _interop_require_default(require("../../lib/base-command"));
|
|
13
|
+
const _browser = require("../../lib/helpers/browser");
|
|
14
|
+
const _error = require("../../lib/helpers/error");
|
|
15
|
+
const _flag = /*#__PURE__*/ _interop_require_wildcard(require("../../lib/helpers/flag"));
|
|
16
|
+
const _request = require("../../lib/helpers/request");
|
|
17
|
+
const _urls = require("../../lib/urls");
|
|
18
|
+
function _define_property(obj, key, value) {
|
|
19
|
+
if (key in obj) {
|
|
20
|
+
Object.defineProperty(obj, key, {
|
|
21
|
+
value: value,
|
|
22
|
+
enumerable: true,
|
|
23
|
+
configurable: true,
|
|
24
|
+
writable: true
|
|
25
|
+
});
|
|
26
|
+
} else {
|
|
27
|
+
obj[key] = value;
|
|
28
|
+
}
|
|
29
|
+
return obj;
|
|
30
|
+
}
|
|
31
|
+
function _interop_require_default(obj) {
|
|
32
|
+
return obj && obj.__esModule ? obj : {
|
|
33
|
+
default: obj
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function _getRequireWildcardCache(nodeInterop) {
|
|
37
|
+
if (typeof WeakMap !== "function") return null;
|
|
38
|
+
var cacheBabelInterop = new WeakMap();
|
|
39
|
+
var cacheNodeInterop = new WeakMap();
|
|
40
|
+
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
41
|
+
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
42
|
+
})(nodeInterop);
|
|
43
|
+
}
|
|
44
|
+
function _interop_require_wildcard(obj, nodeInterop) {
|
|
45
|
+
if (!nodeInterop && obj && obj.__esModule) {
|
|
46
|
+
return obj;
|
|
47
|
+
}
|
|
48
|
+
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
49
|
+
return {
|
|
50
|
+
default: obj
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
var cache = _getRequireWildcardCache(nodeInterop);
|
|
54
|
+
if (cache && cache.has(obj)) {
|
|
55
|
+
return cache.get(obj);
|
|
56
|
+
}
|
|
57
|
+
var newObj = {
|
|
58
|
+
__proto__: null
|
|
59
|
+
};
|
|
60
|
+
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
61
|
+
for(var key in obj){
|
|
62
|
+
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
63
|
+
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
64
|
+
if (desc && (desc.get || desc.set)) {
|
|
65
|
+
Object.defineProperty(newObj, key, desc);
|
|
66
|
+
} else {
|
|
67
|
+
newObj[key] = obj[key];
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
newObj.default = obj;
|
|
72
|
+
if (cache) {
|
|
73
|
+
cache.set(obj, newObj);
|
|
74
|
+
}
|
|
75
|
+
return newObj;
|
|
76
|
+
}
|
|
77
|
+
class MessageTypeOpen extends _basecommand.default {
|
|
78
|
+
async run() {
|
|
79
|
+
const whoamiResp = await this.apiV1.whoami();
|
|
80
|
+
if (!(0, _request.isSuccessResp)(whoamiResp)) {
|
|
81
|
+
const message = (0, _request.formatErrorRespMessage)(whoamiResp);
|
|
82
|
+
_core.ux.error(new _error.ApiError(message));
|
|
83
|
+
}
|
|
84
|
+
const { account_slug } = whoamiResp.data;
|
|
85
|
+
const { messageTypeKey } = this.props.args;
|
|
86
|
+
const { environment, branch } = this.props.flags;
|
|
87
|
+
const envOrBranch = branch !== null && branch !== void 0 ? branch : environment;
|
|
88
|
+
const url = (0, _urls.viewMessageTypeUrl)(this.sessionContext.dashboardOrigin, account_slug, envOrBranch, messageTypeKey);
|
|
89
|
+
this.log(`‣ Opening message type \`${messageTypeKey}\` in the Knock dashboard...`);
|
|
90
|
+
this.log(` ${url}`);
|
|
91
|
+
await _browser.browser.openUrl(url);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
_define_property(MessageTypeOpen, "summary", "Open a message type in the Knock dashboard.");
|
|
95
|
+
_define_property(MessageTypeOpen, "flags", {
|
|
96
|
+
environment: _core.Flags.string({
|
|
97
|
+
default: "development",
|
|
98
|
+
summary: "The environment to use."
|
|
99
|
+
}),
|
|
100
|
+
branch: _flag.branch
|
|
101
|
+
});
|
|
102
|
+
_define_property(MessageTypeOpen, "args", {
|
|
103
|
+
messageTypeKey: _core.Args.string({
|
|
104
|
+
required: true
|
|
105
|
+
})
|
|
106
|
+
});
|
|
@@ -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 _messagetype = /*#__PURE__*/ _interop_require_wildcard(require("../../lib/marshal/message-type"));
|
|
@@ -122,6 +123,7 @@ class MessageTypePull extends _basecommand.default {
|
|
|
122
123
|
async getMessageTypeDirContext() {
|
|
123
124
|
const { messageTypeKey } = this.props.args;
|
|
124
125
|
const { resourceDir, cwd: runCwd } = this.runContext;
|
|
126
|
+
const messageTypesIndexDirCtx = await (0, _projectconfig.resolveResourceDir)(this.projectConfig, "message_type", runCwd);
|
|
125
127
|
// Inside an existing resource dir, use it if valid for the target message
|
|
126
128
|
// type.
|
|
127
129
|
if (resourceDir) {
|
|
@@ -136,7 +138,7 @@ class MessageTypePull extends _basecommand.default {
|
|
|
136
138
|
// a new message type directory in the cwd, or update it if there is one
|
|
137
139
|
// already.
|
|
138
140
|
if (messageTypeKey) {
|
|
139
|
-
const dirPath = _nodepath.resolve(
|
|
141
|
+
const dirPath = _nodepath.resolve(messageTypesIndexDirCtx.abspath, messageTypeKey);
|
|
140
142
|
const exists = await _messagetype.isMessageTypeDir(dirPath);
|
|
141
143
|
return {
|
|
142
144
|
type: "message_type",
|
|
@@ -153,11 +155,8 @@ class MessageTypePull extends _basecommand.default {
|
|
|
153
155
|
* Pull all message types
|
|
154
156
|
*/ async pullAllMessageTypes() {
|
|
155
157
|
const { flags } = this.props;
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
exists: true
|
|
159
|
-
};
|
|
160
|
-
const targetDirCtx = flags["message-types-dir"] || defaultToCwd;
|
|
158
|
+
const messageTypesIndexDirCtx = await (0, _projectconfig.resolveResourceDir)(this.projectConfig, "message_type", this.runContext.cwd);
|
|
159
|
+
const targetDirCtx = flags["message-types-dir"] || messageTypesIndexDirCtx;
|
|
161
160
|
const prompt = targetDirCtx.exists ? `Pull latest message types into ${targetDirCtx.abspath}?\n This will overwrite the contents of this directory.` : `Create a new message types directory at ${targetDirCtx.abspath}?`;
|
|
162
161
|
const input = flags.force || await (0, _ux.promptToConfirm)(prompt);
|
|
163
162
|
if (!input) return;
|
|
@@ -83,7 +83,7 @@ class MessageTypePush extends _basecommand.default {
|
|
|
83
83
|
async run() {
|
|
84
84
|
const { flags } = this.props;
|
|
85
85
|
// 1. First read all message type directories found for the given command.
|
|
86
|
-
const target = await _messagetype.ensureValidCommandTarget(this.props, this.runContext);
|
|
86
|
+
const target = await _messagetype.ensureValidCommandTarget(this.props, this.runContext, this.projectConfig);
|
|
87
87
|
const [messageTypes, readErrors] = await _messagetype.readAllForCommandTarget(target, {
|
|
88
88
|
withExtractedFiles: true
|
|
89
89
|
});
|
|
@@ -80,7 +80,7 @@ function _interop_require_wildcard(obj, nodeInterop) {
|
|
|
80
80
|
class MessageTypeValidate extends _basecommand.default {
|
|
81
81
|
async run() {
|
|
82
82
|
// 1. Read all message type directories found for the given command.
|
|
83
|
-
const target = await _messagetype.ensureValidCommandTarget(this.props, this.runContext);
|
|
83
|
+
const target = await _messagetype.ensureValidCommandTarget(this.props, this.runContext, this.projectConfig);
|
|
84
84
|
const [messageTypes, readErrors] = await _messagetype.readAllForCommandTarget(target, {
|
|
85
85
|
withExtractedFiles: true
|
|
86
86
|
});
|
|
@@ -0,0 +1,274 @@
|
|
|
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 PartialNew;
|
|
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 _partial = /*#__PURE__*/ _interop_require_wildcard(require("../../lib/marshal/partial"));
|
|
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
|
+
const PARTIAL_TYPE_CHOICES = [
|
|
83
|
+
{
|
|
84
|
+
name: _partial.PartialType.Html,
|
|
85
|
+
message: "HTML"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: _partial.PartialType.Json,
|
|
89
|
+
message: "JSON"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
name: _partial.PartialType.Markdown,
|
|
93
|
+
message: "Markdown"
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
name: _partial.PartialType.Text,
|
|
97
|
+
message: "Text"
|
|
98
|
+
}
|
|
99
|
+
];
|
|
100
|
+
class PartialNew extends _basecommand.default {
|
|
101
|
+
async run() {
|
|
102
|
+
const { flags } = this.props;
|
|
103
|
+
const { resourceDir } = this.runContext;
|
|
104
|
+
// 1. Ensure we aren't in any existing resource directory already.
|
|
105
|
+
if (resourceDir) {
|
|
106
|
+
return this.error(`Cannot create a new partial inside an existing ${resourceDir.type} directory`);
|
|
107
|
+
}
|
|
108
|
+
// 2. Prompt for name and key if not provided
|
|
109
|
+
let name = flags.name;
|
|
110
|
+
let key = flags.key;
|
|
111
|
+
if (!name) {
|
|
112
|
+
const nameResponse = await (0, _enquirer.prompt)({
|
|
113
|
+
type: "input",
|
|
114
|
+
name: "name",
|
|
115
|
+
message: "Partial name",
|
|
116
|
+
validate: (value)=>{
|
|
117
|
+
if (!value || value.trim().length === 0) {
|
|
118
|
+
return "Partial name is required";
|
|
119
|
+
}
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
name = nameResponse.name;
|
|
124
|
+
}
|
|
125
|
+
if (!key) {
|
|
126
|
+
const keyResponse = await (0, _enquirer.prompt)({
|
|
127
|
+
type: "input",
|
|
128
|
+
name: "key",
|
|
129
|
+
message: "Partial key (immutable slug)",
|
|
130
|
+
initial: (0, _string.slugify)(name),
|
|
131
|
+
validate: (value)=>{
|
|
132
|
+
if (!value || value.trim().length === 0) {
|
|
133
|
+
return "Partial key is required";
|
|
134
|
+
}
|
|
135
|
+
const keyError = _partial.validatePartialKey(value);
|
|
136
|
+
if (keyError) {
|
|
137
|
+
return `Invalid partial key: ${keyError}`;
|
|
138
|
+
}
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
key = keyResponse.key;
|
|
143
|
+
}
|
|
144
|
+
// Validate the partial key
|
|
145
|
+
const partialKeyError = _partial.validatePartialKey(key);
|
|
146
|
+
if (partialKeyError) {
|
|
147
|
+
return this.error(`Invalid partial key \`${key}\` (${partialKeyError})`);
|
|
148
|
+
}
|
|
149
|
+
const partialDirCtx = await this.getPartialDirContext(key);
|
|
150
|
+
const promptMessage = partialDirCtx.exists ? `Found \`${partialDirCtx.key}\` at ${partialDirCtx.abspath}, overwrite?` : `Create a new partial directory \`${partialDirCtx.key}\` at ${partialDirCtx.abspath}?`;
|
|
151
|
+
// Check if the partial directory already exists, and prompt to confirm if not.
|
|
152
|
+
const input = flags.force || await (0, _ux.promptToConfirm)(promptMessage);
|
|
153
|
+
if (!input) return;
|
|
154
|
+
// Generate the partial either from a template or from scratch
|
|
155
|
+
await (flags.template ? this.fromTemplate(partialDirCtx, name, flags.template) : this.fromType(partialDirCtx, name, flags.type));
|
|
156
|
+
if (flags.push) {
|
|
157
|
+
_ux.spinner.start("‣ Pushing partial to Knock");
|
|
158
|
+
try {
|
|
159
|
+
await _push.default.run([
|
|
160
|
+
key
|
|
161
|
+
]);
|
|
162
|
+
} catch (error) {
|
|
163
|
+
this.error(`Failed to push partial to Knock: ${error}`);
|
|
164
|
+
} finally{
|
|
165
|
+
_ux.spinner.stop();
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
this.log(`‣ Successfully created partial \`${key}\``);
|
|
169
|
+
}
|
|
170
|
+
async fromTemplate(partialDirCtx, name, templateString) {
|
|
171
|
+
// When being called from the template string, we want to try and generate
|
|
172
|
+
// the partial from the provided template.
|
|
173
|
+
_ux.spinner.start(`‣ Generating partial from template \`${templateString}\``);
|
|
174
|
+
try {
|
|
175
|
+
await _partial.generatePartialFromTemplate(partialDirCtx, templateString, {
|
|
176
|
+
name
|
|
177
|
+
});
|
|
178
|
+
} catch (error) {
|
|
179
|
+
this.error(`Failed to generate partial from template: ${error}`);
|
|
180
|
+
} finally{
|
|
181
|
+
_ux.spinner.stop();
|
|
182
|
+
}
|
|
183
|
+
_ux.spinner.stop();
|
|
184
|
+
}
|
|
185
|
+
async fromType(partialDirCtx, name, type) {
|
|
186
|
+
let partialType;
|
|
187
|
+
if (type) {
|
|
188
|
+
partialType = type;
|
|
189
|
+
} else {
|
|
190
|
+
// Prompt for type with select
|
|
191
|
+
const typeResponse = await (0, _enquirer.prompt)({
|
|
192
|
+
type: "select",
|
|
193
|
+
name: "type",
|
|
194
|
+
message: "Select partial type",
|
|
195
|
+
choices: PARTIAL_TYPE_CHOICES.map((choice)=>({
|
|
196
|
+
name: choice.name,
|
|
197
|
+
message: choice.message
|
|
198
|
+
}))
|
|
199
|
+
});
|
|
200
|
+
partialType = typeResponse.type;
|
|
201
|
+
}
|
|
202
|
+
// Generate the partial directory with scaffolded content
|
|
203
|
+
await _partial.generatePartialDir(partialDirCtx, {
|
|
204
|
+
name,
|
|
205
|
+
type: partialType
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
async getPartialDirContext(partialKey) {
|
|
209
|
+
const { resourceDir, cwd: runCwd } = this.runContext;
|
|
210
|
+
// Inside an existing resource dir, use it if valid for the target partial.
|
|
211
|
+
if (resourceDir) {
|
|
212
|
+
const target = {
|
|
213
|
+
commandId: _basecommand.default.id,
|
|
214
|
+
type: "partial",
|
|
215
|
+
key: partialKey
|
|
216
|
+
};
|
|
217
|
+
return (0, _runcontext.ensureResourceDirForTarget)(resourceDir, target);
|
|
218
|
+
}
|
|
219
|
+
// Default to knock project config first if present, otherwise cwd.
|
|
220
|
+
const dirCtx = await (0, _projectconfig.resolveResourceDir)(this.projectConfig, "partial", runCwd);
|
|
221
|
+
// Not inside any existing partial directory, which means either create a
|
|
222
|
+
// new partial directory in the cwd, or update it if there is one already.
|
|
223
|
+
if (partialKey) {
|
|
224
|
+
const dirPath = _nodepath.resolve(dirCtx.abspath, partialKey);
|
|
225
|
+
const exists = await _partial.isPartialDir(dirPath);
|
|
226
|
+
return {
|
|
227
|
+
type: "partial",
|
|
228
|
+
key: partialKey,
|
|
229
|
+
abspath: dirPath,
|
|
230
|
+
exists
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
// Not in any partial directory, nor a partial key arg was given so error.
|
|
234
|
+
return this.error("Missing 1 required arg:\npartialKey");
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
_define_property(PartialNew, "summary", "Create a new partial with a minimal configuration.");
|
|
238
|
+
_define_property(PartialNew, "flags", {
|
|
239
|
+
name: _core.Flags.string({
|
|
240
|
+
summary: "The name of the partial",
|
|
241
|
+
char: "n"
|
|
242
|
+
}),
|
|
243
|
+
key: _core.Flags.string({
|
|
244
|
+
summary: "The key of the partial",
|
|
245
|
+
char: "k"
|
|
246
|
+
}),
|
|
247
|
+
type: _core.Flags.string({
|
|
248
|
+
summary: "The type of the partial (html, json, markdown, text). You cannot use this flag with --template.",
|
|
249
|
+
char: "t",
|
|
250
|
+
options: [
|
|
251
|
+
_partial.PartialType.Html,
|
|
252
|
+
_partial.PartialType.Json,
|
|
253
|
+
_partial.PartialType.Markdown,
|
|
254
|
+
_partial.PartialType.Text
|
|
255
|
+
]
|
|
256
|
+
}),
|
|
257
|
+
environment: _core.Flags.string({
|
|
258
|
+
summary: "The environment to create the partial in. Defaults to development.",
|
|
259
|
+
default: _const.KnockEnv.Development
|
|
260
|
+
}),
|
|
261
|
+
branch: _flag.branch,
|
|
262
|
+
force: _core.Flags.boolean({
|
|
263
|
+
summary: "Force the creation of the partial directory without confirmation."
|
|
264
|
+
}),
|
|
265
|
+
push: _core.Flags.boolean({
|
|
266
|
+
summary: "Whether or not to push the partial to Knock after creation.",
|
|
267
|
+
default: false,
|
|
268
|
+
char: "p"
|
|
269
|
+
}),
|
|
270
|
+
template: _core.Flags.string({
|
|
271
|
+
summary: "The template to use for the partial. Should be `partials/{key}`. You cannot use this flag with --type."
|
|
272
|
+
})
|
|
273
|
+
});
|
|
274
|
+
_define_property(PartialNew, "args", {});
|