@flowgram.ai/cli 0.1.8 → 0.4.11
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/dist/index.cjs +397 -91
- package/dist/index.js +398 -88
- package/package.json +3 -2
- package/src/index.ts +21 -4
- package/src/materials/index.ts +23 -9
- package/src/materials/materials.ts +32 -39
- package/src/materials/refresh-project-import.ts +68 -0
- package/src/update-version/index.ts +52 -0
- package/src/utils/export.ts +117 -0
- package/src/utils/file.ts +87 -0
- package/src/utils/import.ts +3 -3
- package/src/utils/project.ts +10 -0
- package/src/utils/ts-file.ts +128 -0
- package/src/utils/traverse-file.ts +0 -60
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import path from "path";
|
|
7
|
+
import fs from "fs";
|
|
8
|
+
import { File, traverseRecursiveFilePaths } from "./file";
|
|
9
|
+
import { extractNamedExports } from "./export";
|
|
10
|
+
import {
|
|
11
|
+
assembleImport,
|
|
12
|
+
ImportDeclaration,
|
|
13
|
+
traverseFileImports,
|
|
14
|
+
} from "./import";
|
|
15
|
+
|
|
16
|
+
class TsFile extends File {
|
|
17
|
+
exports: {
|
|
18
|
+
values: string[];
|
|
19
|
+
types: string[];
|
|
20
|
+
} = {
|
|
21
|
+
values: [],
|
|
22
|
+
types: [],
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
imports: ImportDeclaration[] = [];
|
|
26
|
+
|
|
27
|
+
get allExportNames() {
|
|
28
|
+
return [...this.exports.values, ...this.exports.types];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
constructor(filePath: string) {
|
|
32
|
+
super(filePath);
|
|
33
|
+
|
|
34
|
+
this.exports = extractNamedExports(fs.readFileSync(filePath, "utf-8"));
|
|
35
|
+
this.imports = Array.from(
|
|
36
|
+
traverseFileImports(fs.readFileSync(filePath, "utf-8")),
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
addImport(importDeclarations: ImportDeclaration[]) {
|
|
41
|
+
importDeclarations.forEach((importDeclaration) => {
|
|
42
|
+
importDeclaration.statement = assembleImport(importDeclaration);
|
|
43
|
+
});
|
|
44
|
+
// add in last import statement
|
|
45
|
+
this.replace((content) => {
|
|
46
|
+
const lastImportStatement = this.imports[this.imports.length - 1];
|
|
47
|
+
return content.replace(
|
|
48
|
+
lastImportStatement.statement,
|
|
49
|
+
`${lastImportStatement?.statement}\n${importDeclarations.map(
|
|
50
|
+
(item) => item.statement,
|
|
51
|
+
)}\n`,
|
|
52
|
+
);
|
|
53
|
+
});
|
|
54
|
+
this.imports.push(...importDeclarations);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
removeImport(importDeclarations: ImportDeclaration[]) {
|
|
58
|
+
this.replace((content) =>
|
|
59
|
+
importDeclarations.reduce(
|
|
60
|
+
(prev, cur) => prev.replace(cur.statement, ""),
|
|
61
|
+
content,
|
|
62
|
+
),
|
|
63
|
+
);
|
|
64
|
+
this.imports = this.imports.filter(
|
|
65
|
+
(item) => !importDeclarations.includes(item),
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
replaceImport(
|
|
70
|
+
oldImports: ImportDeclaration[],
|
|
71
|
+
newImports: ImportDeclaration[],
|
|
72
|
+
) {
|
|
73
|
+
newImports.forEach((importDeclaration) => {
|
|
74
|
+
importDeclaration.statement = assembleImport(importDeclaration);
|
|
75
|
+
});
|
|
76
|
+
this.replace((content) => {
|
|
77
|
+
oldImports.forEach((oldImport, idx) => {
|
|
78
|
+
const replaceTo = newImports[idx];
|
|
79
|
+
if (replaceTo) {
|
|
80
|
+
content = content.replace(oldImport.statement, replaceTo.statement);
|
|
81
|
+
this.imports.map((_import) => {
|
|
82
|
+
if (_import.statement === oldImport.statement) {
|
|
83
|
+
_import = replaceTo;
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
} else {
|
|
87
|
+
content = content.replace(oldImport.statement, "");
|
|
88
|
+
this.imports = this.imports.filter(
|
|
89
|
+
(_import) => _import.statement !== oldImport.statement,
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const restNewImports = newImports.slice(oldImports.length);
|
|
95
|
+
if (restNewImports.length > 0) {
|
|
96
|
+
const lastImportStatement = newImports[oldImports.length - 1].statement;
|
|
97
|
+
content = content.replace(
|
|
98
|
+
lastImportStatement,
|
|
99
|
+
`${lastImportStatement}\n${restNewImports.map(
|
|
100
|
+
(item) => item.statement,
|
|
101
|
+
)}\n`,
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
this.imports.push(...restNewImports);
|
|
105
|
+
|
|
106
|
+
return content;
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function* traverseRecursiveTsFiles(folder: string): Generator<TsFile> {
|
|
112
|
+
for (const filePath of traverseRecursiveFilePaths(folder)) {
|
|
113
|
+
if (filePath.endsWith(".ts") || filePath.endsWith(".tsx")) {
|
|
114
|
+
yield new TsFile(filePath);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export function getIndexTsFile(folder: string): TsFile | undefined {
|
|
120
|
+
// ts or tsx
|
|
121
|
+
const files = fs.readdirSync(folder);
|
|
122
|
+
for (const file of files) {
|
|
123
|
+
if (file === "index.ts" || file === "index.tsx") {
|
|
124
|
+
return new TsFile(path.join(folder, file));
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return undefined;
|
|
128
|
+
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
-
* SPDX-License-Identifier: MIT
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import path from 'path';
|
|
7
|
-
import fs from 'fs';
|
|
8
|
-
|
|
9
|
-
class File {
|
|
10
|
-
content: string;
|
|
11
|
-
|
|
12
|
-
isUtf8: boolean;
|
|
13
|
-
|
|
14
|
-
relativePath: string;
|
|
15
|
-
|
|
16
|
-
path: string;
|
|
17
|
-
|
|
18
|
-
suffix: string;
|
|
19
|
-
|
|
20
|
-
constructor(filePath: string, public root: string = '/') {
|
|
21
|
-
this.path = filePath;
|
|
22
|
-
this.relativePath = path.relative(this.root, this.path);
|
|
23
|
-
this.suffix = path.extname(this.path);
|
|
24
|
-
|
|
25
|
-
// Check if exists
|
|
26
|
-
if (!fs.existsSync(this.path)) {
|
|
27
|
-
throw Error(`File ${path} Not Exists`);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// If no utf-8, skip
|
|
31
|
-
try {
|
|
32
|
-
this.content = fs.readFileSync(this.path, 'utf-8');
|
|
33
|
-
this.isUtf8 = true;
|
|
34
|
-
} catch (e) {
|
|
35
|
-
this.isUtf8 = false;
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
replace(updater: (content: string) => string) {
|
|
41
|
-
if (!this.isUtf8) {
|
|
42
|
-
console.warn('Not UTF-8 file skipped: ', this.path);
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
this.content = updater(this.content);
|
|
46
|
-
fs.writeFileSync(this.path, this.content, 'utf-8');
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export function* traverseRecursiveFiles(folder: string): Generator<File> {
|
|
51
|
-
const files = fs.readdirSync(folder);
|
|
52
|
-
for (const file of files) {
|
|
53
|
-
const filePath = path.join(folder, file);
|
|
54
|
-
if (fs.statSync(filePath).isDirectory()) {
|
|
55
|
-
yield* traverseRecursiveFiles(filePath);
|
|
56
|
-
} else {
|
|
57
|
-
yield new File(filePath);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|