@knocklabs/cli 0.1.0-rc.3 → 0.1.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 +48 -30
- package/dist/commands/ping.js +2 -0
- package/dist/commands/translation/get.js +124 -0
- package/dist/commands/translation/list.js +50 -6
- package/dist/commands/translation/pull.js +59 -17
- package/dist/commands/translation/push.js +13 -6
- package/dist/commands/translation/validate.js +1 -1
- package/dist/commands/whoami.js +28 -0
- package/dist/commands/workflow/pull.js +2 -2
- package/dist/commands/workflow/push.js +52 -42
- package/dist/commands/workflow/validate.js +44 -43
- package/dist/lib/api-v1.js +20 -5
- package/dist/lib/marshal/translation/helpers.js +11 -3
- package/dist/lib/marshal/translation/reader.js +17 -14
- package/dist/lib/marshal/translation/types.js +1 -0
- package/dist/lib/marshal/translation/writer.js +27 -15
- package/dist/lib/marshal/workflow/helpers.js +64 -2
- package/dist/lib/marshal/workflow/reader.js +62 -0
- package/dist/lib/marshal/workflow/writer.js +44 -8
- package/oclif.manifest.json +114 -2
- package/package.json +7 -7
|
@@ -10,10 +10,12 @@ function _export(target, all) {
|
|
|
10
10
|
}
|
|
11
11
|
_export(exports, {
|
|
12
12
|
readWorkflowDir: ()=>readWorkflowDir,
|
|
13
|
+
readAllForCommandTarget: ()=>readAllForCommandTarget,
|
|
13
14
|
checkIfValidExtractedFilePathFormat: ()=>checkIfValidExtractedFilePathFormat,
|
|
14
15
|
readExtractedFileSync: ()=>readExtractedFileSync
|
|
15
16
|
});
|
|
16
17
|
const _nodePath = /*#__PURE__*/ _interopRequireWildcard(require("node:path"));
|
|
18
|
+
const _core = require("@oclif/core");
|
|
17
19
|
const _fsExtra = /*#__PURE__*/ _interopRequireWildcard(require("fs-extra"));
|
|
18
20
|
const _lodash = require("lodash");
|
|
19
21
|
const _error = require("../../helpers/error");
|
|
@@ -247,3 +249,63 @@ const readWorkflowDir = async (workflowDirCtx, opts = {})=>{
|
|
|
247
249
|
[]
|
|
248
250
|
];
|
|
249
251
|
};
|
|
252
|
+
/*
|
|
253
|
+
* For the given list of workflow directory contexts, read each workflow dir and
|
|
254
|
+
* return workflow directory data.
|
|
255
|
+
*/ const readWorkflowDirs = async (workflowDirCtxs, opts = {})=>{
|
|
256
|
+
const workflows = [];
|
|
257
|
+
const errors = [];
|
|
258
|
+
for (const workflowDirCtx of workflowDirCtxs){
|
|
259
|
+
// eslint-disable-next-line no-await-in-loop
|
|
260
|
+
const [workflow, readErrors] = await readWorkflowDir(workflowDirCtx, opts);
|
|
261
|
+
if (readErrors.length > 0) {
|
|
262
|
+
const workflowJsonPath = _nodePath.resolve(workflowDirCtx.abspath, _helpers.WORKFLOW_JSON);
|
|
263
|
+
const e = new _error.SourceError((0, _error.formatErrors)(readErrors), workflowJsonPath);
|
|
264
|
+
errors.push(e);
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
workflows.push({
|
|
268
|
+
...workflowDirCtx,
|
|
269
|
+
content: workflow
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
return [
|
|
273
|
+
workflows,
|
|
274
|
+
errors
|
|
275
|
+
];
|
|
276
|
+
};
|
|
277
|
+
const readAllForCommandTarget = async (target, opts = {})=>{
|
|
278
|
+
const { type: targetType , context: targetCtx } = target;
|
|
279
|
+
if (!targetCtx.exists) {
|
|
280
|
+
const subject = targetType === "workflowDir" ? "a workflow directory at" : "workflow directories in";
|
|
281
|
+
return _core.CliUx.ux.error(`Cannot locate ${subject} \`${targetCtx.abspath}\``);
|
|
282
|
+
}
|
|
283
|
+
switch(targetType){
|
|
284
|
+
case "workflowDir":
|
|
285
|
+
{
|
|
286
|
+
return readWorkflowDirs([
|
|
287
|
+
targetCtx
|
|
288
|
+
], opts);
|
|
289
|
+
}
|
|
290
|
+
case "workflowsIndexDir":
|
|
291
|
+
{
|
|
292
|
+
const dirents = await _fsExtra.readdir(targetCtx.abspath, {
|
|
293
|
+
withFileTypes: true
|
|
294
|
+
});
|
|
295
|
+
const promises = dirents.map(async (dirent)=>{
|
|
296
|
+
const abspath = _nodePath.resolve(targetCtx.abspath, dirent.name);
|
|
297
|
+
const workflowDirCtx = {
|
|
298
|
+
type: "workflow",
|
|
299
|
+
key: dirent.name,
|
|
300
|
+
abspath,
|
|
301
|
+
exists: await (0, _helpers.isWorkflowDir)(abspath)
|
|
302
|
+
};
|
|
303
|
+
return workflowDirCtx;
|
|
304
|
+
});
|
|
305
|
+
const workflowDirCtxs = (await Promise.all(promises)).filter((workflowDirCtx)=>workflowDirCtx.exists);
|
|
306
|
+
return readWorkflowDirs(workflowDirCtxs, opts);
|
|
307
|
+
}
|
|
308
|
+
default:
|
|
309
|
+
throw new Error(`Invalid workflow command target: ${target}`);
|
|
310
|
+
}
|
|
311
|
+
};
|
|
@@ -14,6 +14,7 @@ _export(exports, {
|
|
|
14
14
|
writeWorkflowsIndexDir: ()=>writeWorkflowsIndexDir,
|
|
15
15
|
buildWorkflowDirBundle: ()=>buildWorkflowDirBundle,
|
|
16
16
|
formatExtractedFilePath: ()=>formatExtractedFilePath,
|
|
17
|
+
pruneWorkflowsIndexDir: ()=>pruneWorkflowsIndexDir,
|
|
17
18
|
toWorkflowJson: ()=>toWorkflowJson
|
|
18
19
|
});
|
|
19
20
|
const _nodePath = /*#__PURE__*/ _interopRequireWildcard(require("node:path"));
|
|
@@ -265,10 +266,12 @@ const writeWorkflowDirFromData = async (workflowDirCtx, remoteWorkflow)=>{
|
|
|
265
266
|
return writeWorkflowDirFromBundle(workflowDirCtx, bundle);
|
|
266
267
|
};
|
|
267
268
|
const writeWorkflowDirFromBundle = async (workflowDirCtx, workflowDirBundle)=>{
|
|
269
|
+
const backupDirPath = _nodePath.resolve(_const.sandboxDir, (0, _lodash.uniqueId)("backup"));
|
|
268
270
|
try {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
271
|
+
if (workflowDirCtx.exists) {
|
|
272
|
+
await _fsExtra.copy(workflowDirCtx.abspath, backupDirPath);
|
|
273
|
+
await _fsExtra.emptyDir(workflowDirCtx.abspath);
|
|
274
|
+
}
|
|
272
275
|
const promises = Object.entries(workflowDirBundle).map(([relpath, fileContent])=>{
|
|
273
276
|
const filePath = _nodePath.resolve(workflowDirCtx.abspath, relpath);
|
|
274
277
|
return relpath === _helpers.WORKFLOW_JSON ? _fsExtra.outputJson(filePath, fileContent, {
|
|
@@ -277,10 +280,43 @@ const writeWorkflowDirFromBundle = async (workflowDirCtx, workflowDirBundle)=>{
|
|
|
277
280
|
});
|
|
278
281
|
await Promise.all(promises);
|
|
279
282
|
} catch (error) {
|
|
280
|
-
|
|
283
|
+
// In case of any error, wipe the target directory that is likely in a bad
|
|
284
|
+
// state then restore the backup if one existed before.
|
|
285
|
+
if (workflowDirCtx.exists) {
|
|
286
|
+
await _fsExtra.emptyDir(workflowDirCtx.abspath);
|
|
287
|
+
await _fsExtra.copy(backupDirPath, workflowDirCtx.abspath);
|
|
288
|
+
} else {
|
|
289
|
+
await _fsExtra.remove(workflowDirCtx.abspath);
|
|
290
|
+
}
|
|
281
291
|
throw error;
|
|
292
|
+
} finally{
|
|
293
|
+
// Always clean up the backup directory in the temp sandbox.
|
|
294
|
+
await _fsExtra.remove(backupDirPath);
|
|
282
295
|
}
|
|
283
296
|
};
|
|
297
|
+
/*
|
|
298
|
+
* Prunes the index directory by removing any files, or directories that aren't
|
|
299
|
+
* workflow dirs found in fetched workflows. We want to preserve any workflow
|
|
300
|
+
* dirs that are going to be updated with remote workflows, so extracted links
|
|
301
|
+
* can be respected.
|
|
302
|
+
*/ const pruneWorkflowsIndexDir = async (indexDirCtx, remoteWorkflows)=>{
|
|
303
|
+
const workflowsByKey = Object.fromEntries(remoteWorkflows.map((w)=>[
|
|
304
|
+
w.key.toLowerCase(),
|
|
305
|
+
w
|
|
306
|
+
]));
|
|
307
|
+
const dirents = await _fsExtra.readdir(indexDirCtx.abspath, {
|
|
308
|
+
withFileTypes: true
|
|
309
|
+
});
|
|
310
|
+
const promises = dirents.map(async (dirent)=>{
|
|
311
|
+
const direntName = dirent.name.toLowerCase();
|
|
312
|
+
const direntPath = _nodePath.resolve(indexDirCtx.abspath, direntName);
|
|
313
|
+
if (await (0, _helpers.isWorkflowDir)(direntPath) && workflowsByKey[direntName]) {
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
await _fsExtra.remove(direntPath);
|
|
317
|
+
});
|
|
318
|
+
await Promise.all(promises);
|
|
319
|
+
};
|
|
284
320
|
const writeWorkflowsIndexDir = async (indexDirCtx, remoteWorkflows)=>{
|
|
285
321
|
const backupDirPath = _nodePath.resolve(_const.sandboxDir, (0, _lodash.uniqueId)("backup"));
|
|
286
322
|
try {
|
|
@@ -288,9 +324,7 @@ const writeWorkflowsIndexDir = async (indexDirCtx, remoteWorkflows)=>{
|
|
|
288
324
|
// before wiping it clean.
|
|
289
325
|
if (indexDirCtx.exists) {
|
|
290
326
|
await _fsExtra.copy(indexDirCtx.abspath, backupDirPath);
|
|
291
|
-
|
|
292
|
-
// workflows.
|
|
293
|
-
await _fsExtra.remove(indexDirCtx.abspath);
|
|
327
|
+
await pruneWorkflowsIndexDir(indexDirCtx, remoteWorkflows);
|
|
294
328
|
}
|
|
295
329
|
// Write given remote workflows into the given workflows directory path.
|
|
296
330
|
const writeWorkflowDirPromises = remoteWorkflows.map(async (workflow)=>{
|
|
@@ -307,9 +341,11 @@ const writeWorkflowsIndexDir = async (indexDirCtx, remoteWorkflows)=>{
|
|
|
307
341
|
} catch (error) {
|
|
308
342
|
// In case of any error, wipe the index directory that is likely in a bad
|
|
309
343
|
// state then restore the backup if one existed before.
|
|
310
|
-
await _fsExtra.remove(indexDirCtx.abspath);
|
|
311
344
|
if (indexDirCtx.exists) {
|
|
345
|
+
await _fsExtra.emptyDir(indexDirCtx.abspath);
|
|
312
346
|
await _fsExtra.copy(backupDirPath, indexDirCtx.abspath);
|
|
347
|
+
} else {
|
|
348
|
+
await _fsExtra.remove(indexDirCtx.abspath);
|
|
313
349
|
}
|
|
314
350
|
throw error;
|
|
315
351
|
} finally{
|
package/oclif.manifest.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.1.0
|
|
2
|
+
"version": "0.1.0",
|
|
3
3
|
"commands": {
|
|
4
4
|
"ping": {
|
|
5
5
|
"id": "ping",
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
"pluginName": "@knocklabs/cli",
|
|
9
9
|
"pluginAlias": "@knocklabs/cli",
|
|
10
10
|
"pluginType": "core",
|
|
11
|
+
"hidden": true,
|
|
11
12
|
"aliases": [],
|
|
12
13
|
"examples": [
|
|
13
14
|
"<%= config.bin %> <%= command.id %>"
|
|
@@ -30,6 +31,38 @@
|
|
|
30
31
|
},
|
|
31
32
|
"args": {}
|
|
32
33
|
},
|
|
34
|
+
"whoami": {
|
|
35
|
+
"id": "whoami",
|
|
36
|
+
"strict": true,
|
|
37
|
+
"pluginName": "@knocklabs/cli",
|
|
38
|
+
"pluginAlias": "@knocklabs/cli",
|
|
39
|
+
"pluginType": "core",
|
|
40
|
+
"aliases": [],
|
|
41
|
+
"flags": {
|
|
42
|
+
"service-token": {
|
|
43
|
+
"name": "service-token",
|
|
44
|
+
"type": "option",
|
|
45
|
+
"summary": "The service token to authenticate with",
|
|
46
|
+
"required": true,
|
|
47
|
+
"multiple": false
|
|
48
|
+
},
|
|
49
|
+
"api-origin": {
|
|
50
|
+
"name": "api-origin",
|
|
51
|
+
"type": "option",
|
|
52
|
+
"hidden": true,
|
|
53
|
+
"required": false,
|
|
54
|
+
"multiple": false
|
|
55
|
+
},
|
|
56
|
+
"json": {
|
|
57
|
+
"name": "json",
|
|
58
|
+
"type": "boolean",
|
|
59
|
+
"description": "Format output as json.",
|
|
60
|
+
"helpGroup": "GLOBAL",
|
|
61
|
+
"allowNo": false
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
"args": {}
|
|
65
|
+
},
|
|
33
66
|
"commit": {
|
|
34
67
|
"id": "commit",
|
|
35
68
|
"strict": true,
|
|
@@ -114,6 +147,54 @@
|
|
|
114
147
|
},
|
|
115
148
|
"args": {}
|
|
116
149
|
},
|
|
150
|
+
"translation:get": {
|
|
151
|
+
"id": "translation:get",
|
|
152
|
+
"strict": true,
|
|
153
|
+
"pluginName": "@knocklabs/cli",
|
|
154
|
+
"pluginAlias": "@knocklabs/cli",
|
|
155
|
+
"pluginType": "core",
|
|
156
|
+
"aliases": [],
|
|
157
|
+
"flags": {
|
|
158
|
+
"service-token": {
|
|
159
|
+
"name": "service-token",
|
|
160
|
+
"type": "option",
|
|
161
|
+
"summary": "The service token to authenticate with",
|
|
162
|
+
"required": true,
|
|
163
|
+
"multiple": false
|
|
164
|
+
},
|
|
165
|
+
"api-origin": {
|
|
166
|
+
"name": "api-origin",
|
|
167
|
+
"type": "option",
|
|
168
|
+
"hidden": true,
|
|
169
|
+
"required": false,
|
|
170
|
+
"multiple": false
|
|
171
|
+
},
|
|
172
|
+
"environment": {
|
|
173
|
+
"name": "environment",
|
|
174
|
+
"type": "option",
|
|
175
|
+
"multiple": false,
|
|
176
|
+
"default": "development"
|
|
177
|
+
},
|
|
178
|
+
"hide-uncommitted-changes": {
|
|
179
|
+
"name": "hide-uncommitted-changes",
|
|
180
|
+
"type": "boolean",
|
|
181
|
+
"allowNo": false
|
|
182
|
+
},
|
|
183
|
+
"json": {
|
|
184
|
+
"name": "json",
|
|
185
|
+
"type": "boolean",
|
|
186
|
+
"description": "Format output as json.",
|
|
187
|
+
"helpGroup": "GLOBAL",
|
|
188
|
+
"allowNo": false
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
"args": {
|
|
192
|
+
"translationRef": {
|
|
193
|
+
"name": "translationRef",
|
|
194
|
+
"required": true
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
},
|
|
117
198
|
"translation:list": {
|
|
118
199
|
"id": "translation:list",
|
|
119
200
|
"strict": true,
|
|
@@ -224,7 +305,12 @@
|
|
|
224
305
|
"allowNo": false
|
|
225
306
|
}
|
|
226
307
|
},
|
|
227
|
-
"args": {
|
|
308
|
+
"args": {
|
|
309
|
+
"translationRef": {
|
|
310
|
+
"name": "translationRef",
|
|
311
|
+
"required": false
|
|
312
|
+
}
|
|
313
|
+
}
|
|
228
314
|
},
|
|
229
315
|
"translation:push": {
|
|
230
316
|
"id": "translation:push",
|
|
@@ -640,6 +726,19 @@
|
|
|
640
726
|
],
|
|
641
727
|
"default": "development"
|
|
642
728
|
},
|
|
729
|
+
"all": {
|
|
730
|
+
"name": "all",
|
|
731
|
+
"type": "boolean",
|
|
732
|
+
"allowNo": false
|
|
733
|
+
},
|
|
734
|
+
"workflows-dir": {
|
|
735
|
+
"name": "workflows-dir",
|
|
736
|
+
"type": "option",
|
|
737
|
+
"multiple": false,
|
|
738
|
+
"dependsOn": [
|
|
739
|
+
"all"
|
|
740
|
+
]
|
|
741
|
+
},
|
|
643
742
|
"commit": {
|
|
644
743
|
"name": "commit",
|
|
645
744
|
"type": "boolean",
|
|
@@ -695,6 +794,19 @@
|
|
|
695
794
|
"development"
|
|
696
795
|
],
|
|
697
796
|
"default": "development"
|
|
797
|
+
},
|
|
798
|
+
"all": {
|
|
799
|
+
"name": "all",
|
|
800
|
+
"type": "boolean",
|
|
801
|
+
"allowNo": false
|
|
802
|
+
},
|
|
803
|
+
"workflows-dir": {
|
|
804
|
+
"name": "workflows-dir",
|
|
805
|
+
"type": "option",
|
|
806
|
+
"multiple": false,
|
|
807
|
+
"dependsOn": [
|
|
808
|
+
"all"
|
|
809
|
+
]
|
|
698
810
|
}
|
|
699
811
|
},
|
|
700
812
|
"args": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@knocklabs/cli",
|
|
3
|
-
"version": "0.1.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Knock CLI",
|
|
5
5
|
"author": "@knocklabs",
|
|
6
6
|
"bin": {
|
|
@@ -19,13 +19,13 @@
|
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@oclif/core": "^1.26.2",
|
|
21
21
|
"@oclif/plugin-help": "^5",
|
|
22
|
-
"@oclif/plugin-plugins": "^2.4.
|
|
22
|
+
"@oclif/plugin-plugins": "^2.4.7",
|
|
23
23
|
"@prantlf/jsonlint": "^11.7.2",
|
|
24
|
-
"axios": "^1.
|
|
25
|
-
"date-fns": "^2.
|
|
24
|
+
"axios": "^1.4.0",
|
|
25
|
+
"date-fns": "^2.30.0",
|
|
26
26
|
"enquirer": "^2.3.6",
|
|
27
27
|
"fs-extra": "^10.1.0",
|
|
28
|
-
"liquidjs": "^10.7.
|
|
28
|
+
"liquidjs": "^10.7.1",
|
|
29
29
|
"locale-codes": "^1.3.1",
|
|
30
30
|
"lodash": "^4.17.21",
|
|
31
31
|
"yup": "^0.32.11"
|
|
@@ -43,11 +43,11 @@
|
|
|
43
43
|
"eslint": "^7.32.0",
|
|
44
44
|
"eslint-config-oclif": "^4",
|
|
45
45
|
"eslint-config-oclif-typescript": "^1.0.3",
|
|
46
|
-
"eslint-config-prettier": "^8.
|
|
46
|
+
"eslint-config-prettier": "^8.8.0",
|
|
47
47
|
"eslint-plugin-prettier": "^4.2.1",
|
|
48
48
|
"eslint-plugin-simple-import-sort": "^8.0.0",
|
|
49
49
|
"mocha": "^9",
|
|
50
|
-
"nock": "^13.3.
|
|
50
|
+
"nock": "^13.3.1",
|
|
51
51
|
"oclif": "^3",
|
|
52
52
|
"prettier": "2.8.8",
|
|
53
53
|
"shx": "^0.3.4",
|