@knocklabs/cli 0.1.23 → 0.2.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 +128 -102
- package/bin/dev.js +4 -4
- 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/knock.js +3 -0
- package/dist/commands/login.js +50 -0
- package/dist/commands/logout.js +48 -0
- package/dist/commands/whoami.js +9 -6
- package/dist/lib/api-v1.js +30 -7
- package/dist/lib/auth.js +256 -0
- package/dist/lib/base-command.js +85 -12
- package/dist/lib/helpers/arg.js +23 -0
- package/dist/lib/helpers/browser.js +25 -0
- package/dist/lib/helpers/request.js +48 -2
- 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/reusable-step/types.js +4 -0
- package/dist/lib/types.js +4 -0
- package/dist/lib/urls.js +32 -0
- package/dist/lib/user-config.js +69 -31
- package/oclif.manifest.json +393 -146
- package/package.json +11 -8
package/dist/lib/base-command.js
CHANGED
|
@@ -10,8 +10,10 @@ Object.defineProperty(exports, "default", {
|
|
|
10
10
|
});
|
|
11
11
|
const _core = require("@oclif/core");
|
|
12
12
|
const _apiv1 = /*#__PURE__*/ _interop_require_default(require("./api-v1"));
|
|
13
|
+
const _auth = /*#__PURE__*/ _interop_require_default(require("./auth"));
|
|
13
14
|
const _runcontext = /*#__PURE__*/ _interop_require_wildcard(require("./run-context"));
|
|
14
|
-
const
|
|
15
|
+
const _urls = require("./urls");
|
|
16
|
+
const _userconfig = require("./user-config");
|
|
15
17
|
function _define_property(obj, key, value) {
|
|
16
18
|
if (key in obj) {
|
|
17
19
|
Object.defineProperty(obj, key, {
|
|
@@ -71,24 +73,97 @@ function _interop_require_wildcard(obj, nodeInterop) {
|
|
|
71
73
|
}
|
|
72
74
|
return newObj;
|
|
73
75
|
}
|
|
76
|
+
function sessionWithDefaultOrigins(sessionContext) {
|
|
77
|
+
var _sessionContext_apiOrigin, _sessionContext_dashboardOrigin, _sessionContext_authOrigin;
|
|
78
|
+
return {
|
|
79
|
+
...sessionContext,
|
|
80
|
+
apiOrigin: (_sessionContext_apiOrigin = sessionContext.apiOrigin) !== null && _sessionContext_apiOrigin !== void 0 ? _sessionContext_apiOrigin : _urls.DEFAULT_API_URL,
|
|
81
|
+
dashboardOrigin: (_sessionContext_dashboardOrigin = sessionContext.dashboardOrigin) !== null && _sessionContext_dashboardOrigin !== void 0 ? _sessionContext_dashboardOrigin : _urls.DEFAULT_DASHBOARD_URL,
|
|
82
|
+
authOrigin: (_sessionContext_authOrigin = sessionContext.authOrigin) !== null && _sessionContext_authOrigin !== void 0 ? _sessionContext_authOrigin : _urls.DEFAULT_AUTH_URL
|
|
83
|
+
};
|
|
84
|
+
}
|
|
74
85
|
class BaseCommand extends _core.Command {
|
|
75
86
|
async init() {
|
|
76
87
|
await super.init();
|
|
88
|
+
this.configStore = new _userconfig.UserConfigStore(this.config.configDir);
|
|
77
89
|
// 1. Load user's config from the config dir, as available.
|
|
78
|
-
await
|
|
90
|
+
await this.configStore.load();
|
|
79
91
|
// 2. Parse flags and args, must come after the user config load.
|
|
80
92
|
const { args, flags } = await this.parse(this.ctor);
|
|
81
93
|
this.props = {
|
|
82
94
|
args: args,
|
|
83
95
|
flags: flags
|
|
84
96
|
};
|
|
85
|
-
// 3.
|
|
86
|
-
this.
|
|
87
|
-
// 4.
|
|
97
|
+
// 3. Build the initial session context.
|
|
98
|
+
this.sessionContext = this.buildSessionContext();
|
|
99
|
+
// 4. If the command requires authentication, ensure the session is authenticated.
|
|
100
|
+
if (this.requiresAuth) {
|
|
101
|
+
this.ensureAuthenticated();
|
|
102
|
+
}
|
|
103
|
+
// 5. If the session context is an OAuth session, refresh the access token.
|
|
104
|
+
if (this.sessionContext.type === "oauth") {
|
|
105
|
+
await this.refreshAccessTokenForSession();
|
|
106
|
+
}
|
|
107
|
+
// 6. Instantiate a knock api client.
|
|
108
|
+
this.apiV1 = new _apiv1.default(this.sessionContext, this.config);
|
|
109
|
+
// 7. Load the run context of the invoked command.
|
|
88
110
|
this.runContext = await _runcontext.load(this.id);
|
|
89
111
|
}
|
|
112
|
+
buildSessionContext() {
|
|
113
|
+
const userConfig = this.configStore.get();
|
|
114
|
+
const session = userConfig.userSession;
|
|
115
|
+
// If the user has a session and a service token is not provided, use the session.
|
|
116
|
+
if (session && !this.props.flags["service-token"]) {
|
|
117
|
+
var _this_props_flags_apiorigin;
|
|
118
|
+
return sessionWithDefaultOrigins({
|
|
119
|
+
type: "oauth",
|
|
120
|
+
session,
|
|
121
|
+
apiOrigin: (_this_props_flags_apiorigin = this.props.flags["api-origin"]) !== null && _this_props_flags_apiorigin !== void 0 ? _this_props_flags_apiorigin : userConfig.apiOrigin,
|
|
122
|
+
dashboardOrigin: userConfig.dashboardOrigin,
|
|
123
|
+
authOrigin: userConfig.authOrigin
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
var _this_props_flags_servicetoken, _this_props_flags_apiorigin1;
|
|
127
|
+
// Otherwise, default to this being a service token session.
|
|
128
|
+
return sessionWithDefaultOrigins({
|
|
129
|
+
type: "service",
|
|
130
|
+
token: (_this_props_flags_servicetoken = this.props.flags["service-token"]) !== null && _this_props_flags_servicetoken !== void 0 ? _this_props_flags_servicetoken : userConfig.serviceToken,
|
|
131
|
+
apiOrigin: (_this_props_flags_apiorigin1 = this.props.flags["api-origin"]) !== null && _this_props_flags_apiorigin1 !== void 0 ? _this_props_flags_apiorigin1 : userConfig.apiOrigin,
|
|
132
|
+
dashboardOrigin: userConfig.dashboardOrigin,
|
|
133
|
+
authOrigin: userConfig.authOrigin
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
ensureAuthenticated() {
|
|
137
|
+
if (this.sessionContext.type === "service" && !this.sessionContext.token || this.sessionContext.type === "oauth" && !this.sessionContext.session) {
|
|
138
|
+
this.error("No token found. Refusing to run command.");
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
async refreshAccessTokenForSession() {
|
|
142
|
+
// Maybe refresh the access token?
|
|
143
|
+
try {
|
|
144
|
+
var _this_sessionContext_session, _this_sessionContext_session1;
|
|
145
|
+
var _this_sessionContext_session_clientId, _this_sessionContext_session_refreshToken;
|
|
146
|
+
const refreshedSession = await _auth.default.refreshAccessToken({
|
|
147
|
+
authUrl: this.sessionContext.authOrigin,
|
|
148
|
+
clientId: (_this_sessionContext_session_clientId = (_this_sessionContext_session = this.sessionContext.session) === null || _this_sessionContext_session === void 0 ? void 0 : _this_sessionContext_session.clientId) !== null && _this_sessionContext_session_clientId !== void 0 ? _this_sessionContext_session_clientId : "",
|
|
149
|
+
refreshToken: (_this_sessionContext_session_refreshToken = (_this_sessionContext_session1 = this.sessionContext.session) === null || _this_sessionContext_session1 === void 0 ? void 0 : _this_sessionContext_session1.refreshToken) !== null && _this_sessionContext_session_refreshToken !== void 0 ? _this_sessionContext_session_refreshToken : ""
|
|
150
|
+
});
|
|
151
|
+
this.debug("Successfully refreshed access token.");
|
|
152
|
+
// Update the user config to use the new session.
|
|
153
|
+
await this.configStore.set({
|
|
154
|
+
userSession: refreshedSession
|
|
155
|
+
});
|
|
156
|
+
// Update the session context to use the new session.
|
|
157
|
+
this.sessionContext = this.buildSessionContext();
|
|
158
|
+
} catch {
|
|
159
|
+
this.debug("Failed to refresh access token, clearing session.");
|
|
160
|
+
await this.configStore.set({
|
|
161
|
+
userSession: undefined
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
90
165
|
constructor(...args){
|
|
91
|
-
super(...args), _define_property(this, "props", void 0), _define_property(this, "apiV1", void 0), _define_property(this, "runContext", void 0);
|
|
166
|
+
super(...args), _define_property(this, "props", void 0), _define_property(this, "apiV1", void 0), _define_property(this, "runContext", void 0), _define_property(this, "sessionContext", void 0), _define_property(this, "configStore", void 0), _define_property(this, "requiresAuth", true);
|
|
92
167
|
}
|
|
93
168
|
}
|
|
94
169
|
// Base flags are inherited by any command that extends BaseCommand.
|
|
@@ -99,17 +174,15 @@ _define_property(BaseCommand, "baseFlags", {
|
|
|
99
174
|
// - if not available, fall back to user config
|
|
100
175
|
"service-token": _core.Flags.string({
|
|
101
176
|
summary: "The service token to authenticate with.",
|
|
102
|
-
required:
|
|
177
|
+
required: false,
|
|
103
178
|
multiple: false,
|
|
104
|
-
env: "KNOCK_SERVICE_TOKEN"
|
|
105
|
-
default: async ()=>_userconfig.default.get().serviceToken
|
|
179
|
+
env: "KNOCK_SERVICE_TOKEN"
|
|
106
180
|
}),
|
|
107
|
-
// Hidden
|
|
181
|
+
// Hidden flags to use a different api url for development purposes.
|
|
108
182
|
"api-origin": _core.Flags.string({
|
|
109
183
|
hidden: true,
|
|
110
184
|
required: false,
|
|
111
|
-
multiple: false
|
|
112
|
-
default: async ()=>_userconfig.default.get().apiOrigin
|
|
185
|
+
multiple: false
|
|
113
186
|
})
|
|
114
187
|
});
|
|
115
188
|
const _default = BaseCommand;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "CustomArgs", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return CustomArgs;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _core = require("@oclif/core");
|
|
12
|
+
const slugArg = _core.Args.custom({
|
|
13
|
+
parse: async (str)=>{
|
|
14
|
+
const slug = str.toLowerCase().trim().replace(/\s+/g, "-");
|
|
15
|
+
if (!slug) {
|
|
16
|
+
throw new Error("Invalid slug provided");
|
|
17
|
+
}
|
|
18
|
+
return slug;
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
const CustomArgs = {
|
|
22
|
+
slugArg
|
|
23
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "browser", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return browser;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _open = /*#__PURE__*/ _interop_require_default(require("open"));
|
|
12
|
+
function _interop_require_default(obj) {
|
|
13
|
+
return obj && obj.__esModule ? obj : {
|
|
14
|
+
default: obj
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
const browser = {
|
|
18
|
+
/**
|
|
19
|
+
* Opens a URL in the default browser
|
|
20
|
+
* @param url The URL to open
|
|
21
|
+
* @returns A promise that resolves when the URL is opened
|
|
22
|
+
*/ async openUrl (url) {
|
|
23
|
+
await (0, _open.default)(url);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
@@ -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
|
+
};
|
|
@@ -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/urls.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
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 DEFAULT_API_URL () {
|
|
13
|
+
return DEFAULT_API_URL;
|
|
14
|
+
},
|
|
15
|
+
get DEFAULT_AUTH_URL () {
|
|
16
|
+
return DEFAULT_AUTH_URL;
|
|
17
|
+
},
|
|
18
|
+
get DEFAULT_DASHBOARD_URL () {
|
|
19
|
+
return DEFAULT_DASHBOARD_URL;
|
|
20
|
+
},
|
|
21
|
+
get authErrorUrl () {
|
|
22
|
+
return authErrorUrl;
|
|
23
|
+
},
|
|
24
|
+
get authSuccessUrl () {
|
|
25
|
+
return authSuccessUrl;
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
const DEFAULT_DASHBOARD_URL = "https://dashboard.knock.app";
|
|
29
|
+
const DEFAULT_AUTH_URL = "https://signin.knock.app";
|
|
30
|
+
const DEFAULT_API_URL = "https://control.knock.app";
|
|
31
|
+
const authSuccessUrl = (dashboardUrl)=>`${dashboardUrl}/auth/oauth/cli`;
|
|
32
|
+
const authErrorUrl = (dashboardUrl, error)=>`${dashboardUrl}/auth/oauth/cli?error=${error}`;
|
package/dist/lib/user-config.js
CHANGED
|
@@ -4,16 +4,29 @@
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
-
Object.defineProperty(exports, "
|
|
7
|
+
Object.defineProperty(exports, "UserConfigStore", {
|
|
8
8
|
enumerable: true,
|
|
9
9
|
get: function() {
|
|
10
|
-
return
|
|
10
|
+
return UserConfigStore;
|
|
11
11
|
}
|
|
12
12
|
});
|
|
13
13
|
const _nodepath = /*#__PURE__*/ _interop_require_wildcard(require("node:path"));
|
|
14
14
|
const _fsextra = /*#__PURE__*/ _interop_require_wildcard(require("fs-extra"));
|
|
15
|
-
const
|
|
15
|
+
const _zod = require("zod");
|
|
16
16
|
const _const = require("./helpers/const");
|
|
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
|
+
}
|
|
17
30
|
function _getRequireWildcardCache(nodeInterop) {
|
|
18
31
|
if (typeof WeakMap !== "function") return null;
|
|
19
32
|
var cacheBabelInterop = new WeakMap();
|
|
@@ -55,33 +68,58 @@ function _interop_require_wildcard(obj, nodeInterop) {
|
|
|
55
68
|
}
|
|
56
69
|
return newObj;
|
|
57
70
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
71
|
+
// When a user has authenticated via OAuth, we store the session in the user config.
|
|
72
|
+
const userSessionSchema = _zod.z.object({
|
|
73
|
+
accessToken: _zod.z.string(),
|
|
74
|
+
clientId: _zod.z.string(),
|
|
75
|
+
refreshToken: _zod.z.string()
|
|
76
|
+
});
|
|
77
|
+
const userConfigSchema = _zod.z.object({
|
|
78
|
+
serviceToken: _zod.z.string().optional(),
|
|
79
|
+
apiOrigin: _zod.z.string().optional(),
|
|
80
|
+
dashboardOrigin: _zod.z.string().optional(),
|
|
81
|
+
authOrigin: _zod.z.string().optional(),
|
|
82
|
+
userSession: userSessionSchema.optional()
|
|
61
83
|
});
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (!USER_CONFIG) {
|
|
80
|
-
throw new Error("User config must be loaded first.");
|
|
84
|
+
class UserConfigStore {
|
|
85
|
+
async load() {
|
|
86
|
+
const readConfig = await this.maybeReadJsonConfig();
|
|
87
|
+
const validConfig = userConfigSchema.parse(readConfig || {});
|
|
88
|
+
this.userConfig = validConfig || {};
|
|
89
|
+
return this.userConfig;
|
|
90
|
+
}
|
|
91
|
+
get() {
|
|
92
|
+
return this.userConfig;
|
|
93
|
+
}
|
|
94
|
+
async set(updatedConfig) {
|
|
95
|
+
this.userConfig = {
|
|
96
|
+
...this.userConfig,
|
|
97
|
+
...updatedConfig
|
|
98
|
+
};
|
|
99
|
+
await this.maybeWriteJsonConfig();
|
|
100
|
+
return this.userConfig;
|
|
81
101
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
102
|
+
configPath() {
|
|
103
|
+
return _nodepath.resolve(this.configDir, "config.json");
|
|
104
|
+
}
|
|
105
|
+
async maybeReadJsonConfig() {
|
|
106
|
+
if (_const.isTestEnv) return {};
|
|
107
|
+
const path = this.configPath();
|
|
108
|
+
const exists = await _fsextra.pathExists(path);
|
|
109
|
+
if (!exists) return {};
|
|
110
|
+
return _fsextra.readJSON(path);
|
|
111
|
+
}
|
|
112
|
+
async maybeWriteJsonConfig() {
|
|
113
|
+
if (_const.isTestEnv) return;
|
|
114
|
+
const path = this.configPath();
|
|
115
|
+
await _fsextra.outputJson(path, this.userConfig, {
|
|
116
|
+
spaces: 2
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
constructor(configDir){
|
|
120
|
+
_define_property(this, "configDir", void 0);
|
|
121
|
+
_define_property(this, "userConfig", void 0);
|
|
122
|
+
this.configDir = configDir;
|
|
123
|
+
this.userConfig = {};
|
|
124
|
+
}
|
|
125
|
+
}
|