@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
|
@@ -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.");
|
|
@@ -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 EmailLayoutNew;
|
|
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 _emaillayout = /*#__PURE__*/ _interop_require_wildcard(require("../../lib/marshal/email-layout"));
|
|
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 EmailLayoutNew 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 email layout 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: "Email layout name",
|
|
98
|
+
validate: (value)=>{
|
|
99
|
+
if (!value || value.trim().length === 0) {
|
|
100
|
+
return "Email layout 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: "Email layout key (immutable slug)",
|
|
112
|
+
initial: (0, _string.slugify)(name),
|
|
113
|
+
validate: (value)=>{
|
|
114
|
+
if (!value || value.trim().length === 0) {
|
|
115
|
+
return "Email layout key is required";
|
|
116
|
+
}
|
|
117
|
+
const keyError = _emaillayout.validateEmailLayoutKey(value);
|
|
118
|
+
if (keyError) {
|
|
119
|
+
return `Invalid email layout key: ${keyError}`;
|
|
120
|
+
}
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
key = keyResponse.key;
|
|
125
|
+
}
|
|
126
|
+
// Validate the email layout key
|
|
127
|
+
const emailLayoutKeyError = _emaillayout.validateEmailLayoutKey(key);
|
|
128
|
+
if (emailLayoutKeyError) {
|
|
129
|
+
return this.error(`Invalid email layout key \`${key}\` (${emailLayoutKeyError})`);
|
|
130
|
+
}
|
|
131
|
+
const emailLayoutDirCtx = await this.getEmailLayoutDirContext(key);
|
|
132
|
+
const promptMessage = emailLayoutDirCtx.exists ? `Found \`${emailLayoutDirCtx.key}\` at ${emailLayoutDirCtx.abspath}, overwrite?` : `Create a new email layout directory \`${emailLayoutDirCtx.key}\` at ${emailLayoutDirCtx.abspath}?`;
|
|
133
|
+
// Check if the email layout 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 email layout either from a template or from scratch
|
|
137
|
+
await (flags.template ? this.fromTemplate(emailLayoutDirCtx, name, flags.template) : this.fromScratch(emailLayoutDirCtx, name));
|
|
138
|
+
if (flags.push) {
|
|
139
|
+
_ux.spinner.start("‣ Pushing email layout to Knock");
|
|
140
|
+
try {
|
|
141
|
+
await _push.default.run([
|
|
142
|
+
key
|
|
143
|
+
]);
|
|
144
|
+
} catch (error) {
|
|
145
|
+
this.error(`Failed to push email layout to Knock: ${error}`);
|
|
146
|
+
} finally{
|
|
147
|
+
_ux.spinner.stop();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
this.log(`‣ Successfully created email layout \`${key}\``);
|
|
151
|
+
}
|
|
152
|
+
async fromTemplate(emailLayoutDirCtx, name, templateString) {
|
|
153
|
+
// When being called from the template string, we want to try and generate
|
|
154
|
+
// the email layout from the provided template.
|
|
155
|
+
_ux.spinner.start(`‣ Generating email layout from template \`${templateString}\``);
|
|
156
|
+
try {
|
|
157
|
+
await _emaillayout.generateEmailLayoutFromTemplate(emailLayoutDirCtx, templateString, {
|
|
158
|
+
name
|
|
159
|
+
});
|
|
160
|
+
} catch (error) {
|
|
161
|
+
this.error(`Failed to generate email layout from template: ${error}`);
|
|
162
|
+
} finally{
|
|
163
|
+
_ux.spinner.stop();
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
async fromScratch(emailLayoutDirCtx, name) {
|
|
167
|
+
// Generate the email layout directory with scaffolded content
|
|
168
|
+
await _emaillayout.generateEmailLayoutDir(emailLayoutDirCtx, {
|
|
169
|
+
name
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
async getEmailLayoutDirContext(emailLayoutKey) {
|
|
173
|
+
const { resourceDir, cwd: runCwd } = this.runContext;
|
|
174
|
+
// Inside an existing resource dir, use it if valid for the target email layout.
|
|
175
|
+
if (resourceDir) {
|
|
176
|
+
const target = {
|
|
177
|
+
commandId: _basecommand.default.id,
|
|
178
|
+
type: "email_layout",
|
|
179
|
+
key: emailLayoutKey
|
|
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, "email_layout", runCwd);
|
|
185
|
+
// Not inside any existing email layout directory, which means either create a
|
|
186
|
+
// new email layout directory in the cwd, or update it if there is one already.
|
|
187
|
+
if (emailLayoutKey) {
|
|
188
|
+
const dirPath = _nodepath.resolve(dirCtx.abspath, emailLayoutKey);
|
|
189
|
+
const exists = await _emaillayout.isEmailLayoutDir(dirPath);
|
|
190
|
+
return {
|
|
191
|
+
type: "email_layout",
|
|
192
|
+
key: emailLayoutKey,
|
|
193
|
+
abspath: dirPath,
|
|
194
|
+
exists
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
// Not in any email layout directory, nor an email layout key arg was given so error.
|
|
198
|
+
return this.error("Missing 1 required arg:\nemailLayoutKey");
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
_define_property(EmailLayoutNew, "summary", "Create a new email layout with a minimal configuration.");
|
|
202
|
+
_define_property(EmailLayoutNew, "flags", {
|
|
203
|
+
name: _core.Flags.string({
|
|
204
|
+
summary: "The name of the email layout",
|
|
205
|
+
char: "n"
|
|
206
|
+
}),
|
|
207
|
+
key: _core.Flags.string({
|
|
208
|
+
summary: "The key of the email layout",
|
|
209
|
+
char: "k"
|
|
210
|
+
}),
|
|
211
|
+
environment: _core.Flags.string({
|
|
212
|
+
summary: "The environment to create the email layout 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 email layout directory without confirmation."
|
|
218
|
+
}),
|
|
219
|
+
push: _core.Flags.boolean({
|
|
220
|
+
summary: "Whether or not to push the email layout to Knock after creation.",
|
|
221
|
+
default: false,
|
|
222
|
+
char: "p"
|
|
223
|
+
}),
|
|
224
|
+
template: _core.Flags.string({
|
|
225
|
+
summary: "The template to use for the email layout. Should be `email-layouts/{key}`."
|
|
226
|
+
})
|
|
227
|
+
});
|
|
228
|
+
_define_property(EmailLayoutNew, "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 _emaillayout = /*#__PURE__*/ _interop_require_wildcard(require("../../lib/marshal/email-layout"));
|
|
@@ -119,11 +120,8 @@ class EmailLayoutPull extends _basecommand.default {
|
|
|
119
120
|
// Pull all email layouts
|
|
120
121
|
async pullAllEmailLayouts() {
|
|
121
122
|
const { flags } = this.props;
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
exists: true
|
|
125
|
-
};
|
|
126
|
-
const targetDirCtx = flags["layouts-dir"] || defaultToCwd;
|
|
123
|
+
const layoutsIndexDirCtx = await (0, _projectconfig.resolveResourceDir)(this.projectConfig, "email_layout", this.runContext.cwd);
|
|
124
|
+
const targetDirCtx = flags["layouts-dir"] || layoutsIndexDirCtx;
|
|
127
125
|
const prompt = targetDirCtx.exists ? `Pull latest layouts into ${targetDirCtx.abspath}?\n This will overwrite the contents of this directory.` : `Create a new layouts directory at ${targetDirCtx.abspath}?`;
|
|
128
126
|
const input = flags.force || await (0, _ux.promptToConfirm)(prompt);
|
|
129
127
|
if (!input) return;
|
|
@@ -171,10 +169,11 @@ class EmailLayoutPull extends _basecommand.default {
|
|
|
171
169
|
};
|
|
172
170
|
return (0, _runcontext.ensureResourceDirForTarget)(resourceDir, target);
|
|
173
171
|
}
|
|
172
|
+
const layoutsIndexDirCtx = await (0, _projectconfig.resolveResourceDir)(this.projectConfig, "email_layout", runCwd);
|
|
174
173
|
// Not inside any existing email layout directory, which means either create a
|
|
175
174
|
// new email layout directory in the cwd, or update it if there is one already.
|
|
176
175
|
if (emailLayoutKey) {
|
|
177
|
-
const dirPath = _nodepath.resolve(
|
|
176
|
+
const dirPath = _nodepath.resolve(layoutsIndexDirCtx.abspath, emailLayoutKey);
|
|
178
177
|
const exists = await _emaillayout.isEmailLayoutDir(dirPath);
|
|
179
178
|
return {
|
|
180
179
|
type: "email_layout",
|
|
@@ -83,7 +83,7 @@ class EmailLayoutPush extends _basecommand.default {
|
|
|
83
83
|
async run() {
|
|
84
84
|
const { flags } = this.props;
|
|
85
85
|
// 1. First read all layout directories found for the given command.
|
|
86
|
-
const target = await _emaillayout.ensureValidCommandTarget(this.props, this.runContext);
|
|
86
|
+
const target = await _emaillayout.ensureValidCommandTarget(this.props, this.runContext, this.projectConfig);
|
|
87
87
|
const [layouts, readErrors] = await _emaillayout.readAllForCommandTarget(target, {
|
|
88
88
|
withExtractedFiles: true
|
|
89
89
|
});
|
|
@@ -80,7 +80,7 @@ function _interop_require_wildcard(obj, nodeInterop) {
|
|
|
80
80
|
class EmailLayoutValidate extends _basecommand.default {
|
|
81
81
|
async run() {
|
|
82
82
|
// 1. Read all layout directories found for the given command.
|
|
83
|
-
const target = await _emaillayout.ensureValidCommandTarget(this.props, this.runContext);
|
|
83
|
+
const target = await _emaillayout.ensureValidCommandTarget(this.props, this.runContext, this.projectConfig);
|
|
84
84
|
const [layouts, readErrors] = await _emaillayout.readAllForCommandTarget(target, {
|
|
85
85
|
withExtractedFiles: true
|
|
86
86
|
});
|
|
@@ -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", {});
|
|
@@ -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
|
});
|