@knocklabs/cli 0.2.0 → 0.2.2
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 +258 -36
- package/dist/commands/branch/create.js +56 -0
- package/dist/commands/branch/delete.js +60 -0
- package/dist/commands/branch/list.js +89 -0
- package/dist/commands/commit/get.js +4 -4
- package/dist/commands/commit/index.js +47 -2
- package/dist/commands/commit/list.js +61 -13
- package/dist/commands/guide/activate.js +48 -4
- package/dist/commands/guide/generate-types.js +4 -1
- package/dist/commands/guide/get.js +46 -3
- package/dist/commands/guide/list.js +46 -3
- package/dist/commands/guide/pull.js +6 -4
- package/dist/commands/guide/push.js +4 -3
- package/dist/commands/guide/validate.js +4 -3
- package/dist/commands/layout/get.js +46 -1
- package/dist/commands/layout/list.js +46 -1
- package/dist/commands/layout/pull.js +6 -2
- package/dist/commands/layout/push.js +4 -1
- package/dist/commands/layout/validate.js +4 -1
- package/dist/commands/login.js +1 -0
- package/dist/commands/logout.js +1 -0
- package/dist/commands/message-type/get.js +46 -3
- package/dist/commands/message-type/list.js +46 -3
- package/dist/commands/message-type/pull.js +6 -4
- package/dist/commands/message-type/push.js +4 -3
- package/dist/commands/message-type/validate.js +4 -3
- package/dist/commands/partial/get.js +46 -1
- package/dist/commands/partial/list.js +46 -1
- package/dist/commands/partial/pull.js +6 -2
- package/dist/commands/partial/push.js +4 -1
- package/dist/commands/partial/validate.js +6 -1
- package/dist/commands/pull.js +28 -8
- package/dist/commands/push.js +27 -8
- package/dist/commands/translation/get.js +5 -1
- package/dist/commands/translation/list.js +5 -1
- package/dist/commands/translation/pull.js +8 -3
- package/dist/commands/translation/push.js +4 -1
- package/dist/commands/translation/validate.js +4 -1
- package/dist/commands/whoami.js +7 -8
- package/dist/commands/workflow/activate.js +47 -3
- package/dist/commands/workflow/generate-types.js +4 -1
- package/dist/commands/workflow/get.js +9 -4
- package/dist/commands/workflow/list.js +5 -1
- package/dist/commands/workflow/pull.js +6 -2
- package/dist/commands/workflow/push.js +4 -1
- package/dist/commands/workflow/run.js +46 -2
- package/dist/commands/workflow/validate.js +4 -1
- package/dist/lib/api-v1.js +57 -20
- package/dist/lib/helpers/arg.js +24 -0
- package/dist/lib/helpers/command.js +14 -0
- package/dist/lib/helpers/flag.js +18 -0
- package/dist/lib/helpers/request.js +48 -2
- package/dist/lib/helpers/string.js +4 -0
- package/dist/lib/marshal/commit/index.js +0 -1
- package/dist/lib/marshal/index.isomorphic.js +8 -4
- package/dist/lib/marshal/reusable-step/helpers.js +72 -0
- package/dist/lib/marshal/reusable-step/index.js +19 -0
- package/dist/lib/marshal/reusable-step/processor.isomorphic.js +86 -0
- package/dist/lib/marshal/{commit → reusable-step}/types.js +0 -1
- package/dist/lib/resources.js +6 -1
- package/dist/lib/urls.js +4 -0
- package/oclif.manifest.json +489 -50
- package/package.json +16 -5
- package/dist/commands/ping.js +0 -37
|
@@ -12,16 +12,28 @@ _export(exports, {
|
|
|
12
12
|
get formatErrorRespMessage () {
|
|
13
13
|
return formatErrorRespMessage;
|
|
14
14
|
},
|
|
15
|
+
get formatMgmtError () {
|
|
16
|
+
return formatMgmtError;
|
|
17
|
+
},
|
|
15
18
|
get isSuccessResp () {
|
|
16
19
|
return isSuccessResp;
|
|
17
20
|
},
|
|
18
21
|
get withSpinner () {
|
|
19
22
|
return withSpinner;
|
|
23
|
+
},
|
|
24
|
+
get withSpinnerV2 () {
|
|
25
|
+
return withSpinnerV2;
|
|
20
26
|
}
|
|
21
27
|
});
|
|
28
|
+
const _mgmt = /*#__PURE__*/ _interop_require_default(require("@knocklabs/mgmt"));
|
|
22
29
|
const _core = require("@oclif/core");
|
|
23
30
|
const _error = require("./error");
|
|
24
31
|
const _ux = require("./ux");
|
|
32
|
+
function _interop_require_default(obj) {
|
|
33
|
+
return obj && obj.__esModule ? obj : {
|
|
34
|
+
default: obj
|
|
35
|
+
};
|
|
36
|
+
}
|
|
25
37
|
const isSuccessResp = (resp)=>resp.status >= 200 && resp.status < 300;
|
|
26
38
|
const formatErrorRespMessage = ({ status, data })=>{
|
|
27
39
|
if (status === 500) {
|
|
@@ -36,16 +48,50 @@ const formatErrorRespMessage = ({ status, data })=>{
|
|
|
36
48
|
}
|
|
37
49
|
return message;
|
|
38
50
|
};
|
|
51
|
+
const formatMgmtError = (apiError)=>{
|
|
52
|
+
if (apiError.status === 500) {
|
|
53
|
+
return "An internal server error occurred";
|
|
54
|
+
}
|
|
55
|
+
var _apiError_error_message;
|
|
56
|
+
// Prefer the error message from the error object over
|
|
57
|
+
// the error message formatted by the Stainless SDK
|
|
58
|
+
const description = `${(_apiError_error_message = apiError.error.message) !== null && _apiError_error_message !== void 0 ? _apiError_error_message : apiError.message} (status: ${apiError.status})`;
|
|
59
|
+
var _apiError_error_errors;
|
|
60
|
+
const inputErrors = (_apiError_error_errors = apiError.error.errors) !== null && _apiError_error_errors !== void 0 ? _apiError_error_errors : [];
|
|
61
|
+
if (Array.isArray(inputErrors) && inputErrors.length > 0) {
|
|
62
|
+
const errs = inputErrors.map((e)=>new _error.JsonDataError(e.message, e.field));
|
|
63
|
+
return errs.length === 0 ? description : description + "\n\n" + (0, _error.formatErrors)(errs, {
|
|
64
|
+
indentBy: 2
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return description;
|
|
68
|
+
};
|
|
39
69
|
const withSpinner = async (requestFn, opts = {})=>{
|
|
40
|
-
const { action = "‣ Loading"
|
|
70
|
+
const { action = "‣ Loading" } = opts;
|
|
41
71
|
// Suppress printing the spinner in tests, oclif doesn't for some reasons.
|
|
42
72
|
_ux.spinner.start(action);
|
|
43
73
|
const resp = await requestFn();
|
|
44
74
|
// Error out before the action stop so the spinner can update accordingly.
|
|
45
|
-
if (
|
|
75
|
+
if (!isSuccessResp(resp)) {
|
|
46
76
|
const message = formatErrorRespMessage(resp);
|
|
47
77
|
_core.ux.error(new _error.ApiError(message));
|
|
48
78
|
}
|
|
49
79
|
_ux.spinner.stop();
|
|
50
80
|
return resp;
|
|
51
81
|
};
|
|
82
|
+
const withSpinnerV2 = async (requestFn, opts = {})=>{
|
|
83
|
+
const { action = "‣ Loading" } = opts;
|
|
84
|
+
// Suppress printing the spinner in tests, oclif doesn't for some reasons.
|
|
85
|
+
_ux.spinner.start(action);
|
|
86
|
+
try {
|
|
87
|
+
const resp = await requestFn();
|
|
88
|
+
_ux.spinner.stop();
|
|
89
|
+
return resp;
|
|
90
|
+
} catch (error) {
|
|
91
|
+
if (error instanceof _mgmt.default.APIError) {
|
|
92
|
+
const message = formatMgmtError(error);
|
|
93
|
+
return _core.ux.error(new _error.ApiError(message));
|
|
94
|
+
}
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
};
|
|
@@ -16,6 +16,9 @@ _export(exports, {
|
|
|
16
16
|
},
|
|
17
17
|
get indentString () {
|
|
18
18
|
return indentString;
|
|
19
|
+
},
|
|
20
|
+
get slugify () {
|
|
21
|
+
return slugify;
|
|
19
22
|
}
|
|
20
23
|
});
|
|
21
24
|
const SLUG_FORMAT_RE = /^[\w-]+$/;
|
|
@@ -44,3 +47,4 @@ const indentString = (string, count = 0, options = {})=>{
|
|
|
44
47
|
const regex = includeEmptyLines ? /^/gm : /^(?!\s*$)/gm;
|
|
45
48
|
return string.replace(regex, indent.repeat(count));
|
|
46
49
|
};
|
|
50
|
+
const slugify = (input)=>input.toLowerCase().trim().replace(/\s+/g, "-");
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
3
3
|
value: true
|
|
4
4
|
});
|
|
5
5
|
_export_star(require("./helpers"), exports);
|
|
6
|
-
_export_star(require("./types"), exports);
|
|
7
6
|
function _export_star(from, to) {
|
|
8
7
|
Object.keys(from).forEach(function(k) {
|
|
9
8
|
if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
|
|
@@ -23,16 +23,20 @@ _export(exports, {
|
|
|
23
23
|
get buildPartialDirBundle () {
|
|
24
24
|
return _processorisomorphic3.buildPartialDirBundle;
|
|
25
25
|
},
|
|
26
|
+
get buildReusableStepDirBundle () {
|
|
27
|
+
return _processorisomorphic4.buildReusableStepDirBundle;
|
|
28
|
+
},
|
|
26
29
|
get buildTranslationDirBundle () {
|
|
27
|
-
return
|
|
30
|
+
return _processorisomorphic5.buildTranslationDirBundle;
|
|
28
31
|
},
|
|
29
32
|
get buildWorkflowDirBundle () {
|
|
30
|
-
return
|
|
33
|
+
return _processorisomorphic6.buildWorkflowDirBundle;
|
|
31
34
|
}
|
|
32
35
|
});
|
|
33
36
|
const _processorisomorphic = require("./email-layout/processor.isomorphic");
|
|
34
37
|
const _processorisomorphic1 = require("./guide/processor.isomorphic");
|
|
35
38
|
const _processorisomorphic2 = require("./message-type/processor.isomorphic");
|
|
36
39
|
const _processorisomorphic3 = require("./partial/processor.isomorphic");
|
|
37
|
-
const _processorisomorphic4 = require("./
|
|
38
|
-
const _processorisomorphic5 = require("./
|
|
40
|
+
const _processorisomorphic4 = require("./reusable-step/processor.isomorphic");
|
|
41
|
+
const _processorisomorphic5 = require("./translation/processor.isomorphic");
|
|
42
|
+
const _processorisomorphic6 = require("./workflow/processor.isomorphic");
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get isReusableStepDir () {
|
|
13
|
+
return isReusableStepDir;
|
|
14
|
+
},
|
|
15
|
+
get lsReusableStepJson () {
|
|
16
|
+
return lsReusableStepJson;
|
|
17
|
+
},
|
|
18
|
+
get reusableStepJsonPath () {
|
|
19
|
+
return reusableStepJsonPath;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
const _nodepath = /*#__PURE__*/ _interop_require_wildcard(require("node:path"));
|
|
23
|
+
const _fsextra = /*#__PURE__*/ _interop_require_wildcard(require("fs-extra"));
|
|
24
|
+
const _processorisomorphic = require("./processor.isomorphic");
|
|
25
|
+
function _getRequireWildcardCache(nodeInterop) {
|
|
26
|
+
if (typeof WeakMap !== "function") return null;
|
|
27
|
+
var cacheBabelInterop = new WeakMap();
|
|
28
|
+
var cacheNodeInterop = new WeakMap();
|
|
29
|
+
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
30
|
+
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
31
|
+
})(nodeInterop);
|
|
32
|
+
}
|
|
33
|
+
function _interop_require_wildcard(obj, nodeInterop) {
|
|
34
|
+
if (!nodeInterop && obj && obj.__esModule) {
|
|
35
|
+
return obj;
|
|
36
|
+
}
|
|
37
|
+
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
38
|
+
return {
|
|
39
|
+
default: obj
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
var cache = _getRequireWildcardCache(nodeInterop);
|
|
43
|
+
if (cache && cache.has(obj)) {
|
|
44
|
+
return cache.get(obj);
|
|
45
|
+
}
|
|
46
|
+
var newObj = {
|
|
47
|
+
__proto__: null
|
|
48
|
+
};
|
|
49
|
+
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
50
|
+
for(var key in obj){
|
|
51
|
+
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
52
|
+
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
53
|
+
if (desc && (desc.get || desc.set)) {
|
|
54
|
+
Object.defineProperty(newObj, key, desc);
|
|
55
|
+
} else {
|
|
56
|
+
newObj[key] = obj[key];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
newObj.default = obj;
|
|
61
|
+
if (cache) {
|
|
62
|
+
cache.set(obj, newObj);
|
|
63
|
+
}
|
|
64
|
+
return newObj;
|
|
65
|
+
}
|
|
66
|
+
const reusableStepJsonPath = (reusableStepDirCtx)=>_nodepath.resolve(reusableStepDirCtx.abspath, _processorisomorphic.REUSABLE_STEP_JSON);
|
|
67
|
+
const isReusableStepDir = async (dirPath)=>Boolean(await lsReusableStepJson(dirPath));
|
|
68
|
+
const lsReusableStepJson = async (dirPath)=>{
|
|
69
|
+
const reusableStepJsonPath = _nodepath.resolve(dirPath, _processorisomorphic.REUSABLE_STEP_JSON);
|
|
70
|
+
const exists = await _fsextra.pathExists(reusableStepJsonPath);
|
|
71
|
+
return exists ? reusableStepJsonPath : undefined;
|
|
72
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
_export_star(require("./processor.isomorphic"), exports);
|
|
6
|
+
_export_star(require("./types"), exports);
|
|
7
|
+
function _export_star(from, to) {
|
|
8
|
+
Object.keys(from).forEach(function(k) {
|
|
9
|
+
if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
|
|
10
|
+
Object.defineProperty(to, k, {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
get: function() {
|
|
13
|
+
return from[k];
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
return from;
|
|
19
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* IMPORTANT:
|
|
3
|
+
*
|
|
4
|
+
* This file is suffixed with `.isomorphic` because the code in this file is
|
|
5
|
+
* meant to run not just in a nodejs environment but also in a browser. For this
|
|
6
|
+
* reason there are some restrictions for which nodejs imports are allowed in
|
|
7
|
+
* this module. See `.eslintrc.json` for more details.
|
|
8
|
+
*/ "use strict";
|
|
9
|
+
Object.defineProperty(exports, "__esModule", {
|
|
10
|
+
value: true
|
|
11
|
+
});
|
|
12
|
+
function _export(target, all) {
|
|
13
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
_export(exports, {
|
|
19
|
+
get REUSABLE_STEP_JSON () {
|
|
20
|
+
return REUSABLE_STEP_JSON;
|
|
21
|
+
},
|
|
22
|
+
get buildReusableStepDirBundle () {
|
|
23
|
+
return buildReusableStepDirBundle;
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
const _lodash = require("lodash");
|
|
27
|
+
const _objectisomorphic = require("../../helpers/object.isomorphic");
|
|
28
|
+
const _constisomorphic = require("../shared/const.isomorphic");
|
|
29
|
+
const _helpersisomorphic = require("../shared/helpers.isomorphic");
|
|
30
|
+
const REUSABLE_STEP_JSON = "reusable_step.json";
|
|
31
|
+
const compileExtractionSettings = (reusableStep)=>{
|
|
32
|
+
const extractableFields = (0, _lodash.get)(reusableStep, [
|
|
33
|
+
"__annotation",
|
|
34
|
+
"extractable_fields"
|
|
35
|
+
], {});
|
|
36
|
+
const map = new Map();
|
|
37
|
+
for (const key of Object.keys(reusableStep)){
|
|
38
|
+
// If the field we are on is extractable, then add its extraction
|
|
39
|
+
// settings to the map with the current object path.
|
|
40
|
+
if (key in extractableFields) {
|
|
41
|
+
map.set([
|
|
42
|
+
key
|
|
43
|
+
], extractableFields[key]);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return map;
|
|
47
|
+
};
|
|
48
|
+
const buildReusableStepDirBundle = (remoteReusableStep, localReusableStep = {})=>{
|
|
49
|
+
const bundle = {};
|
|
50
|
+
const mutRemoteReusableStep = (0, _lodash.cloneDeep)(remoteReusableStep);
|
|
51
|
+
// A map of extraction settings of every field in the reusable step
|
|
52
|
+
const compiledExtractionSettings = compileExtractionSettings(mutRemoteReusableStep);
|
|
53
|
+
// Iterate through each extractable field, determine whether we need to
|
|
54
|
+
// extract the field content, and if so, perform the extraction.
|
|
55
|
+
for (const [objPathParts, extractionSettings] of compiledExtractionSettings){
|
|
56
|
+
// If this reusable step doesn't have this field path, then we don't extract.
|
|
57
|
+
if (!(0, _lodash.has)(mutRemoteReusableStep, objPathParts)) continue;
|
|
58
|
+
// If the field at this path is extracted in the local reusable step, then
|
|
59
|
+
// always extract; otherwise extract based on the field settings default.
|
|
60
|
+
const objPathStr = _objectisomorphic.ObjPath.stringify(objPathParts);
|
|
61
|
+
const extractedFilePath = (0, _lodash.get)(localReusableStep, `${objPathStr}${_constisomorphic.FILEPATH_MARKER}`);
|
|
62
|
+
const { default: extractByDefault, file_ext: fileExt } = extractionSettings;
|
|
63
|
+
if (!extractedFilePath && !extractByDefault) continue;
|
|
64
|
+
// By this point, we have a field where we need to extract its content.
|
|
65
|
+
const data = (0, _lodash.get)(mutRemoteReusableStep, objPathParts);
|
|
66
|
+
const fileName = objPathParts.pop();
|
|
67
|
+
// If we have an extracted file path from the local reusable step, we use that.
|
|
68
|
+
// In the other case we use the default path.
|
|
69
|
+
const relpath = typeof extractedFilePath === "string" ? extractedFilePath : `${fileName}.${fileExt}`;
|
|
70
|
+
// Perform the extraction by adding the content and its file path to the
|
|
71
|
+
// bundle for writing to the file system later. Then replace the field
|
|
72
|
+
// content with the extracted file path and mark the field as extracted
|
|
73
|
+
// with @ suffix.
|
|
74
|
+
const content = typeof data === "string" ? data : JSON.stringify(data, null, 2);
|
|
75
|
+
(0, _lodash.set)(bundle, [
|
|
76
|
+
relpath
|
|
77
|
+
], content);
|
|
78
|
+
(0, _lodash.set)(mutRemoteReusableStep, `${objPathStr}${_constisomorphic.FILEPATH_MARKER}`, relpath);
|
|
79
|
+
(0, _lodash.unset)(mutRemoteReusableStep, objPathStr);
|
|
80
|
+
}
|
|
81
|
+
// At this point the bundle contains all extractable files, so we finally add
|
|
82
|
+
// the reusable step JSON relative path + the file content.
|
|
83
|
+
return (0, _lodash.set)(bundle, [
|
|
84
|
+
REUSABLE_STEP_JSON
|
|
85
|
+
], (0, _helpersisomorphic.prepareResourceJson)(mutRemoteReusableStep));
|
|
86
|
+
};
|
package/dist/lib/resources.js
CHANGED
|
@@ -22,11 +22,16 @@ const ALL_RESOURCE_TYPES = [
|
|
|
22
22
|
// Email layouts next, as workflows with email channel steps may reference them
|
|
23
23
|
"email_layout",
|
|
24
24
|
"workflow",
|
|
25
|
+
// Message types then guides, as guides use message types.
|
|
26
|
+
"message_type",
|
|
27
|
+
"guide",
|
|
25
28
|
"translation"
|
|
26
29
|
];
|
|
27
30
|
const RESOURCE_SUBDIRS = {
|
|
28
31
|
email_layout: "layouts",
|
|
29
32
|
partial: "partials",
|
|
30
33
|
translation: "translations",
|
|
31
|
-
workflow: "workflows"
|
|
34
|
+
workflow: "workflows",
|
|
35
|
+
message_type: "message-types",
|
|
36
|
+
guide: "guides"
|
|
32
37
|
};
|
package/dist/lib/urls.js
CHANGED
|
@@ -23,6 +23,9 @@ _export(exports, {
|
|
|
23
23
|
},
|
|
24
24
|
get authSuccessUrl () {
|
|
25
25
|
return authSuccessUrl;
|
|
26
|
+
},
|
|
27
|
+
get viewWorkflowUrl () {
|
|
28
|
+
return viewWorkflowUrl;
|
|
26
29
|
}
|
|
27
30
|
});
|
|
28
31
|
const DEFAULT_DASHBOARD_URL = "https://dashboard.knock.app";
|
|
@@ -30,3 +33,4 @@ const DEFAULT_AUTH_URL = "https://signin.knock.app";
|
|
|
30
33
|
const DEFAULT_API_URL = "https://control.knock.app";
|
|
31
34
|
const authSuccessUrl = (dashboardUrl)=>`${dashboardUrl}/auth/oauth/cli`;
|
|
32
35
|
const authErrorUrl = (dashboardUrl, error)=>`${dashboardUrl}/auth/oauth/cli?error=${error}`;
|
|
36
|
+
const viewWorkflowUrl = (dashboardUrl, accountSlug, envOrBranchSlug, workflowKey)=>`${dashboardUrl}/${accountSlug}/${envOrBranchSlug.toLowerCase()}/workflows/${workflowKey}`;
|