@flowgram.ai/cli 0.4.10 → 0.4.12
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 +603 -378
- package/dist/index.js +603 -378
- package/package.json +9 -5
- package/src/create-app/index.ts +63 -32
- package/src/find-materials/index.ts +75 -0
- package/src/index.ts +41 -10
- package/src/materials/copy.ts +60 -0
- package/src/materials/index.ts +45 -74
- package/src/materials/material.ts +61 -0
- package/src/materials/refresh-project-import.ts +55 -36
- package/src/materials/select.ts +69 -0
- package/src/materials/types.ts +23 -0
- package/src/update-version/index.ts +53 -0
- package/src/utils/export.ts +8 -11
- package/src/utils/file.ts +31 -3
- package/src/utils/import.ts +7 -5
- package/src/utils/npm.ts +92 -19
- package/src/utils/project.ts +23 -23
- package/src/utils/ts-file.ts +24 -45
- package/src/materials/materials.ts +0 -127
package/dist/index.cjs
CHANGED
|
@@ -23,34 +23,108 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
23
23
|
));
|
|
24
24
|
|
|
25
25
|
// src/index.ts
|
|
26
|
+
var import_path10 = __toESM(require("path"), 1);
|
|
26
27
|
var import_commander = require("commander");
|
|
27
28
|
|
|
28
|
-
// src/
|
|
29
|
-
var
|
|
30
|
-
var import_chalk3 = __toESM(require("chalk"), 1);
|
|
29
|
+
// src/update-version/index.ts
|
|
30
|
+
var import_chalk = __toESM(require("chalk"), 1);
|
|
31
31
|
|
|
32
|
-
// src/
|
|
33
|
-
var
|
|
34
|
-
var
|
|
32
|
+
// src/utils/npm.ts
|
|
33
|
+
var import_path = __toESM(require("path"), 1);
|
|
34
|
+
var import_https = __toESM(require("https"), 1);
|
|
35
|
+
var import_fs = require("fs");
|
|
36
|
+
var import_child_process = require("child_process");
|
|
37
|
+
var tar = __toESM(require("tar"), 1);
|
|
38
|
+
var import_fs_extra = __toESM(require("fs-extra"), 1);
|
|
39
|
+
var LoadedNpmPkg = class {
|
|
40
|
+
constructor(name, version, path11) {
|
|
41
|
+
this.name = name;
|
|
42
|
+
this.version = version;
|
|
43
|
+
this.path = path11;
|
|
44
|
+
}
|
|
45
|
+
get srcPath() {
|
|
46
|
+
return import_path.default.join(this.path, "src");
|
|
47
|
+
}
|
|
48
|
+
get distPath() {
|
|
49
|
+
return import_path.default.join(this.path, "dist");
|
|
50
|
+
}
|
|
51
|
+
get packageJson() {
|
|
52
|
+
if (!this._packageJson) {
|
|
53
|
+
this._packageJson = JSON.parse((0, import_fs.readFileSync)(import_path.default.join(this.path, "package.json"), "utf8"));
|
|
54
|
+
}
|
|
55
|
+
return this._packageJson;
|
|
56
|
+
}
|
|
57
|
+
get dependencies() {
|
|
58
|
+
return this.packageJson.dependencies;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
function downloadFile(url, dest) {
|
|
62
|
+
return new Promise((resolve, reject) => {
|
|
63
|
+
const file = import_fs_extra.default.createWriteStream(dest);
|
|
64
|
+
import_https.default.get(url, (response) => {
|
|
65
|
+
if (response.statusCode !== 200) {
|
|
66
|
+
reject(new Error(`Download failed: ${response.statusCode}`));
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
response.pipe(file);
|
|
70
|
+
file.on("finish", () => {
|
|
71
|
+
file.close();
|
|
72
|
+
resolve();
|
|
73
|
+
});
|
|
74
|
+
}).on("error", (err) => {
|
|
75
|
+
import_fs_extra.default.unlink(dest, () => reject(err));
|
|
76
|
+
});
|
|
77
|
+
file.on("error", (err) => {
|
|
78
|
+
import_fs_extra.default.unlink(dest, () => reject(err));
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
async function getLatestVersion(packageName) {
|
|
83
|
+
return (0, import_child_process.execSync)(`npm view ${packageName} version --tag=latest`).toString().trim();
|
|
84
|
+
}
|
|
85
|
+
async function loadNpm(packageName) {
|
|
86
|
+
const packageLatestVersion = await getLatestVersion(packageName);
|
|
87
|
+
const packagePath = import_path.default.join(__dirname, `./.download/${packageName}-${packageLatestVersion}`);
|
|
88
|
+
if ((0, import_fs.existsSync)(packagePath)) {
|
|
89
|
+
return new LoadedNpmPkg(packageName, packageLatestVersion, packagePath);
|
|
90
|
+
}
|
|
91
|
+
try {
|
|
92
|
+
const tarballUrl = (0, import_child_process.execSync)(`npm view ${packageName}@${packageLatestVersion} dist.tarball`).toString().trim();
|
|
93
|
+
const tempTarballPath = import_path.default.join(
|
|
94
|
+
__dirname,
|
|
95
|
+
`./.download/${packageName}-${packageLatestVersion}.tgz`
|
|
96
|
+
);
|
|
97
|
+
import_fs_extra.default.ensureDirSync(import_path.default.dirname(tempTarballPath));
|
|
98
|
+
await downloadFile(tarballUrl, tempTarballPath);
|
|
99
|
+
import_fs_extra.default.ensureDirSync(packagePath);
|
|
100
|
+
await tar.x({
|
|
101
|
+
file: tempTarballPath,
|
|
102
|
+
cwd: packagePath,
|
|
103
|
+
strip: 1
|
|
104
|
+
});
|
|
105
|
+
import_fs_extra.default.unlinkSync(tempTarballPath);
|
|
106
|
+
return new LoadedNpmPkg(packageName, packageLatestVersion, packagePath);
|
|
107
|
+
} catch (error) {
|
|
108
|
+
console.error(`Error downloading or extracting package: ${error}`);
|
|
109
|
+
throw error;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
35
112
|
|
|
36
|
-
// src/utils/
|
|
113
|
+
// src/utils/file.ts
|
|
37
114
|
var import_path2 = __toESM(require("path"), 1);
|
|
38
115
|
var import_fs2 = __toESM(require("fs"), 1);
|
|
39
|
-
|
|
40
|
-
// src/utils/file.ts
|
|
41
|
-
var import_path = __toESM(require("path"), 1);
|
|
42
|
-
var import_fs = __toESM(require("fs"), 1);
|
|
116
|
+
var import_ignore = __toESM(require("ignore"), 1);
|
|
43
117
|
var File = class {
|
|
44
118
|
constructor(filePath, root = "/") {
|
|
45
119
|
this.root = root;
|
|
46
120
|
this.path = filePath;
|
|
47
|
-
this.relativePath =
|
|
48
|
-
this.suffix =
|
|
49
|
-
if (!
|
|
50
|
-
throw Error(`File ${
|
|
121
|
+
this.relativePath = import_path2.default.relative(this.root, this.path);
|
|
122
|
+
this.suffix = import_path2.default.extname(this.path);
|
|
123
|
+
if (!import_fs2.default.existsSync(this.path)) {
|
|
124
|
+
throw Error(`File ${import_path2.default} Not Exists`);
|
|
51
125
|
}
|
|
52
126
|
try {
|
|
53
|
-
this.content =
|
|
127
|
+
this.content = import_fs2.default.readFileSync(this.path, "utf-8");
|
|
54
128
|
this.isUtf8 = true;
|
|
55
129
|
} catch (e) {
|
|
56
130
|
this.isUtf8 = false;
|
|
@@ -63,19 +137,220 @@ var File = class {
|
|
|
63
137
|
return;
|
|
64
138
|
}
|
|
65
139
|
this.content = updater(this.content);
|
|
66
|
-
|
|
140
|
+
import_fs2.default.writeFileSync(this.path, this.content, "utf-8");
|
|
141
|
+
}
|
|
142
|
+
write(nextContent) {
|
|
143
|
+
this.content = nextContent;
|
|
144
|
+
import_fs2.default.writeFileSync(this.path, this.content, "utf-8");
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
function* traverseRecursiveFilePaths(folder, ig = (0, import_ignore.default)().add(".git"), root = folder) {
|
|
148
|
+
const files = import_fs2.default.readdirSync(folder);
|
|
149
|
+
if (import_fs2.default.existsSync(import_path2.default.join(folder, ".gitignore"))) {
|
|
150
|
+
ig.add(import_fs2.default.readFileSync(import_path2.default.join(folder, ".gitignore"), "utf-8"));
|
|
151
|
+
}
|
|
152
|
+
for (const file of files) {
|
|
153
|
+
const filePath = import_path2.default.join(folder, file);
|
|
154
|
+
if (ig.ignores(import_path2.default.relative(root, filePath))) {
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
if (import_fs2.default.statSync(filePath).isDirectory()) {
|
|
158
|
+
yield* traverseRecursiveFilePaths(filePath, ig, root);
|
|
159
|
+
} else {
|
|
160
|
+
yield filePath;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
function* traverseRecursiveFiles(folder) {
|
|
165
|
+
for (const filePath of traverseRecursiveFilePaths(folder)) {
|
|
166
|
+
yield new File(filePath, folder);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// src/update-version/index.ts
|
|
171
|
+
async function updateFlowgramVersion(inputVersion) {
|
|
172
|
+
console.log(import_chalk.default.bold("\u{1F680} Welcome to @flowgram.ai update-version helper"));
|
|
173
|
+
const latestVersion = await getLatestVersion("@flowgram.ai/editor");
|
|
174
|
+
const currentPath = process.cwd();
|
|
175
|
+
console.log("- Latest flowgram version: ", latestVersion);
|
|
176
|
+
console.log("- Current Path: ", currentPath);
|
|
177
|
+
const flowgramVersion = inputVersion || latestVersion;
|
|
178
|
+
for (const file of traverseRecursiveFiles(currentPath)) {
|
|
179
|
+
if (file.path.endsWith("package.json")) {
|
|
180
|
+
console.log("\u{1F440} Find package.json: ", file.path);
|
|
181
|
+
let updated = false;
|
|
182
|
+
const json = JSON.parse(file.content);
|
|
183
|
+
if (json.dependencies) {
|
|
184
|
+
for (const key in json.dependencies) {
|
|
185
|
+
if (key.startsWith("@flowgram.ai/")) {
|
|
186
|
+
updated = true;
|
|
187
|
+
json.dependencies[key] = flowgramVersion;
|
|
188
|
+
console.log(`- Update ${key} to ${flowgramVersion}`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
if (json.devDependencies) {
|
|
193
|
+
for (const key in json.devDependencies) {
|
|
194
|
+
if (key.startsWith("@flowgram.ai/")) {
|
|
195
|
+
updated = true;
|
|
196
|
+
json.devDependencies[key] = flowgramVersion;
|
|
197
|
+
console.log(`- Update ${key} to ${flowgramVersion}`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (updated) {
|
|
202
|
+
file.write(JSON.stringify(json, null, 2));
|
|
203
|
+
console.log(`\u2705 ${file.path} Updated`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// src/materials/index.ts
|
|
210
|
+
var import_path8 = __toESM(require("path"), 1);
|
|
211
|
+
var import_chalk5 = __toESM(require("chalk"), 1);
|
|
212
|
+
|
|
213
|
+
// src/utils/project.ts
|
|
214
|
+
var import_path3 = __toESM(require("path"), 1);
|
|
215
|
+
var import_fs3 = require("fs");
|
|
216
|
+
var import_chalk2 = __toESM(require("chalk"), 1);
|
|
217
|
+
var Project = class _Project {
|
|
218
|
+
constructor() {
|
|
219
|
+
}
|
|
220
|
+
async init() {
|
|
221
|
+
let projectPath = process.cwd();
|
|
222
|
+
while (projectPath !== "/" && !(0, import_fs3.existsSync)(import_path3.default.join(projectPath, "package.json"))) {
|
|
223
|
+
projectPath = import_path3.default.join(projectPath, "..");
|
|
224
|
+
}
|
|
225
|
+
if (projectPath === "/") {
|
|
226
|
+
throw new Error("Please run this command in a valid project");
|
|
227
|
+
}
|
|
228
|
+
this.projectPath = projectPath;
|
|
229
|
+
this.srcPath = import_path3.default.join(projectPath, "src");
|
|
230
|
+
this.packageJsonPath = import_path3.default.join(projectPath, "package.json");
|
|
231
|
+
this.packageJson = JSON.parse((0, import_fs3.readFileSync)(this.packageJsonPath, "utf8"));
|
|
232
|
+
this.flowgramVersion = this.packageJson.dependencies["@flowgram.ai/fixed-layout-editor"] || this.packageJson.dependencies["@flowgram.ai/free-layout-editor"] || this.packageJson.dependencies["@flowgram.ai/editor"];
|
|
233
|
+
}
|
|
234
|
+
async addDependency(dependency) {
|
|
235
|
+
let name;
|
|
236
|
+
let version;
|
|
237
|
+
const lastAtIndex = dependency.lastIndexOf("@");
|
|
238
|
+
if (lastAtIndex <= 0) {
|
|
239
|
+
name = dependency;
|
|
240
|
+
version = await getLatestVersion(name);
|
|
241
|
+
} else {
|
|
242
|
+
name = dependency.substring(0, lastAtIndex);
|
|
243
|
+
version = dependency.substring(lastAtIndex + 1);
|
|
244
|
+
if (!version.trim()) {
|
|
245
|
+
version = await getLatestVersion(name);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
this.packageJson.dependencies[name] = version;
|
|
249
|
+
(0, import_fs3.writeFileSync)(this.packageJsonPath, JSON.stringify(this.packageJson, null, 2));
|
|
250
|
+
}
|
|
251
|
+
async addDependencies(dependencies) {
|
|
252
|
+
for (const dependency of dependencies) {
|
|
253
|
+
await this.addDependency(dependency);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
writeToPackageJsonFile() {
|
|
257
|
+
(0, import_fs3.writeFileSync)(this.packageJsonPath, JSON.stringify(this.packageJson, null, 2));
|
|
258
|
+
}
|
|
259
|
+
printInfo() {
|
|
260
|
+
console.log(import_chalk2.default.bold("Project Info:"));
|
|
261
|
+
console.log(import_chalk2.default.black(` - Flowgram Version: ${this.flowgramVersion}`));
|
|
262
|
+
console.log(import_chalk2.default.black(` - Project Path: ${this.projectPath}`));
|
|
263
|
+
}
|
|
264
|
+
static async getSingleton() {
|
|
265
|
+
const info = new _Project();
|
|
266
|
+
await info.init();
|
|
267
|
+
return info;
|
|
67
268
|
}
|
|
68
269
|
};
|
|
69
270
|
|
|
271
|
+
// src/materials/select.ts
|
|
272
|
+
var import_inquirer = __toESM(require("inquirer"), 1);
|
|
273
|
+
var import_chalk3 = __toESM(require("chalk"), 1);
|
|
274
|
+
|
|
275
|
+
// src/materials/material.ts
|
|
276
|
+
var import_path5 = __toESM(require("path"), 1);
|
|
277
|
+
var import_fs5 = require("fs");
|
|
278
|
+
|
|
279
|
+
// src/utils/ts-file.ts
|
|
280
|
+
var import_path4 = __toESM(require("path"), 1);
|
|
281
|
+
var import_fs4 = __toESM(require("fs"), 1);
|
|
282
|
+
|
|
283
|
+
// src/utils/import.ts
|
|
284
|
+
function assembleImport(declaration) {
|
|
285
|
+
const { namedImports, defaultImport, namespaceImport, source } = declaration;
|
|
286
|
+
const importClauses = [];
|
|
287
|
+
if (namedImports) {
|
|
288
|
+
importClauses.push(
|
|
289
|
+
`{ ${namedImports.map(
|
|
290
|
+
({ local, imported, typeOnly }) => `${typeOnly ? "type " : ""}${imported}${local ? ` as ${local}` : ""}`
|
|
291
|
+
).join(", ")} }`
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
if (defaultImport) {
|
|
295
|
+
importClauses.push(defaultImport);
|
|
296
|
+
}
|
|
297
|
+
if (namespaceImport) {
|
|
298
|
+
importClauses.push(`* as ${namespaceImport}`);
|
|
299
|
+
}
|
|
300
|
+
return `import ${importClauses.join(", ")} from '${source}';`;
|
|
301
|
+
}
|
|
302
|
+
function* traverseFileImports(fileContent) {
|
|
303
|
+
const importRegex = /import\s+([^{}*,]*?)?(?:\s*\*\s*as\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*,?)?(?:\s*\{([^}]*)\}\s*,?)?(?:\s*([a-zA-Z_$][a-zA-Z0-9_$]*)\s*,?)?\s*from\s*['"`]([^'"`]+)['"`]\;?/g;
|
|
304
|
+
let match;
|
|
305
|
+
while ((match = importRegex.exec(fileContent)) !== null) {
|
|
306
|
+
const [fullMatch, defaultPart, namespacePart, namedPart, defaultPart2, source] = match;
|
|
307
|
+
const declaration = {
|
|
308
|
+
statement: fullMatch,
|
|
309
|
+
source
|
|
310
|
+
};
|
|
311
|
+
const defaultImport = defaultPart?.trim() || defaultPart2?.trim();
|
|
312
|
+
if (defaultImport && !namespacePart && !namedPart) {
|
|
313
|
+
declaration.defaultImport = defaultImport;
|
|
314
|
+
} else if (defaultImport && (namespacePart || namedPart)) {
|
|
315
|
+
declaration.defaultImport = defaultImport;
|
|
316
|
+
}
|
|
317
|
+
if (namespacePart) {
|
|
318
|
+
declaration.namespaceImport = namespacePart.trim();
|
|
319
|
+
}
|
|
320
|
+
if (namedPart) {
|
|
321
|
+
const namedImports = [];
|
|
322
|
+
const namedItems = namedPart.split(",").map((item) => item.trim()).filter(Boolean);
|
|
323
|
+
for (const item of namedItems) {
|
|
324
|
+
const typeOnly = item.startsWith("type ");
|
|
325
|
+
const cleanItem = typeOnly ? item.slice(5).trim() : item;
|
|
326
|
+
if (cleanItem.includes(" as ")) {
|
|
327
|
+
const [imported, local] = cleanItem.split(" as ").map((s) => s.trim());
|
|
328
|
+
namedImports.push({
|
|
329
|
+
imported,
|
|
330
|
+
local,
|
|
331
|
+
typeOnly
|
|
332
|
+
});
|
|
333
|
+
} else {
|
|
334
|
+
namedImports.push({
|
|
335
|
+
imported: cleanItem,
|
|
336
|
+
typeOnly
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
if (namedImports.length > 0) {
|
|
341
|
+
declaration.namedImports = namedImports;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
yield declaration;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
70
348
|
// src/utils/export.ts
|
|
71
349
|
function extractNamedExports(content) {
|
|
72
350
|
const valueExports = [];
|
|
73
351
|
const typeExports = [];
|
|
74
352
|
const typeDefinitions = /* @__PURE__ */ new Set();
|
|
75
|
-
const typePatterns = [
|
|
76
|
-
/\b(?:type|interface)\s+(\w+)/g,
|
|
77
|
-
/\bexport\s+(?:type|interface)\s+(\w+)/g
|
|
78
|
-
];
|
|
353
|
+
const typePatterns = [/\b(?:type|interface)\s+(\w+)/g, /\bexport\s+(?:type|interface)\s+(\w+)/g];
|
|
79
354
|
let match;
|
|
80
355
|
for (const pattern of typePatterns) {
|
|
81
356
|
while ((match = pattern.exec(content)) !== null) {
|
|
@@ -154,84 +429,17 @@ function extractNamedExports(content) {
|
|
|
154
429
|
};
|
|
155
430
|
}
|
|
156
431
|
|
|
157
|
-
// src/utils/import.ts
|
|
158
|
-
function assembleImport(declaration) {
|
|
159
|
-
const { namedImports, defaultImport, namespaceImport, source } = declaration;
|
|
160
|
-
const importClauses = [];
|
|
161
|
-
if (namedImports) {
|
|
162
|
-
importClauses.push(
|
|
163
|
-
`{ ${namedImports.map(
|
|
164
|
-
({ local, imported, typeOnly }) => `${typeOnly ? "type " : ""}${imported}${local ? ` as ${local}` : ""}`
|
|
165
|
-
).join(", ")} }`
|
|
166
|
-
);
|
|
167
|
-
}
|
|
168
|
-
if (defaultImport) {
|
|
169
|
-
importClauses.push(defaultImport);
|
|
170
|
-
}
|
|
171
|
-
if (namespaceImport) {
|
|
172
|
-
importClauses.push(`* as ${namespaceImport}`);
|
|
173
|
-
}
|
|
174
|
-
return `import ${importClauses.join(", ")} from '${source}';`;
|
|
175
|
-
}
|
|
176
|
-
function* traverseFileImports(fileContent) {
|
|
177
|
-
const importRegex = /import\s+([^{}*,]*?)?(?:\s*\*\s*as\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*,?)?(?:\s*\{([^}]*)\}\s*,?)?(?:\s*([a-zA-Z_$][a-zA-Z0-9_$]*)\s*,?)?\s*from\s*['"`]([^'"`]+)['"`]\;?/g;
|
|
178
|
-
let match;
|
|
179
|
-
while ((match = importRegex.exec(fileContent)) !== null) {
|
|
180
|
-
const [fullMatch, defaultPart, namespacePart, namedPart, defaultPart2, source] = match;
|
|
181
|
-
const declaration = {
|
|
182
|
-
statement: fullMatch,
|
|
183
|
-
source
|
|
184
|
-
};
|
|
185
|
-
const defaultImport = defaultPart?.trim() || defaultPart2?.trim();
|
|
186
|
-
if (defaultImport && !namespacePart && !namedPart) {
|
|
187
|
-
declaration.defaultImport = defaultImport;
|
|
188
|
-
} else if (defaultImport && (namespacePart || namedPart)) {
|
|
189
|
-
declaration.defaultImport = defaultImport;
|
|
190
|
-
}
|
|
191
|
-
if (namespacePart) {
|
|
192
|
-
declaration.namespaceImport = namespacePart.trim();
|
|
193
|
-
}
|
|
194
|
-
if (namedPart) {
|
|
195
|
-
const namedImports = [];
|
|
196
|
-
const namedItems = namedPart.split(",").map((item) => item.trim()).filter(Boolean);
|
|
197
|
-
for (const item of namedItems) {
|
|
198
|
-
const typeOnly = item.startsWith("type ");
|
|
199
|
-
const cleanItem = typeOnly ? item.slice(5).trim() : item;
|
|
200
|
-
if (cleanItem.includes(" as ")) {
|
|
201
|
-
const [imported, local] = cleanItem.split(" as ").map((s) => s.trim());
|
|
202
|
-
namedImports.push({
|
|
203
|
-
imported,
|
|
204
|
-
local,
|
|
205
|
-
typeOnly
|
|
206
|
-
});
|
|
207
|
-
} else {
|
|
208
|
-
namedImports.push({
|
|
209
|
-
imported: cleanItem,
|
|
210
|
-
typeOnly
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
if (namedImports.length > 0) {
|
|
215
|
-
declaration.namedImports = namedImports;
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
yield declaration;
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
432
|
// src/utils/ts-file.ts
|
|
223
433
|
var TsFile = class extends File {
|
|
224
|
-
constructor(filePath) {
|
|
225
|
-
super(filePath);
|
|
434
|
+
constructor(filePath, root) {
|
|
435
|
+
super(filePath, root);
|
|
226
436
|
this.exports = {
|
|
227
437
|
values: [],
|
|
228
438
|
types: []
|
|
229
439
|
};
|
|
230
440
|
this.imports = [];
|
|
231
|
-
this.exports = extractNamedExports(
|
|
232
|
-
this.imports = Array.from(
|
|
233
|
-
traverseFileImports(import_fs2.default.readFileSync(filePath, "utf-8"))
|
|
234
|
-
);
|
|
441
|
+
this.exports = extractNamedExports(import_fs4.default.readFileSync(filePath, "utf-8"));
|
|
442
|
+
this.imports = Array.from(traverseFileImports(import_fs4.default.readFileSync(filePath, "utf-8")));
|
|
235
443
|
}
|
|
236
444
|
get allExportNames() {
|
|
237
445
|
return [...this.exports.values, ...this.exports.types];
|
|
@@ -245,9 +453,7 @@ var TsFile = class extends File {
|
|
|
245
453
|
return content.replace(
|
|
246
454
|
lastImportStatement.statement,
|
|
247
455
|
`${lastImportStatement?.statement}
|
|
248
|
-
${importDeclarations.map(
|
|
249
|
-
(item) => item.statement
|
|
250
|
-
)}
|
|
456
|
+
${importDeclarations.map((item) => item.statement)}
|
|
251
457
|
`
|
|
252
458
|
);
|
|
253
459
|
});
|
|
@@ -255,14 +461,9 @@ ${importDeclarations.map(
|
|
|
255
461
|
}
|
|
256
462
|
removeImport(importDeclarations) {
|
|
257
463
|
this.replace(
|
|
258
|
-
(content) => importDeclarations.reduce(
|
|
259
|
-
(prev, cur) => prev.replace(cur.statement, ""),
|
|
260
|
-
content
|
|
261
|
-
)
|
|
262
|
-
);
|
|
263
|
-
this.imports = this.imports.filter(
|
|
264
|
-
(item) => !importDeclarations.includes(item)
|
|
464
|
+
(content) => importDeclarations.reduce((prev, cur) => prev.replace(cur.statement, ""), content)
|
|
265
465
|
);
|
|
466
|
+
this.imports = this.imports.filter((item) => !importDeclarations.includes(item));
|
|
266
467
|
}
|
|
267
468
|
replaceImport(oldImports, newImports) {
|
|
268
469
|
newImports.forEach((importDeclaration) => {
|
|
@@ -291,9 +492,7 @@ ${importDeclarations.map(
|
|
|
291
492
|
content = content.replace(
|
|
292
493
|
lastImportStatement,
|
|
293
494
|
`${lastImportStatement}
|
|
294
|
-
${restNewImports.map(
|
|
295
|
-
(item) => item.statement
|
|
296
|
-
)}
|
|
495
|
+
${restNewImports.map((item) => item.statement).join("\n")}
|
|
297
496
|
`
|
|
298
497
|
);
|
|
299
498
|
}
|
|
@@ -303,238 +502,160 @@ ${restNewImports.map(
|
|
|
303
502
|
}
|
|
304
503
|
};
|
|
305
504
|
function* traverseRecursiveTsFiles(folder) {
|
|
306
|
-
const
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
if (import_fs2.default.statSync(filePath).isDirectory()) {
|
|
310
|
-
yield* traverseRecursiveTsFiles(filePath);
|
|
311
|
-
} else {
|
|
312
|
-
if (file.endsWith(".ts") || file.endsWith(".tsx")) {
|
|
313
|
-
yield new TsFile(filePath);
|
|
314
|
-
}
|
|
505
|
+
for (const filePath of traverseRecursiveFilePaths(folder)) {
|
|
506
|
+
if (filePath.endsWith(".ts") || filePath.endsWith(".tsx")) {
|
|
507
|
+
yield new TsFile(filePath, folder);
|
|
315
508
|
}
|
|
316
509
|
}
|
|
317
510
|
}
|
|
318
511
|
function getIndexTsFile(folder) {
|
|
319
|
-
const files =
|
|
512
|
+
const files = import_fs4.default.readdirSync(folder);
|
|
320
513
|
for (const file of files) {
|
|
321
514
|
if (file === "index.ts" || file === "index.tsx") {
|
|
322
|
-
return new TsFile(
|
|
515
|
+
return new TsFile(import_path4.default.join(folder, file), folder);
|
|
323
516
|
}
|
|
324
517
|
}
|
|
325
518
|
return void 0;
|
|
326
519
|
}
|
|
327
520
|
|
|
328
|
-
// src/materials/
|
|
329
|
-
var
|
|
521
|
+
// src/materials/material.ts
|
|
522
|
+
var _Material = class _Material {
|
|
523
|
+
constructor(type, name, formMaterialPkg) {
|
|
524
|
+
this.type = type;
|
|
525
|
+
this.name = name;
|
|
526
|
+
this.formMaterialPkg = formMaterialPkg;
|
|
527
|
+
}
|
|
528
|
+
get fullName() {
|
|
529
|
+
return `${this.type}/${this.name}`;
|
|
530
|
+
}
|
|
531
|
+
get sourceDir() {
|
|
532
|
+
return import_path5.default.join(this.formMaterialPkg.srcPath, this.type, this.name);
|
|
533
|
+
}
|
|
534
|
+
get indexFile() {
|
|
535
|
+
return getIndexTsFile(this.sourceDir);
|
|
536
|
+
}
|
|
537
|
+
get allExportNames() {
|
|
538
|
+
return this.indexFile?.allExportNames || [];
|
|
539
|
+
}
|
|
540
|
+
static listAll(formMaterialPkg) {
|
|
541
|
+
if (!this._all_materials_cache.length) {
|
|
542
|
+
this._all_materials_cache = _Material.ALL_TYPES.map((type) => {
|
|
543
|
+
const materialsPath = import_path5.default.join(formMaterialPkg.srcPath, type);
|
|
544
|
+
return (0, import_fs5.readdirSync)(materialsPath).map((_path) => {
|
|
545
|
+
if (_path === "index.ts") {
|
|
546
|
+
return null;
|
|
547
|
+
}
|
|
548
|
+
return new _Material(type, _path, formMaterialPkg);
|
|
549
|
+
}).filter((material) => material !== null);
|
|
550
|
+
}).flat();
|
|
551
|
+
}
|
|
552
|
+
return this._all_materials_cache;
|
|
553
|
+
}
|
|
554
|
+
};
|
|
555
|
+
_Material._all_materials_cache = [];
|
|
556
|
+
_Material.ALL_TYPES = [
|
|
330
557
|
"components",
|
|
331
558
|
"effects",
|
|
332
559
|
"plugins",
|
|
333
560
|
"shared",
|
|
334
|
-
"typings",
|
|
335
561
|
"validate",
|
|
336
562
|
"form-plugins",
|
|
337
563
|
"hooks"
|
|
338
564
|
];
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
)
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
return packageJson.dependencies;
|
|
363
|
-
};
|
|
364
|
-
var copyMaterial = (material, project, formMaterialPath) => {
|
|
365
|
-
const formMaterialDependencies = getFormMaterialDependencies(formMaterialPath);
|
|
366
|
-
const sourceDir = material.path;
|
|
367
|
-
const materialRoot = import_path3.default.join(
|
|
368
|
-
project.projectPath,
|
|
369
|
-
"src",
|
|
370
|
-
"form-materials",
|
|
371
|
-
`${material.type}`
|
|
372
|
-
);
|
|
373
|
-
const targetDir = import_path3.default.join(materialRoot, material.name);
|
|
374
|
-
const packagesToInstall = /* @__PURE__ */ new Set();
|
|
375
|
-
import_fs3.default.cpSync(sourceDir, targetDir, { recursive: true });
|
|
376
|
-
for (const file of traverseRecursiveTsFiles(targetDir)) {
|
|
377
|
-
for (const importDeclaration of file.imports) {
|
|
378
|
-
const { source } = importDeclaration;
|
|
379
|
-
if (source.startsWith("@/")) {
|
|
380
|
-
console.log(
|
|
381
|
-
`Replace Import from ${source} to @flowgram.ai/form-materials`
|
|
382
|
-
);
|
|
383
|
-
file.replaceImport(
|
|
384
|
-
[importDeclaration],
|
|
385
|
-
[{ ...importDeclaration, source: "@flowgram.ai/form-materials" }]
|
|
386
|
-
);
|
|
387
|
-
packagesToInstall.add(
|
|
388
|
-
`@flowgram.ai/form-materials@${project.flowgramVersion}`
|
|
389
|
-
);
|
|
390
|
-
} else if (!source.startsWith(".") && !source.startsWith("react")) {
|
|
391
|
-
const [dep, version] = Object.entries(formMaterialDependencies).find(
|
|
392
|
-
([_key]) => source.startsWith(_key)
|
|
393
|
-
) || [];
|
|
394
|
-
if (!dep) {
|
|
395
|
-
continue;
|
|
565
|
+
var Material = _Material;
|
|
566
|
+
|
|
567
|
+
// src/materials/select.ts
|
|
568
|
+
var getSelectedMaterials = async (cliOpts, formMaterialPkg) => {
|
|
569
|
+
const { materialName, selectMultiple } = cliOpts;
|
|
570
|
+
const materials = Material.listAll(formMaterialPkg);
|
|
571
|
+
let selectedMaterials = [];
|
|
572
|
+
if (materialName) {
|
|
573
|
+
selectedMaterials = materialName.split(",").map((_name) => materials.find((_m) => _m.fullName === _name.trim())).filter(Boolean);
|
|
574
|
+
}
|
|
575
|
+
if (!selectedMaterials.length) {
|
|
576
|
+
console.log(import_chalk3.default.yellow(`Material "${materialName}" not found. Please select from the list:`));
|
|
577
|
+
const choices = materials.map((_material) => ({
|
|
578
|
+
name: _material.fullName,
|
|
579
|
+
value: _material
|
|
580
|
+
}));
|
|
581
|
+
if (selectMultiple) {
|
|
582
|
+
const result = await import_inquirer.default.prompt([
|
|
583
|
+
{
|
|
584
|
+
type: "checkbox",
|
|
585
|
+
name: "material",
|
|
586
|
+
message: "Select multiple materials to add:",
|
|
587
|
+
choices
|
|
396
588
|
}
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
589
|
+
]);
|
|
590
|
+
selectedMaterials = result.material;
|
|
591
|
+
} else {
|
|
592
|
+
const result = await import_inquirer.default.prompt([
|
|
593
|
+
{
|
|
594
|
+
type: "list",
|
|
595
|
+
name: "material",
|
|
596
|
+
message: "Select one material to add:",
|
|
597
|
+
choices
|
|
401
598
|
}
|
|
402
|
-
|
|
599
|
+
]);
|
|
600
|
+
selectedMaterials = [result.material];
|
|
403
601
|
}
|
|
404
602
|
}
|
|
405
|
-
return
|
|
406
|
-
packagesToInstall: [...packagesToInstall]
|
|
407
|
-
};
|
|
603
|
+
return selectedMaterials;
|
|
408
604
|
};
|
|
409
605
|
|
|
410
|
-
// src/
|
|
411
|
-
var import_child_process = require("child_process");
|
|
412
|
-
var import_fs4 = require("fs");
|
|
413
|
-
var import_path4 = __toESM(require("path"), 1);
|
|
414
|
-
var import_download = __toESM(require("download"), 1);
|
|
415
|
-
async function getLatestVersion(packageName) {
|
|
416
|
-
return (0, import_child_process.execSync)(`npm view ${packageName} version --tag=latest`).toString().trim();
|
|
417
|
-
}
|
|
418
|
-
async function loadNpm(packageName) {
|
|
419
|
-
const packageLatestVersion = await getLatestVersion(packageName);
|
|
420
|
-
const packagePath = import_path4.default.join(
|
|
421
|
-
__dirname,
|
|
422
|
-
`./.download/${packageName}-${packageLatestVersion}`
|
|
423
|
-
);
|
|
424
|
-
if ((0, import_fs4.existsSync)(packagePath)) {
|
|
425
|
-
return packagePath;
|
|
426
|
-
}
|
|
427
|
-
try {
|
|
428
|
-
const tarballUrl = (0, import_child_process.execSync)(
|
|
429
|
-
`npm view ${packageName}@${packageLatestVersion} dist.tarball`
|
|
430
|
-
).toString().trim();
|
|
431
|
-
await (0, import_download.default)(tarballUrl, packagePath, { extract: true, strip: 1 });
|
|
432
|
-
return packagePath;
|
|
433
|
-
} catch (error) {
|
|
434
|
-
console.error(`Error downloading or extracting package: ${error}`);
|
|
435
|
-
throw error;
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
// src/materials/index.ts
|
|
606
|
+
// src/materials/refresh-project-import.ts
|
|
440
607
|
var import_path6 = __toESM(require("path"), 1);
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
let projectPath = process.cwd();
|
|
451
|
-
while (projectPath !== "/" && !(0, import_fs5.existsSync)(import_path5.default.join(projectPath, "package.json"))) {
|
|
452
|
-
projectPath = import_path5.default.join(projectPath, "..");
|
|
453
|
-
}
|
|
454
|
-
if (projectPath === "/") {
|
|
455
|
-
throw new Error("Please run this command in a valid project");
|
|
456
|
-
}
|
|
457
|
-
this.projectPath = projectPath;
|
|
458
|
-
this.srcPath = import_path5.default.join(projectPath, "src");
|
|
459
|
-
this.packageJsonPath = import_path5.default.join(projectPath, "package.json");
|
|
460
|
-
this.packageJson = JSON.parse((0, import_fs5.readFileSync)(this.packageJsonPath, "utf8"));
|
|
461
|
-
this.flowgramVersion = this.packageJson.dependencies["@flowgram.ai/fixed-layout-editor"] || this.packageJson.dependencies["@flowgram.ai/free-layout-editor"] || this.packageJson.dependencies["@flowgram.ai/editor"];
|
|
462
|
-
}
|
|
463
|
-
async addDependency(dependency) {
|
|
464
|
-
let name;
|
|
465
|
-
let version;
|
|
466
|
-
const lastAtIndex = dependency.lastIndexOf("@");
|
|
467
|
-
if (lastAtIndex <= 0) {
|
|
468
|
-
name = dependency;
|
|
469
|
-
version = await getLatestVersion(name);
|
|
470
|
-
} else {
|
|
471
|
-
name = dependency.substring(0, lastAtIndex);
|
|
472
|
-
version = dependency.substring(lastAtIndex + 1);
|
|
473
|
-
if (!version.trim()) {
|
|
474
|
-
version = await getLatestVersion(name);
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
this.packageJson.dependencies[name] = version;
|
|
478
|
-
(0, import_fs5.writeFileSync)(
|
|
479
|
-
this.packageJsonPath,
|
|
480
|
-
JSON.stringify(this.packageJson, null, 2)
|
|
481
|
-
);
|
|
482
|
-
}
|
|
483
|
-
async addDependencies(dependencies) {
|
|
484
|
-
for (const dependency of dependencies) {
|
|
485
|
-
await this.addDependency(dependency);
|
|
608
|
+
var import_chalk4 = __toESM(require("chalk"), 1);
|
|
609
|
+
function executeRefreshProjectImport(context) {
|
|
610
|
+
const { selectedMaterials, project, targetFormMaterialRoot } = context;
|
|
611
|
+
const exportName2Material = /* @__PURE__ */ new Map();
|
|
612
|
+
const targetModule = `@/${import_path6.default.relative(project.srcPath, targetFormMaterialRoot)}`;
|
|
613
|
+
for (const material of selectedMaterials) {
|
|
614
|
+
if (!material.indexFile) {
|
|
615
|
+
console.warn(`Material ${material.name} not found`);
|
|
616
|
+
return;
|
|
486
617
|
}
|
|
618
|
+
console.log(`\u{1F440} The exports of ${material.name} is ${material.allExportNames.join(",")}`);
|
|
619
|
+
material.allExportNames.forEach((exportName) => {
|
|
620
|
+
exportName2Material.set(exportName, material);
|
|
621
|
+
});
|
|
487
622
|
}
|
|
488
|
-
printInfo() {
|
|
489
|
-
console.log(import_chalk.default.bold("Project Info:"));
|
|
490
|
-
console.log(import_chalk.default.black(` - Flowgram Version: ${this.flowgramVersion}`));
|
|
491
|
-
console.log(import_chalk.default.black(` - Project Path: ${this.projectPath}`));
|
|
492
|
-
}
|
|
493
|
-
static async getSingleton() {
|
|
494
|
-
const info = new _Project();
|
|
495
|
-
await info.init();
|
|
496
|
-
return info;
|
|
497
|
-
}
|
|
498
|
-
};
|
|
499
|
-
|
|
500
|
-
// src/materials/refresh-project-import.ts
|
|
501
|
-
var import_chalk2 = __toESM(require("chalk"), 1);
|
|
502
|
-
function executeRefreshProjectImport(project, material) {
|
|
503
|
-
const materialFile = getIndexTsFile(material.path);
|
|
504
|
-
if (!materialFile) {
|
|
505
|
-
console.warn(`Material ${material.name} not found`);
|
|
506
|
-
return;
|
|
507
|
-
}
|
|
508
|
-
const targetDir = `@/form-materials/${material.type}/${material.name}`;
|
|
509
|
-
const exportNames = materialFile.allExportNames;
|
|
510
|
-
console.log(`\u{1F440} The exports of ${material.name} is ${exportNames.join(",")}`);
|
|
511
623
|
for (const tsFile of traverseRecursiveTsFiles(project.srcPath)) {
|
|
512
624
|
for (const importDeclaration of tsFile.imports) {
|
|
513
|
-
if (importDeclaration.source
|
|
514
|
-
const
|
|
515
|
-
|
|
516
|
-
)
|
|
517
|
-
if (!currentMaterialImports?.length) {
|
|
625
|
+
if (importDeclaration.source.startsWith("@flowgram.ai/form-materials")) {
|
|
626
|
+
const restImports = [];
|
|
627
|
+
const importMap = {};
|
|
628
|
+
if (!importDeclaration.namedImports) {
|
|
518
629
|
continue;
|
|
519
630
|
}
|
|
520
|
-
const
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
631
|
+
for (const nameImport of importDeclaration.namedImports) {
|
|
632
|
+
const material = exportName2Material.get(nameImport.imported);
|
|
633
|
+
if (material) {
|
|
634
|
+
const importModule = `${targetModule}/${material.fullName}`;
|
|
635
|
+
importMap[importModule] = importMap[importModule] || [];
|
|
636
|
+
importMap[importModule].push(nameImport);
|
|
637
|
+
} else {
|
|
638
|
+
restImports.push(nameImport);
|
|
525
639
|
}
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
640
|
+
}
|
|
641
|
+
if (Object.keys(importMap).length === 0) {
|
|
642
|
+
continue;
|
|
643
|
+
}
|
|
644
|
+
const nextImports = Object.entries(importMap).map(
|
|
645
|
+
([importModule, namedImports]) => ({
|
|
646
|
+
...importDeclaration,
|
|
647
|
+
namedImports,
|
|
648
|
+
source: importModule
|
|
649
|
+
})
|
|
529
650
|
);
|
|
530
|
-
if (
|
|
651
|
+
if (restImports?.length) {
|
|
531
652
|
nextImports.unshift({
|
|
532
653
|
...importDeclaration,
|
|
533
|
-
namedImports:
|
|
654
|
+
namedImports: restImports
|
|
534
655
|
});
|
|
535
656
|
}
|
|
536
657
|
tsFile.replaceImport([importDeclaration], nextImports);
|
|
537
|
-
console.log(
|
|
658
|
+
console.log(import_chalk4.default.green(`\u{1F504} Refresh Imports In: ${tsFile.path}`));
|
|
538
659
|
console.log(
|
|
539
660
|
`From:
|
|
540
661
|
${importDeclaration.statement}
|
|
@@ -546,86 +667,147 @@ ${nextImports.map((item) => item.statement).join("\n")}`
|
|
|
546
667
|
}
|
|
547
668
|
}
|
|
548
669
|
|
|
670
|
+
// src/materials/copy.ts
|
|
671
|
+
var import_path7 = __toESM(require("path"), 1);
|
|
672
|
+
var import_fs6 = __toESM(require("fs"), 1);
|
|
673
|
+
var copyMaterials = (ctx) => {
|
|
674
|
+
const { selectedMaterials, project, formMaterialPkg, targetFormMaterialRoot } = ctx;
|
|
675
|
+
const formMaterialDependencies = formMaterialPkg.dependencies;
|
|
676
|
+
const packagesToInstall = /* @__PURE__ */ new Set();
|
|
677
|
+
for (const material of selectedMaterials) {
|
|
678
|
+
const sourceDir = material.sourceDir;
|
|
679
|
+
const targetDir = import_path7.default.join(targetFormMaterialRoot, material.type, material.name);
|
|
680
|
+
import_fs6.default.cpSync(sourceDir, targetDir, { recursive: true });
|
|
681
|
+
for (const file of traverseRecursiveTsFiles(targetDir)) {
|
|
682
|
+
for (const importDeclaration of file.imports) {
|
|
683
|
+
const { source } = importDeclaration;
|
|
684
|
+
if (source.startsWith("@/")) {
|
|
685
|
+
console.log(`Replace Import from ${source} to @flowgram.ai/form-materials`);
|
|
686
|
+
file.replaceImport(
|
|
687
|
+
[importDeclaration],
|
|
688
|
+
[{ ...importDeclaration, source: "@flowgram.ai/form-materials" }]
|
|
689
|
+
);
|
|
690
|
+
packagesToInstall.add(`@flowgram.ai/form-materials@${project.flowgramVersion}`);
|
|
691
|
+
} else if (!source.startsWith(".") && !source.startsWith("react")) {
|
|
692
|
+
const [dep, version] = Object.entries(formMaterialDependencies).find(([_key]) => source.startsWith(_key)) || [];
|
|
693
|
+
if (!dep) {
|
|
694
|
+
continue;
|
|
695
|
+
}
|
|
696
|
+
if (dep.startsWith("@flowgram.ai/")) {
|
|
697
|
+
packagesToInstall.add(`${dep}@${project.flowgramVersion}`);
|
|
698
|
+
} else {
|
|
699
|
+
packagesToInstall.add(`${dep}@${version}`);
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
return {
|
|
706
|
+
packagesToInstall: [...packagesToInstall]
|
|
707
|
+
};
|
|
708
|
+
};
|
|
709
|
+
|
|
549
710
|
// src/materials/index.ts
|
|
550
|
-
async function syncMaterial(
|
|
551
|
-
const {
|
|
552
|
-
console.log(
|
|
711
|
+
async function syncMaterial(cliOpts) {
|
|
712
|
+
const { refreshProjectImports, targetMaterialRootDir } = cliOpts;
|
|
713
|
+
console.log(import_chalk5.default.bold("\u{1F680} Welcome to @flowgram.ai form-materials CLI!"));
|
|
553
714
|
const project = await Project.getSingleton();
|
|
554
715
|
project.printInfo();
|
|
716
|
+
const targetFormMaterialRoot = targetMaterialRootDir || import_path8.default.join(project.projectPath, "src", "form-materials");
|
|
717
|
+
console.log(import_chalk5.default.black(` - Target material root: ${targetFormMaterialRoot}`));
|
|
555
718
|
if (!project.flowgramVersion) {
|
|
556
719
|
throw new Error(
|
|
557
|
-
|
|
720
|
+
import_chalk5.default.red(
|
|
558
721
|
"\u274C Please install @flowgram.ai/fixed-layout-editor or @flowgram.ai/free-layout-editor"
|
|
559
722
|
)
|
|
560
723
|
);
|
|
561
724
|
}
|
|
562
|
-
const
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
if (materialName) {
|
|
567
|
-
const selectedMaterial = materials.find(
|
|
568
|
-
(m) => `${m.type}/${m.name}` === materialName
|
|
569
|
-
);
|
|
570
|
-
if (selectedMaterial) {
|
|
571
|
-
material = selectedMaterial;
|
|
572
|
-
console.log(import_chalk3.default.green(`Using material: ${materialName}`));
|
|
573
|
-
} else {
|
|
574
|
-
console.log(
|
|
575
|
-
import_chalk3.default.yellow(
|
|
576
|
-
`Material "${materialName}" not found. Please select from the list:`
|
|
577
|
-
)
|
|
578
|
-
);
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
if (!material) {
|
|
582
|
-
const result = await import_inquirer.default.prompt([
|
|
583
|
-
{
|
|
584
|
-
type: "list",
|
|
585
|
-
name: "material",
|
|
586
|
-
message: "Select one material to add:",
|
|
587
|
-
choices: [
|
|
588
|
-
...materials.map((_material) => ({
|
|
589
|
-
name: `${_material.type}/${_material.name}`,
|
|
590
|
-
value: _material
|
|
591
|
-
}))
|
|
592
|
-
]
|
|
593
|
-
}
|
|
594
|
-
]);
|
|
595
|
-
material = result.material;
|
|
596
|
-
}
|
|
597
|
-
if (!material) {
|
|
598
|
-
console.error(import_chalk3.default.red("No material selected. Exiting."));
|
|
725
|
+
const formMaterialPkg = await loadNpm("@flowgram.ai/form-materials");
|
|
726
|
+
let selectedMaterials = await getSelectedMaterials(cliOpts, formMaterialPkg);
|
|
727
|
+
if (!selectedMaterials.length) {
|
|
728
|
+
console.error(import_chalk5.default.red("No material selected. Exiting."));
|
|
599
729
|
process.exit(1);
|
|
600
730
|
}
|
|
731
|
+
const context = {
|
|
732
|
+
selectedMaterials,
|
|
733
|
+
project,
|
|
734
|
+
formMaterialPkg,
|
|
735
|
+
cliOpts,
|
|
736
|
+
targetFormMaterialRoot
|
|
737
|
+
};
|
|
738
|
+
console.log(import_chalk5.default.bold("\u{1F680} The following materials will be added to your project"));
|
|
739
|
+
console.log(selectedMaterials.map((material) => `\u{1F4E6} ${material.fullName}`).join("\n"));
|
|
740
|
+
console.log("\n");
|
|
741
|
+
let { packagesToInstall } = copyMaterials(context);
|
|
601
742
|
if (refreshProjectImports) {
|
|
602
|
-
console.log(
|
|
603
|
-
executeRefreshProjectImport(
|
|
604
|
-
}
|
|
605
|
-
console.log(
|
|
606
|
-
import_chalk3.default.bold("\u{1F680} The following materials will be added to your project")
|
|
607
|
-
);
|
|
608
|
-
console.log(material);
|
|
609
|
-
let { packagesToInstall } = copyMaterial(material, project, formMaterialPath);
|
|
743
|
+
console.log(import_chalk5.default.bold("\u{1F680} Refresh imports in your project"));
|
|
744
|
+
executeRefreshProjectImport(context);
|
|
745
|
+
}
|
|
610
746
|
await project.addDependencies(packagesToInstall);
|
|
611
|
-
console.log(
|
|
612
|
-
import_chalk3.default.bold("\u2705 These npm dependencies is added to your package.json")
|
|
613
|
-
);
|
|
747
|
+
console.log(import_chalk5.default.bold("\n\u2705 These npm dependencies is added to your package.json"));
|
|
614
748
|
packagesToInstall.forEach((_package) => {
|
|
615
749
|
console.log(`- ${_package}`);
|
|
616
750
|
});
|
|
617
|
-
console.log(
|
|
751
|
+
console.log(import_chalk5.default.bold(import_chalk5.default.bold("\n\u27A1\uFE0F Please run npm install to install dependencies\n")));
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
// src/find-materials/index.ts
|
|
755
|
+
var import_chalk6 = __toESM(require("chalk"), 1);
|
|
756
|
+
async function findUsedMaterials() {
|
|
757
|
+
console.log(import_chalk6.default.bold("\u{1F680} Welcome to @flowgram.ai form-materials CLI!"));
|
|
758
|
+
const project = await Project.getSingleton();
|
|
759
|
+
project.printInfo();
|
|
760
|
+
const formMaterialPkg = await loadNpm("@flowgram.ai/form-materials");
|
|
761
|
+
const materials = Material.listAll(formMaterialPkg);
|
|
762
|
+
const allUsedMaterials = /* @__PURE__ */ new Set();
|
|
763
|
+
const exportName2Material = /* @__PURE__ */ new Map();
|
|
764
|
+
for (const material of materials) {
|
|
765
|
+
if (!material.indexFile) {
|
|
766
|
+
console.warn(`Material ${material.name} not found`);
|
|
767
|
+
return;
|
|
768
|
+
}
|
|
769
|
+
console.log(`\u{1F440} The exports of ${material.name} is ${material.allExportNames.join(",")}`);
|
|
770
|
+
material.allExportNames.forEach((exportName) => {
|
|
771
|
+
exportName2Material.set(exportName, material);
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
for (const tsFile of traverseRecursiveTsFiles(project.srcPath)) {
|
|
775
|
+
const fileMaterials = /* @__PURE__ */ new Set();
|
|
776
|
+
let fileImportPrinted = false;
|
|
777
|
+
for (const importDeclaration of tsFile.imports) {
|
|
778
|
+
if (!importDeclaration.source.startsWith("@flowgram.ai/form-materials") || !importDeclaration.namedImports?.length) {
|
|
779
|
+
continue;
|
|
780
|
+
}
|
|
781
|
+
if (!fileImportPrinted) {
|
|
782
|
+
fileImportPrinted = true;
|
|
783
|
+
console.log(import_chalk6.default.bold(`
|
|
784
|
+
\u{1F440} Searching ${tsFile.path}`));
|
|
785
|
+
}
|
|
786
|
+
console.log(`\u{1F50D} ${importDeclaration.statement}`);
|
|
787
|
+
if (importDeclaration.namedImports) {
|
|
788
|
+
importDeclaration.namedImports.forEach((namedImport) => {
|
|
789
|
+
const material = exportName2Material.get(namedImport.imported);
|
|
790
|
+
if (material) {
|
|
791
|
+
fileMaterials.add(material);
|
|
792
|
+
allUsedMaterials.add(material);
|
|
793
|
+
console.log(`import ${import_chalk6.default.bold(material.fullName)} by ${namedImport.imported}`);
|
|
794
|
+
}
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
console.log(import_chalk6.default.bold("\n\u{1F4E6} All used materials:"));
|
|
800
|
+
console.log([...allUsedMaterials].map((_material) => _material.fullName).join(","));
|
|
618
801
|
}
|
|
619
802
|
|
|
620
803
|
// src/create-app/index.ts
|
|
621
|
-
var
|
|
804
|
+
var import_path9 = __toESM(require("path"), 1);
|
|
805
|
+
var import_https2 = __toESM(require("https"), 1);
|
|
622
806
|
var import_child_process2 = require("child_process");
|
|
807
|
+
var tar2 = __toESM(require("tar"), 1);
|
|
623
808
|
var import_inquirer2 = __toESM(require("inquirer"), 1);
|
|
624
|
-
var
|
|
625
|
-
var
|
|
626
|
-
var import_download2 = __toESM(require("download"), 1);
|
|
627
|
-
var tar = __toESM(require("tar"), 1);
|
|
628
|
-
var args = process.argv.slice(2);
|
|
809
|
+
var import_fs_extra2 = __toESM(require("fs-extra"), 1);
|
|
810
|
+
var import_chalk7 = __toESM(require("chalk"), 1);
|
|
629
811
|
var updateFlowGramVersions = (dependencies, latestVersion) => {
|
|
630
812
|
for (const packageName in dependencies) {
|
|
631
813
|
if (packageName.startsWith("@flowgram.ai")) {
|
|
@@ -633,8 +815,29 @@ var updateFlowGramVersions = (dependencies, latestVersion) => {
|
|
|
633
815
|
}
|
|
634
816
|
}
|
|
635
817
|
};
|
|
818
|
+
function downloadFile2(url, dest) {
|
|
819
|
+
return new Promise((resolve, reject) => {
|
|
820
|
+
const file = import_fs_extra2.default.createWriteStream(dest);
|
|
821
|
+
import_https2.default.get(url, (response) => {
|
|
822
|
+
if (response.statusCode !== 200) {
|
|
823
|
+
reject(new Error(`Download failed: ${response.statusCode}`));
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
826
|
+
response.pipe(file);
|
|
827
|
+
file.on("finish", () => {
|
|
828
|
+
file.close();
|
|
829
|
+
resolve();
|
|
830
|
+
});
|
|
831
|
+
}).on("error", (err) => {
|
|
832
|
+
import_fs_extra2.default.unlink(dest, () => reject(err));
|
|
833
|
+
});
|
|
834
|
+
file.on("error", (err) => {
|
|
835
|
+
import_fs_extra2.default.unlink(dest, () => reject(err));
|
|
836
|
+
});
|
|
837
|
+
});
|
|
838
|
+
}
|
|
636
839
|
var createApp = async (projectName) => {
|
|
637
|
-
console.log(
|
|
840
|
+
console.log(import_chalk7.default.green("Welcome to @flowgram.ai/create-app CLI!"));
|
|
638
841
|
const latest = (0, import_child_process2.execSync)("npm view @flowgram.ai/demo-fixed-layout version --tag=latest latest").toString().trim();
|
|
639
842
|
let folderName = "";
|
|
640
843
|
if (!projectName) {
|
|
@@ -656,7 +859,14 @@ var createApp = async (projectName) => {
|
|
|
656
859
|
]);
|
|
657
860
|
folderName = repo;
|
|
658
861
|
} else {
|
|
659
|
-
if ([
|
|
862
|
+
if ([
|
|
863
|
+
"fixed-layout",
|
|
864
|
+
"free-layout",
|
|
865
|
+
"fixed-layout-simple",
|
|
866
|
+
"free-layout-simple",
|
|
867
|
+
"playground",
|
|
868
|
+
"nextjs"
|
|
869
|
+
].includes(projectName)) {
|
|
660
870
|
folderName = `demo-${projectName}`;
|
|
661
871
|
} else {
|
|
662
872
|
console.error('Invalid projectName. Please run "npx create-app" to choose demo.');
|
|
@@ -664,19 +874,20 @@ var createApp = async (projectName) => {
|
|
|
664
874
|
}
|
|
665
875
|
}
|
|
666
876
|
try {
|
|
667
|
-
const targetDir =
|
|
877
|
+
const targetDir = import_path9.default.join(process.cwd());
|
|
668
878
|
const downloadPackage = async () => {
|
|
669
879
|
try {
|
|
670
|
-
const
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
880
|
+
const url = `https://registry.npmjs.org/@flowgram.ai/${folderName}/-/${folderName}-${latest}.tgz`;
|
|
881
|
+
const tempTarballPath = import_path9.default.join(process.cwd(), `${folderName}.tgz`);
|
|
882
|
+
console.log(import_chalk7.default.blue(`Downloading ${url} ...`));
|
|
883
|
+
await downloadFile2(url, tempTarballPath);
|
|
884
|
+
import_fs_extra2.default.ensureDirSync(targetDir);
|
|
885
|
+
await tar2.x({
|
|
675
886
|
file: tempTarballPath,
|
|
676
887
|
C: targetDir
|
|
677
888
|
});
|
|
678
|
-
|
|
679
|
-
|
|
889
|
+
import_fs_extra2.default.renameSync(import_path9.default.join(targetDir, "package"), import_path9.default.join(targetDir, folderName));
|
|
890
|
+
import_fs_extra2.default.unlinkSync(tempTarballPath);
|
|
680
891
|
return true;
|
|
681
892
|
} catch (error) {
|
|
682
893
|
console.error(`Error downloading or extracting package: ${error}`);
|
|
@@ -684,8 +895,8 @@ var createApp = async (projectName) => {
|
|
|
684
895
|
}
|
|
685
896
|
};
|
|
686
897
|
const res = await downloadPackage();
|
|
687
|
-
const pkgJsonPath =
|
|
688
|
-
const data =
|
|
898
|
+
const pkgJsonPath = import_path9.default.join(targetDir, folderName, "package.json");
|
|
899
|
+
const data = import_fs_extra2.default.readFileSync(pkgJsonPath, "utf-8");
|
|
689
900
|
const packageLatestVersion = (0, import_child_process2.execSync)("npm view @flowgram.ai/core version --tag=latest latest").toString().trim();
|
|
690
901
|
const jsonData = JSON.parse(data);
|
|
691
902
|
if (jsonData.dependencies) {
|
|
@@ -694,15 +905,15 @@ var createApp = async (projectName) => {
|
|
|
694
905
|
if (jsonData.devDependencies) {
|
|
695
906
|
updateFlowGramVersions(jsonData.devDependencies, packageLatestVersion);
|
|
696
907
|
}
|
|
697
|
-
|
|
908
|
+
import_fs_extra2.default.writeFileSync(pkgJsonPath, JSON.stringify(jsonData, null, 2), "utf-8");
|
|
698
909
|
if (res) {
|
|
699
|
-
console.log(
|
|
700
|
-
console.log(
|
|
701
|
-
console.log(
|
|
702
|
-
console.log(
|
|
703
|
-
console.log(
|
|
910
|
+
console.log(import_chalk7.default.green(`${folderName} Demo project created successfully!`));
|
|
911
|
+
console.log(import_chalk7.default.yellow("Run the following commands to start:"));
|
|
912
|
+
console.log(import_chalk7.default.cyan(` cd ${folderName}`));
|
|
913
|
+
console.log(import_chalk7.default.cyan(" npm install"));
|
|
914
|
+
console.log(import_chalk7.default.cyan(" npm start"));
|
|
704
915
|
} else {
|
|
705
|
-
console.log(
|
|
916
|
+
console.log(import_chalk7.default.red("Download failed"));
|
|
706
917
|
}
|
|
707
918
|
} catch (error) {
|
|
708
919
|
console.error("Error downloading repo:", error);
|
|
@@ -716,7 +927,21 @@ program.name("flowgram-cli").version("1.0.0").description("Flowgram CLI");
|
|
|
716
927
|
program.command("create-app").description("Create a new flowgram project").argument("[string]", "Project name").action(async (projectName) => {
|
|
717
928
|
await createApp(projectName);
|
|
718
929
|
});
|
|
719
|
-
program.command("materials").description("Sync materials to the project").argument(
|
|
720
|
-
|
|
930
|
+
program.command("materials").description("Sync materials to the project").argument(
|
|
931
|
+
"[string]",
|
|
932
|
+
"Material name or names\nExample 1: components/variable-selector \nExample2: components/variable-selector,effect/provideJsonSchemaOutputs"
|
|
933
|
+
).option("--refresh-project-imports", "Refresh project imports to copied materials", false).option("--target-material-root-dir <string>", "Target directory to copy materials").option("--select-multiple", "Select multiple materials", false).action(async (materialName, options) => {
|
|
934
|
+
await syncMaterial({
|
|
935
|
+
materialName,
|
|
936
|
+
refreshProjectImports: options.refreshProjectImports,
|
|
937
|
+
targetMaterialRootDir: options.targetMaterialRootDir ? import_path10.default.join(process.cwd(), options.targetMaterialRootDir) : void 0,
|
|
938
|
+
selectMultiple: options.selectMultiple
|
|
939
|
+
});
|
|
940
|
+
});
|
|
941
|
+
program.command("find-used-materials").description("Find used materials in the project").action(async () => {
|
|
942
|
+
await findUsedMaterials();
|
|
943
|
+
});
|
|
944
|
+
program.command("update-version").description("Update flowgram version in the project").argument("[string]", "Flowgram version").action(async (version) => {
|
|
945
|
+
await updateFlowgramVersion(version);
|
|
721
946
|
});
|
|
722
947
|
program.parse(process.argv);
|