@superblocksteam/util 1.14.1 → 2.0.3-next.46
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/.prettierrc +1 -0
- package/dist/api-files/api.d.mts +7 -0
- package/dist/api-files/api.d.mts.map +1 -0
- package/dist/api-files/api.mjs +262 -0
- package/dist/api-files/api.mjs.map +1 -0
- package/dist/api-files/constants.d.ts +6 -0
- package/dist/api-files/constants.d.ts.map +1 -0
- package/dist/api-files/constants.js +9 -0
- package/dist/api-files/constants.js.map +1 -0
- package/dist/api-files/index.d.ts +7 -0
- package/dist/api-files/index.d.ts.map +1 -0
- package/dist/api-files/index.js +13 -0
- package/dist/api-files/index.js.map +1 -0
- package/dist/api-files/types.d.ts +117 -0
- package/dist/api-files/types.d.ts.map +1 -0
- package/dist/api-files/types.js +17 -0
- package/dist/api-files/types.js.map +1 -0
- package/dist/component-configs.d.ts +1 -0
- package/dist/component-configs.d.ts.map +1 -0
- package/dist/component-configs.js +10 -9
- package/dist/component-configs.js.map +1 -0
- package/dist/constants.d.ts +1 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +1 -0
- package/dist/constants.js.map +1 -0
- package/dist/data-types.d.ts +1 -0
- package/dist/data-types.d.ts.map +1 -0
- package/dist/data-types.js +1 -0
- package/dist/data-types.js.map +1 -0
- package/dist/events.d.ts +1 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +1 -0
- package/dist/events.js.map +1 -0
- package/dist/file-uploader.d.ts +1 -0
- package/dist/file-uploader.d.ts.map +1 -0
- package/dist/file-uploader.js +1 -0
- package/dist/file-uploader.js.map +1 -0
- package/dist/generate-component-types.d.ts +2 -1
- package/dist/generate-component-types.d.ts.map +1 -0
- package/dist/generate-component-types.js +5 -5
- package/dist/generate-component-types.js.map +1 -0
- package/dist/identifiers.d.ts +1 -0
- package/dist/identifiers.d.ts.map +1 -0
- package/dist/identifiers.js +2 -1
- package/dist/identifiers.js.map +1 -0
- package/dist/index.d.ts +16 -11
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -11
- package/dist/index.js.map +1 -0
- package/dist/localGitRepoState.d.ts +2 -1
- package/dist/localGitRepoState.d.ts.map +1 -0
- package/dist/localGitRepoState.js +1 -0
- package/dist/localGitRepoState.js.map +1 -0
- package/dist/login.d.ts +1 -0
- package/dist/login.d.ts.map +1 -0
- package/dist/login.js +6 -5
- package/dist/login.js.map +1 -0
- package/dist/mask-unix-signals.d.ts +27 -0
- package/dist/mask-unix-signals.d.ts.map +1 -0
- package/dist/mask-unix-signals.js +81 -0
- package/dist/mask-unix-signals.js.map +1 -0
- package/dist/resource-configs.d.ts +9 -1
- package/dist/resource-configs.d.ts.map +1 -0
- package/dist/resource-configs.js +66 -11
- package/dist/resource-configs.js.map +1 -0
- package/dist/types.d.ts +8 -7
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/dist/unreachable.d.ts +2 -1
- package/dist/unreachable.d.ts.map +1 -0
- package/dist/unreachable.js +3 -2
- package/dist/unreachable.js.map +1 -0
- package/dist/validation.d.ts +1 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +4 -3
- package/dist/validation.js.map +1 -0
- package/eslint.config.js +11 -1
- package/package.json +18 -11
- package/src/api-files/api.mts +504 -0
- package/src/api-files/constants.ts +6 -0
- package/src/api-files/index.ts +15 -0
- package/src/api-files/types.ts +134 -0
- package/src/component-configs.ts +3 -3
- package/src/generate-component-types.ts +2 -2
- package/src/index.ts +15 -11
- package/src/localGitRepoState.ts +1 -1
- package/src/login.ts +1 -1
- package/src/mask-unix-signals.ts +86 -0
- package/src/resource-configs.ts +81 -1
- package/src/types.ts +8 -11
- package/src/unreachable.ts +4 -2
- package/src/validation.ts +4 -3
- package/tsconfig.json +9 -2
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC,UAAU,sBAAsB,CAAC,CAAC,SAAS,QAAQ;IACjD;;;;OAIG;IACH,WAAW,EAAE,CAAC,SAAS,SAAS,GAC5B,MAAM,GAAG,SAAS,GAAG,QAAQ,GAC7B,MAAM,GAAG,SAAS,CAAC;IAEvB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,CAAC;IAEjB;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,CAAC;CAClB;AAED,MAAM,WAAW,eAAe,CAAC,CAAC,SAAS,QAAQ;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,CAAC,CAAC;IAEZ;;;QAGI;IACJ,sBAAsB,CAAC,EAAE,sBAAsB,CAAC,CAAC,CAAC,CAAC;IAEnD;;;QAGI;IACJ,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B;;;QAGI;IACJ,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,MAAM,QAAQ,GAChB,eAAe,CAAC,QAAQ,CAAC,GACzB,eAAe,CAAC,QAAQ,CAAC,GACzB,eAAe,CAAC,SAAS,CAAC,GAC1B,eAAe,CAAC,KAAK,CAAC,CAAC;AAE3B,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,IAAI,CAAC;IAET;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB,UAAU,EAAE,KAAK,CAIb,eAAe,CAAC,QAAQ,CAAC,GACzB,eAAe,CAAC,QAAQ,CAAC,GACzB,eAAe,CAAC,SAAS,CAAC,GAC1B,eAAe,CAAC,KAAK,CAAC,CACzB,CAAC;IAEF;;;;;OAKG;IACH,MAAM,EAAE,KAAK,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;IAEH,cAAc,CAAC,EAAE;QACf,cAAc,EAAE,MAAM,CAAC;QACvB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH"}
|
package/dist/types.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/dist/unreachable.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export declare function unreachable(value: never): never;
|
|
1
|
+
export declare function unreachable(value: never, errMsg?: string): never;
|
|
2
|
+
//# sourceMappingURL=unreachable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unreachable.d.ts","sourceRoot":"","sources":["../src/unreachable.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAIhE"}
|
package/dist/unreachable.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.unreachable = unreachable;
|
|
4
|
-
function unreachable(value) {
|
|
5
|
-
throw new TypeError("Encountered impossible value: " + JSON.stringify(value));
|
|
4
|
+
function unreachable(value, errMsg) {
|
|
5
|
+
throw new TypeError(errMsg ?? "Encountered impossible value: " + JSON.stringify(value));
|
|
6
6
|
}
|
|
7
|
+
//# sourceMappingURL=unreachable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unreachable.js","sourceRoot":"","sources":["../src/unreachable.ts"],"names":[],"mappings":";;AAAA,kCAIC;AAJD,SAAgB,WAAW,CAAC,KAAY,EAAE,MAAe;IACvD,MAAM,IAAI,SAAS,CACjB,MAAM,IAAI,gCAAgC,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CACnE,CAAC;AACJ,CAAC"}
|
package/dist/validation.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AA4IA,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,GAAG,GAAG;IACnD,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAWA"}
|
package/dist/validation.js
CHANGED
|
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.validateCustomComponents = validateCustomComponents;
|
|
7
7
|
const ajv_1 = __importDefault(require("ajv"));
|
|
8
8
|
const better_ajv_errors_1 = __importDefault(require("better-ajv-errors"));
|
|
9
|
-
const
|
|
9
|
+
const identifiers_js_1 = require("./identifiers.js");
|
|
10
10
|
const ajv = new ajv_1.default();
|
|
11
11
|
ajv.addKeyword({
|
|
12
12
|
keyword: "stringFormat",
|
|
@@ -17,7 +17,7 @@ ajv.addKeyword({
|
|
|
17
17
|
validateFunc = (data) => {
|
|
18
18
|
if (typeof data != "string")
|
|
19
19
|
return false;
|
|
20
|
-
if (!(0,
|
|
20
|
+
if (!(0, identifiers_js_1.isValidIdentifier)(data)) {
|
|
21
21
|
validateFunc.errors = [
|
|
22
22
|
{
|
|
23
23
|
keyword: "format",
|
|
@@ -26,7 +26,7 @@ ajv.addKeyword({
|
|
|
26
26
|
];
|
|
27
27
|
return false;
|
|
28
28
|
}
|
|
29
|
-
if ((0,
|
|
29
|
+
if ((0, identifiers_js_1.isReservedPropertyName)(data)) {
|
|
30
30
|
validateFunc.errors = [
|
|
31
31
|
{
|
|
32
32
|
keyword: "format",
|
|
@@ -149,3 +149,4 @@ function validateCustomComponents(data) {
|
|
|
149
149
|
}
|
|
150
150
|
return { valid: true };
|
|
151
151
|
}
|
|
152
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"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"}
|
package/eslint.config.js
CHANGED
|
@@ -21,7 +21,7 @@ const config = [
|
|
|
21
21
|
},
|
|
22
22
|
js.configs.recommended,
|
|
23
23
|
...tseslint.configs.recommended,
|
|
24
|
-
eslintPluginPrettierRecommended,
|
|
24
|
+
{ files: ["./*", "src/**"], ...eslintPluginPrettierRecommended },
|
|
25
25
|
{
|
|
26
26
|
plugins: {
|
|
27
27
|
"@typescript-eslint": tseslint.plugin,
|
|
@@ -39,6 +39,8 @@ const config = [
|
|
|
39
39
|
"@typescript-eslint/no-explicit-any": "off",
|
|
40
40
|
"@typescript-eslint/no-unused-vars": "error",
|
|
41
41
|
"@typescript-eslint/no-var-requires": "off",
|
|
42
|
+
"@typescript-eslint/no-import-type-side-effects": "error",
|
|
43
|
+
"@typescript-eslint/consistent-type-imports": "error",
|
|
42
44
|
"unicorn/no-nested-ternary": "off",
|
|
43
45
|
"import/order": [
|
|
44
46
|
"error",
|
|
@@ -57,6 +59,14 @@ const config = [
|
|
|
57
59
|
},
|
|
58
60
|
],
|
|
59
61
|
"import/no-cycle": "error",
|
|
62
|
+
"import/extensions": [
|
|
63
|
+
"error",
|
|
64
|
+
"ignorePackages",
|
|
65
|
+
{
|
|
66
|
+
ts: "never",
|
|
67
|
+
tsx: "never",
|
|
68
|
+
},
|
|
69
|
+
],
|
|
60
70
|
"no-template-curly-in-string": "off",
|
|
61
71
|
"no-useless-escape": "off",
|
|
62
72
|
"no-void": ["error", { allowAsStatement: true }],
|
package/package.json
CHANGED
|
@@ -1,39 +1,46 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@superblocksteam/util",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
3
|
+
"description": "",
|
|
4
|
+
"version": "2.0.3-next.46",
|
|
5
5
|
"homepage": "https://www.superblocks.com",
|
|
6
6
|
"license": "Superblocks Community Software License",
|
|
7
|
-
"
|
|
7
|
+
"main": "dist/index.js",
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"ajv": "^8.12.0",
|
|
10
|
-
"better-ajv-errors": "
|
|
10
|
+
"better-ajv-errors": "1.2.0",
|
|
11
11
|
"fs-extra": "^11.1.1",
|
|
12
12
|
"lodash": "^4.17.21",
|
|
13
|
-
"
|
|
13
|
+
"lodash-es": "^4.17.21",
|
|
14
|
+
"mime-types": "^2.1.35",
|
|
15
|
+
"slugify": "^1.6.6",
|
|
16
|
+
"typescript": "^5.1.3",
|
|
17
|
+
"yaml": "^2.4.2"
|
|
14
18
|
},
|
|
15
19
|
"devDependencies": {
|
|
20
|
+
"@eslint/js": "^9.16.0",
|
|
16
21
|
"@types/fs-extra": "^11.0.1",
|
|
17
22
|
"@types/lodash": "^4.17.7",
|
|
23
|
+
"@types/lodash-es": "^4.17.12",
|
|
18
24
|
"@types/mime-types": "^2.1.1",
|
|
19
25
|
"@types/node": "^20.11.18",
|
|
20
26
|
"@typescript-eslint/eslint-plugin": "^8.25.0",
|
|
21
27
|
"@typescript-eslint/parser": "^8.25.0",
|
|
22
28
|
"eslint": "^9.21.0",
|
|
29
|
+
"eslint-plugin-import": "2.31.0",
|
|
30
|
+
"eslint-plugin-mocha": "^10.5.0",
|
|
23
31
|
"eslint-plugin-prettier": "^5.2.5",
|
|
24
32
|
"eslint-plugin-unicorn": "^47.0.0",
|
|
25
33
|
"prettier": "^3.5.2",
|
|
26
34
|
"tslib": "^2.5.0",
|
|
27
|
-
"typescript": "^
|
|
35
|
+
"typescript-eslint": "^8.18.0"
|
|
28
36
|
},
|
|
29
37
|
"scripts": {
|
|
30
|
-
"dev": "tsc --watch",
|
|
31
38
|
"build": "tsc --build",
|
|
32
|
-
"
|
|
33
|
-
"clean
|
|
39
|
+
"check": "pnpm run lint && pnpm run typecheck",
|
|
40
|
+
"clean": "rm -rf dist tsconfig.tsbuildinfo",
|
|
41
|
+
"dev": "tsc --build --watch",
|
|
34
42
|
"lint": "eslint .",
|
|
35
43
|
"lint:fix": "eslint . --fix",
|
|
36
|
-
"typecheck": "tsc --noEmit"
|
|
37
|
-
"check": "pnpm run lint && pnpm run typecheck"
|
|
44
|
+
"typecheck": "tsc --noEmit"
|
|
38
45
|
}
|
|
39
46
|
}
|
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
import fs from "fs-extra";
|
|
2
|
+
import { cloneDeep } from "lodash-es";
|
|
3
|
+
import slugify from "slugify";
|
|
4
|
+
import { parse, stringify as ymlstringify } from "yaml";
|
|
5
|
+
import {
|
|
6
|
+
DEFAULT_LINES_FOR_LARGE_STEPS,
|
|
7
|
+
LANGUAGE_STEP_EXTENSIONS,
|
|
8
|
+
} from "./constants.js";
|
|
9
|
+
import type {
|
|
10
|
+
AdditionalStepFiles,
|
|
11
|
+
Api,
|
|
12
|
+
ApiRepresentation,
|
|
13
|
+
ApiWrapper,
|
|
14
|
+
Block,
|
|
15
|
+
LanguageContent,
|
|
16
|
+
Step,
|
|
17
|
+
} from "./types.js";
|
|
18
|
+
|
|
19
|
+
function slugifyName(originalName: any): string {
|
|
20
|
+
return (slugify as any)(originalName, {
|
|
21
|
+
replacement: "_",
|
|
22
|
+
lower: true,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function findUnusedFilePath(
|
|
27
|
+
filename: string,
|
|
28
|
+
extension: string,
|
|
29
|
+
existingFilePaths: Set<string>,
|
|
30
|
+
): string {
|
|
31
|
+
let proposedFilename = `${filename}.${extension}`;
|
|
32
|
+
let i = 1;
|
|
33
|
+
while (existingFilePaths.has(proposedFilename)) {
|
|
34
|
+
proposedFilename = `${filename}_${i}.${extension}`;
|
|
35
|
+
i++;
|
|
36
|
+
}
|
|
37
|
+
existingFilePaths.add(proposedFilename);
|
|
38
|
+
return proposedFilename;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function extractAdditionalStepFiles(
|
|
42
|
+
api: Api,
|
|
43
|
+
additionalStepFiles: AdditionalStepFiles[],
|
|
44
|
+
stepPathMap: Record<string, string>,
|
|
45
|
+
currentStepNames: string[],
|
|
46
|
+
apiRepresentation?: ApiRepresentation,
|
|
47
|
+
): Api {
|
|
48
|
+
if (!api.blocks || !apiRepresentation?.extractLargeSourceFiles) {
|
|
49
|
+
return api;
|
|
50
|
+
}
|
|
51
|
+
// TODO: lodash
|
|
52
|
+
const apiClone = cloneDeep(api);
|
|
53
|
+
const minLinesForExtraction =
|
|
54
|
+
apiRepresentation?.minLinesForExtraction ?? DEFAULT_LINES_FOR_LARGE_STEPS;
|
|
55
|
+
const existingFilePaths = new Set<string>();
|
|
56
|
+
extractAdditionalStepFilesFromBlocks(
|
|
57
|
+
apiClone.blocks ?? [],
|
|
58
|
+
additionalStepFiles,
|
|
59
|
+
existingFilePaths,
|
|
60
|
+
minLinesForExtraction,
|
|
61
|
+
stepPathMap,
|
|
62
|
+
currentStepNames,
|
|
63
|
+
);
|
|
64
|
+
return apiClone;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function extractAdditionalStepFilesFromStep(
|
|
68
|
+
step: Step,
|
|
69
|
+
name: string,
|
|
70
|
+
additionalStepFiles: AdditionalStepFiles[],
|
|
71
|
+
existingFilePaths: Set<string>,
|
|
72
|
+
minLinesForExtraction: number,
|
|
73
|
+
stepPathMap: Record<string, string>,
|
|
74
|
+
currentStepNames: string[],
|
|
75
|
+
) {
|
|
76
|
+
// Handle language step files
|
|
77
|
+
if (step && "integration" in step) {
|
|
78
|
+
const integration = step.integration as keyof Step;
|
|
79
|
+
const extension =
|
|
80
|
+
LANGUAGE_STEP_EXTENSIONS[
|
|
81
|
+
integration as keyof typeof LANGUAGE_STEP_EXTENSIONS
|
|
82
|
+
];
|
|
83
|
+
if (extension) {
|
|
84
|
+
const languageContent = step[integration] as LanguageContent;
|
|
85
|
+
if (languageContent) {
|
|
86
|
+
const blockBody = languageContent.body;
|
|
87
|
+
if (blockBody && typeof blockBody === "string") {
|
|
88
|
+
const lines = blockBody?.split("\n");
|
|
89
|
+
const linesNum = lines?.length;
|
|
90
|
+
if (linesNum && linesNum > minLinesForExtraction) {
|
|
91
|
+
// Record the separate file is needed, with the language contents
|
|
92
|
+
let relativePath;
|
|
93
|
+
if (stepPathMap?.[name]) {
|
|
94
|
+
relativePath = stepPathMap[name].startsWith("./")
|
|
95
|
+
? stepPathMap[name].split("./")?.[1]
|
|
96
|
+
: stepPathMap[name];
|
|
97
|
+
} else {
|
|
98
|
+
relativePath = findUnusedFilePath(
|
|
99
|
+
slugifyName(name),
|
|
100
|
+
extension,
|
|
101
|
+
existingFilePaths,
|
|
102
|
+
);
|
|
103
|
+
stepPathMap[name] = `./${relativePath}`;
|
|
104
|
+
}
|
|
105
|
+
additionalStepFiles.push({
|
|
106
|
+
relativePath: relativePath,
|
|
107
|
+
contents: blockBody,
|
|
108
|
+
language: integration,
|
|
109
|
+
});
|
|
110
|
+
currentStepNames.push(name);
|
|
111
|
+
// Replace the body with a reference to the separate file
|
|
112
|
+
languageContent.body = {
|
|
113
|
+
path: `./${relativePath}`,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function extractAdditionalStepFilesFromBlocks(
|
|
123
|
+
blocks: Block[],
|
|
124
|
+
additionalStepFiles: AdditionalStepFiles[],
|
|
125
|
+
existingFilePaths: Set<string>,
|
|
126
|
+
minLinesForExtraction: number,
|
|
127
|
+
stepPathMap: Record<string, string>,
|
|
128
|
+
currentStepNames: string[],
|
|
129
|
+
) {
|
|
130
|
+
for (const block of blocks) {
|
|
131
|
+
// Handle language step files
|
|
132
|
+
if (block.step) {
|
|
133
|
+
extractAdditionalStepFilesFromStep(
|
|
134
|
+
block.step,
|
|
135
|
+
block.name,
|
|
136
|
+
additionalStepFiles,
|
|
137
|
+
existingFilePaths,
|
|
138
|
+
minLinesForExtraction,
|
|
139
|
+
stepPathMap,
|
|
140
|
+
currentStepNames,
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Handle loops
|
|
145
|
+
extractAdditionalStepFilesFromBlocks(
|
|
146
|
+
block.loop?.blocks ?? [],
|
|
147
|
+
additionalStepFiles,
|
|
148
|
+
existingFilePaths,
|
|
149
|
+
minLinesForExtraction,
|
|
150
|
+
stepPathMap,
|
|
151
|
+
currentStepNames,
|
|
152
|
+
);
|
|
153
|
+
// Handle try/catch
|
|
154
|
+
if (block.tryCatch) {
|
|
155
|
+
extractAdditionalStepFilesFromBlocks(
|
|
156
|
+
block.tryCatch.try?.blocks ?? [],
|
|
157
|
+
additionalStepFiles,
|
|
158
|
+
existingFilePaths,
|
|
159
|
+
minLinesForExtraction,
|
|
160
|
+
stepPathMap,
|
|
161
|
+
currentStepNames,
|
|
162
|
+
);
|
|
163
|
+
extractAdditionalStepFilesFromBlocks(
|
|
164
|
+
block.tryCatch.catch?.blocks ?? [],
|
|
165
|
+
additionalStepFiles,
|
|
166
|
+
existingFilePaths,
|
|
167
|
+
minLinesForExtraction,
|
|
168
|
+
stepPathMap,
|
|
169
|
+
currentStepNames,
|
|
170
|
+
);
|
|
171
|
+
extractAdditionalStepFilesFromBlocks(
|
|
172
|
+
block.tryCatch.finally?.blocks ?? [],
|
|
173
|
+
additionalStepFiles,
|
|
174
|
+
existingFilePaths,
|
|
175
|
+
minLinesForExtraction,
|
|
176
|
+
stepPathMap,
|
|
177
|
+
currentStepNames,
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
// Handle conditional
|
|
181
|
+
if (block.conditional) {
|
|
182
|
+
extractAdditionalStepFilesFromBlocks(
|
|
183
|
+
block.conditional.if?.blocks ?? [],
|
|
184
|
+
additionalStepFiles,
|
|
185
|
+
existingFilePaths,
|
|
186
|
+
minLinesForExtraction,
|
|
187
|
+
stepPathMap,
|
|
188
|
+
currentStepNames,
|
|
189
|
+
);
|
|
190
|
+
for (const elseIfBlock of block.conditional.elseIf ?? []) {
|
|
191
|
+
extractAdditionalStepFilesFromBlocks(
|
|
192
|
+
elseIfBlock.blocks,
|
|
193
|
+
additionalStepFiles,
|
|
194
|
+
existingFilePaths,
|
|
195
|
+
minLinesForExtraction,
|
|
196
|
+
stepPathMap,
|
|
197
|
+
currentStepNames,
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
extractAdditionalStepFilesFromBlocks(
|
|
201
|
+
block.conditional.else?.blocks ?? [],
|
|
202
|
+
additionalStepFiles,
|
|
203
|
+
existingFilePaths,
|
|
204
|
+
minLinesForExtraction,
|
|
205
|
+
stepPathMap,
|
|
206
|
+
currentStepNames,
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
// Handle Parallel API
|
|
210
|
+
if (block.parallel) {
|
|
211
|
+
for (const path of Object.values(block.parallel?.static?.paths ?? {})) {
|
|
212
|
+
extractAdditionalStepFilesFromBlocks(
|
|
213
|
+
path.blocks,
|
|
214
|
+
additionalStepFiles,
|
|
215
|
+
existingFilePaths,
|
|
216
|
+
minLinesForExtraction,
|
|
217
|
+
stepPathMap,
|
|
218
|
+
currentStepNames,
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
extractAdditionalStepFilesFromBlocks(
|
|
222
|
+
block.parallel?.dynamic?.blocks ?? [],
|
|
223
|
+
additionalStepFiles,
|
|
224
|
+
existingFilePaths,
|
|
225
|
+
minLinesForExtraction,
|
|
226
|
+
stepPathMap,
|
|
227
|
+
currentStepNames,
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
// Handle stream
|
|
231
|
+
if (block.stream) {
|
|
232
|
+
const trigger = block.stream.trigger;
|
|
233
|
+
if (trigger && trigger.step) {
|
|
234
|
+
extractAdditionalStepFilesFromStep(
|
|
235
|
+
trigger.step,
|
|
236
|
+
trigger.name,
|
|
237
|
+
additionalStepFiles,
|
|
238
|
+
existingFilePaths,
|
|
239
|
+
minLinesForExtraction,
|
|
240
|
+
stepPathMap,
|
|
241
|
+
currentStepNames,
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
extractAdditionalStepFilesFromBlocks(
|
|
245
|
+
block.stream.process?.blocks ?? [],
|
|
246
|
+
additionalStepFiles,
|
|
247
|
+
existingFilePaths,
|
|
248
|
+
minLinesForExtraction,
|
|
249
|
+
stepPathMap,
|
|
250
|
+
currentStepNames,
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
async function readYamlFile(path: string): Promise<any> {
|
|
257
|
+
return parse(await fs.readFile(path, "utf8"));
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
async function resolveLanguageSpecificStepContentFromBlocks(
|
|
261
|
+
parentPath: string,
|
|
262
|
+
blocks: Block[],
|
|
263
|
+
stepPathMap: Record<string, string>,
|
|
264
|
+
) {
|
|
265
|
+
for (const block of blocks) {
|
|
266
|
+
// Handle language-specific step content
|
|
267
|
+
if (block.step) {
|
|
268
|
+
const step = block.step;
|
|
269
|
+
await resolveLanguageSpecificStepContentFromStep(
|
|
270
|
+
parentPath,
|
|
271
|
+
step,
|
|
272
|
+
block.name,
|
|
273
|
+
stepPathMap,
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
// Handle conditional blocks
|
|
277
|
+
if (block.conditional) {
|
|
278
|
+
await resolveLanguageSpecificStepContentFromBlocks(
|
|
279
|
+
parentPath,
|
|
280
|
+
block.conditional.if?.blocks ?? [],
|
|
281
|
+
stepPathMap,
|
|
282
|
+
);
|
|
283
|
+
for (const elseIfBlock of block.conditional.elseIf) {
|
|
284
|
+
await resolveLanguageSpecificStepContentFromBlocks(
|
|
285
|
+
parentPath,
|
|
286
|
+
elseIfBlock.blocks,
|
|
287
|
+
stepPathMap,
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
await resolveLanguageSpecificStepContentFromBlocks(
|
|
291
|
+
parentPath,
|
|
292
|
+
block.conditional.else?.blocks ?? [],
|
|
293
|
+
stepPathMap,
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
// Handle loop blocks
|
|
297
|
+
await resolveLanguageSpecificStepContentFromBlocks(
|
|
298
|
+
parentPath,
|
|
299
|
+
block.loop?.blocks ?? [],
|
|
300
|
+
stepPathMap,
|
|
301
|
+
);
|
|
302
|
+
// Handle try-catch blocks
|
|
303
|
+
if (block.tryCatch) {
|
|
304
|
+
await resolveLanguageSpecificStepContentFromBlocks(
|
|
305
|
+
parentPath,
|
|
306
|
+
block.tryCatch.try?.blocks ?? [],
|
|
307
|
+
stepPathMap,
|
|
308
|
+
);
|
|
309
|
+
await resolveLanguageSpecificStepContentFromBlocks(
|
|
310
|
+
parentPath,
|
|
311
|
+
block.tryCatch.catch?.blocks ?? [],
|
|
312
|
+
stepPathMap,
|
|
313
|
+
);
|
|
314
|
+
await resolveLanguageSpecificStepContentFromBlocks(
|
|
315
|
+
parentPath,
|
|
316
|
+
block.tryCatch.finally?.blocks ?? [],
|
|
317
|
+
stepPathMap,
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
// Handle parallel blocks
|
|
321
|
+
if (block.parallel) {
|
|
322
|
+
for (const path of Object.values(block.parallel?.static?.paths ?? {})) {
|
|
323
|
+
await resolveLanguageSpecificStepContentFromBlocks(
|
|
324
|
+
parentPath,
|
|
325
|
+
path.blocks,
|
|
326
|
+
stepPathMap,
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
await resolveLanguageSpecificStepContentFromBlocks(
|
|
330
|
+
parentPath,
|
|
331
|
+
block.parallel?.dynamic?.blocks ?? [],
|
|
332
|
+
stepPathMap,
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
// Handle stream blocks
|
|
336
|
+
if (block.stream) {
|
|
337
|
+
await resolveLanguageSpecificStepContentFromBlocks(
|
|
338
|
+
parentPath,
|
|
339
|
+
block.stream.process?.blocks ?? [],
|
|
340
|
+
stepPathMap,
|
|
341
|
+
);
|
|
342
|
+
await resolveLanguageSpecificStepContentFromStep(
|
|
343
|
+
parentPath,
|
|
344
|
+
block.stream.trigger?.step ?? ({} as Step),
|
|
345
|
+
block.stream.trigger?.name,
|
|
346
|
+
stepPathMap,
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
async function resolveLanguageSpecificStepContentFromStep(
|
|
353
|
+
parentPath: string,
|
|
354
|
+
step: Step,
|
|
355
|
+
stepName?: string,
|
|
356
|
+
stepPathMap?: Record<string, string>,
|
|
357
|
+
) {
|
|
358
|
+
// Handle language-specific step content
|
|
359
|
+
if (
|
|
360
|
+
!step?.integration ||
|
|
361
|
+
!LANGUAGE_STEP_EXTENSIONS[
|
|
362
|
+
step.integration as keyof typeof LANGUAGE_STEP_EXTENSIONS
|
|
363
|
+
]
|
|
364
|
+
) {
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
const languageContent = step[
|
|
368
|
+
step.integration as keyof Step
|
|
369
|
+
] as LanguageContent;
|
|
370
|
+
if (
|
|
371
|
+
languageContent.body &&
|
|
372
|
+
typeof languageContent.body === "object" &&
|
|
373
|
+
"path" in languageContent.body
|
|
374
|
+
) {
|
|
375
|
+
const languageFilePath = `${parentPath}/${languageContent.body.path}`;
|
|
376
|
+
if (await fs.pathExists(languageFilePath)) {
|
|
377
|
+
// Read the file content
|
|
378
|
+
const stepBodyContent = await fs.readFile(languageFilePath, "utf8");
|
|
379
|
+
if (stepBodyContent && languageContent) {
|
|
380
|
+
if (stepPathMap && stepName) {
|
|
381
|
+
stepPathMap[stepName] = languageContent.body.path;
|
|
382
|
+
}
|
|
383
|
+
languageContent.body = stepBodyContent;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
export async function writeApiFiles(
|
|
390
|
+
api: ApiWrapper,
|
|
391
|
+
apiNameSlug: string,
|
|
392
|
+
directoryPath: string,
|
|
393
|
+
nestedApiFiles: boolean,
|
|
394
|
+
apiPromises: Array<Promise<void>>,
|
|
395
|
+
additionalStepFiles: AdditionalStepFiles[],
|
|
396
|
+
apiRepresentation?: ApiRepresentation,
|
|
397
|
+
existingFilePaths?: Set<string>,
|
|
398
|
+
stepPathMap?: Record<string, string>,
|
|
399
|
+
) {
|
|
400
|
+
let pathForApiFile = directoryPath;
|
|
401
|
+
let yamlFileName = `${apiNameSlug}.yaml`;
|
|
402
|
+
|
|
403
|
+
const currentStepNames: string[] = [];
|
|
404
|
+
// Determine whether to extract into separate files the source code from the steps
|
|
405
|
+
const updatedApi = extractAdditionalStepFiles(
|
|
406
|
+
api.apiPb,
|
|
407
|
+
additionalStepFiles,
|
|
408
|
+
stepPathMap ?? {},
|
|
409
|
+
currentStepNames,
|
|
410
|
+
apiRepresentation,
|
|
411
|
+
);
|
|
412
|
+
|
|
413
|
+
// Stop tracking unused step paths from removed steps (e.g. when a step is renamed or removed)
|
|
414
|
+
if (stepPathMap) {
|
|
415
|
+
Object.keys(stepPathMap).forEach((stepName) => {
|
|
416
|
+
if (!currentStepNames.includes(stepName)) {
|
|
417
|
+
const stepFileName = stepPathMap[stepName].startsWith("./")
|
|
418
|
+
? stepPathMap[stepName].split("./")[1]
|
|
419
|
+
: stepPathMap[stepName];
|
|
420
|
+
fs.remove(`${pathForApiFile}/${stepFileName}`);
|
|
421
|
+
delete stepPathMap[stepName];
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
if (apiRepresentation?.extractLargeSourceFiles) {
|
|
427
|
+
if (nestedApiFiles) {
|
|
428
|
+
// This API has at least one large step code file, so we need a nested directory
|
|
429
|
+
pathForApiFile = `${pathForApiFile}/${apiNameSlug}`;
|
|
430
|
+
yamlFileName = "api.yaml";
|
|
431
|
+
}
|
|
432
|
+
// Make sure the directory exists
|
|
433
|
+
await fs.ensureDir(pathForApiFile);
|
|
434
|
+
// Write any additional step source code files to the disk
|
|
435
|
+
for (const stepFile of additionalStepFiles) {
|
|
436
|
+
const sourceFilePath = `${pathForApiFile}/${stepFile.relativePath}`;
|
|
437
|
+
const handleApi = async () => {
|
|
438
|
+
await fs.outputFile(sourceFilePath, stepFile.contents);
|
|
439
|
+
};
|
|
440
|
+
apiPromises.push(handleApi());
|
|
441
|
+
// Mark the existing source file as being reused
|
|
442
|
+
existingFilePaths?.delete(sourceFilePath);
|
|
443
|
+
}
|
|
444
|
+
} else {
|
|
445
|
+
// No additional step files to write, so mark the API directory as existing so that it will be removed later.
|
|
446
|
+
// Do this even if the current representation does not extract large source files, in case they were previously
|
|
447
|
+
existingFilePaths?.add(`${directoryPath}/${apiNameSlug}`);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
// Convert the updated API to YAML and write it to disk
|
|
451
|
+
const apiContent = ymlstringify(updatedApi, {
|
|
452
|
+
sortMapEntries: true,
|
|
453
|
+
blockQuote: "literal",
|
|
454
|
+
});
|
|
455
|
+
const yamlFilePath = `${pathForApiFile}/${yamlFileName}`;
|
|
456
|
+
const handleApi = async () => {
|
|
457
|
+
await fs.outputFile(yamlFilePath, apiContent);
|
|
458
|
+
};
|
|
459
|
+
apiPromises.push(handleApi());
|
|
460
|
+
// Mark the existing source file as being reused
|
|
461
|
+
existingFilePaths?.delete(yamlFilePath);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
export async function readAppApiYamlFile(
|
|
465
|
+
parentDirectory: string,
|
|
466
|
+
apiName?: string,
|
|
467
|
+
): Promise<{ api: Api; stepPathMap: Record<string, string> }> {
|
|
468
|
+
// The API is either stored in its entirety in a single YAML file, or
|
|
469
|
+
// or in a subdirectory containing the YAML file and zero or more language-specific files.
|
|
470
|
+
const apiNameSlug = slugifyName(apiName ?? "api");
|
|
471
|
+
const singularApiYamlPath = `${parentDirectory}/${apiNameSlug}.yaml`;
|
|
472
|
+
const apiDirPath = `${parentDirectory}/${apiNameSlug}`;
|
|
473
|
+
const nestedApiYamlPath = `${apiDirPath}/api.yaml`;
|
|
474
|
+
|
|
475
|
+
// Read the YAML file
|
|
476
|
+
let yamlPath: string;
|
|
477
|
+
let yamlParentPath: string;
|
|
478
|
+
if (await fs.pathExists(singularApiYamlPath)) {
|
|
479
|
+
// The API YAML file is in the parent directory
|
|
480
|
+
yamlPath = singularApiYamlPath;
|
|
481
|
+
yamlParentPath = parentDirectory;
|
|
482
|
+
} else if (await fs.pathExists(nestedApiYamlPath)) {
|
|
483
|
+
// The API YAML file is nested in an API-specific directory
|
|
484
|
+
yamlPath = nestedApiYamlPath;
|
|
485
|
+
yamlParentPath = apiDirPath;
|
|
486
|
+
} else {
|
|
487
|
+
throw new Error(`API ${apiName ?? ""} not found at ${parentDirectory}`);
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
// That is nested in an API-specific directory
|
|
491
|
+
const apiDefn = (await readYamlFile(yamlPath)) as Api;
|
|
492
|
+
|
|
493
|
+
// Map step name -> step path
|
|
494
|
+
const stepPathMap: Record<string, string> = {};
|
|
495
|
+
|
|
496
|
+
// The API YAML file may or may not have language-specific content in separate files.
|
|
497
|
+
// Replace any file references with the actual content
|
|
498
|
+
await resolveLanguageSpecificStepContentFromBlocks(
|
|
499
|
+
yamlParentPath,
|
|
500
|
+
apiDefn.blocks ?? [],
|
|
501
|
+
stepPathMap,
|
|
502
|
+
);
|
|
503
|
+
return { api: apiDefn, stepPathMap };
|
|
504
|
+
}
|