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