@flowgram.ai/cli 0.1.8 → 0.4.10
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 +324 -95
- package/dist/index.js +325 -92
- package/package.json +1 -1
- package/src/index.ts +3 -2
- package/src/materials/index.ts +23 -9
- package/src/materials/materials.ts +32 -39
- package/src/materials/refresh-project-import.ts +68 -0
- package/src/utils/export.ts +117 -0
- package/src/utils/{traverse-file.ts → file.ts} +1 -1
- package/src/utils/import.ts +3 -3
- package/src/utils/project.ts +3 -0
- package/src/utils/ts-file.ts +134 -0
package/dist/index.js
CHANGED
|
@@ -10,14 +10,17 @@ import { Command } from "commander";
|
|
|
10
10
|
|
|
11
11
|
// src/materials/index.ts
|
|
12
12
|
import inquirer from "inquirer";
|
|
13
|
-
import
|
|
13
|
+
import chalk3 from "chalk";
|
|
14
14
|
|
|
15
15
|
// src/materials/materials.ts
|
|
16
|
-
import
|
|
16
|
+
import path4 from "path";
|
|
17
|
+
import fs3 from "fs";
|
|
18
|
+
|
|
19
|
+
// src/utils/ts-file.ts
|
|
17
20
|
import path3 from "path";
|
|
18
21
|
import fs2 from "fs";
|
|
19
22
|
|
|
20
|
-
// src/utils/
|
|
23
|
+
// src/utils/file.ts
|
|
21
24
|
import path2 from "path";
|
|
22
25
|
import fs from "fs";
|
|
23
26
|
var File = class {
|
|
@@ -46,16 +49,92 @@ var File = class {
|
|
|
46
49
|
fs.writeFileSync(this.path, this.content, "utf-8");
|
|
47
50
|
}
|
|
48
51
|
};
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
|
|
53
|
+
// src/utils/export.ts
|
|
54
|
+
function extractNamedExports(content) {
|
|
55
|
+
const valueExports = [];
|
|
56
|
+
const typeExports = [];
|
|
57
|
+
const typeDefinitions = /* @__PURE__ */ new Set();
|
|
58
|
+
const typePatterns = [
|
|
59
|
+
/\b(?:type|interface)\s+(\w+)/g,
|
|
60
|
+
/\bexport\s+(?:type|interface)\s+(\w+)/g
|
|
61
|
+
];
|
|
62
|
+
let match;
|
|
63
|
+
for (const pattern of typePatterns) {
|
|
64
|
+
while ((match = pattern.exec(content)) !== null) {
|
|
65
|
+
typeDefinitions.add(match[1]);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const exportPatterns = [
|
|
69
|
+
// export const/var/let/function/class/type/interface
|
|
70
|
+
/\bexport\s+(const|var|let|function|class|type|interface)\s+(\w+)/g,
|
|
71
|
+
// export { name1, name2 }
|
|
72
|
+
/\bexport\s*\{([^}]+)\}/g,
|
|
73
|
+
// export { name as alias }
|
|
74
|
+
/\bexport\s*\{[^}]*\b(\w+)\s+as\s+(\w+)[^}]*\}/g,
|
|
75
|
+
// export default function name()
|
|
76
|
+
/\bexport\s+default\s+(?:function|class)\s+(\w+)/g,
|
|
77
|
+
// export type { Type1, Type2 }
|
|
78
|
+
/\bexport\s+type\s*\{([^}]+)\}/g,
|
|
79
|
+
// export type { Original as Alias }
|
|
80
|
+
/\bexport\s+type\s*\{[^}]*\b(\w+)\s+as\s+(\w+)[^}]*\}/g
|
|
81
|
+
];
|
|
82
|
+
exportPatterns[0].lastIndex = 0;
|
|
83
|
+
while ((match = exportPatterns[0].exec(content)) !== null) {
|
|
84
|
+
const [, kind, name] = match;
|
|
85
|
+
if (kind === "type" || kind === "interface" || typeDefinitions.has(name)) {
|
|
86
|
+
typeExports.push(name);
|
|
87
|
+
} else {
|
|
88
|
+
valueExports.push(name);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
exportPatterns[1].lastIndex = 0;
|
|
92
|
+
while ((match = exportPatterns[1].exec(content)) !== null) {
|
|
93
|
+
const exportsList = match[1].split(",").map((item) => item.trim()).filter((item) => item && !item.includes(" as "));
|
|
94
|
+
for (const name of exportsList) {
|
|
95
|
+
if (name.startsWith("type ")) {
|
|
96
|
+
typeExports.push(name.replace("type ", "").trim());
|
|
97
|
+
} else if (typeDefinitions.has(name)) {
|
|
98
|
+
typeExports.push(name);
|
|
99
|
+
} else {
|
|
100
|
+
valueExports.push(name);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
exportPatterns[2].lastIndex = 0;
|
|
105
|
+
while ((match = exportPatterns[2].exec(content)) !== null) {
|
|
106
|
+
const [, original, alias] = match;
|
|
107
|
+
if (typeDefinitions.has(original)) {
|
|
108
|
+
typeExports.push(alias);
|
|
55
109
|
} else {
|
|
56
|
-
|
|
110
|
+
valueExports.push(alias);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
exportPatterns[3].lastIndex = 0;
|
|
114
|
+
while ((match = exportPatterns[3].exec(content)) !== null) {
|
|
115
|
+
const name = match[1];
|
|
116
|
+
if (typeDefinitions.has(name)) {
|
|
117
|
+
typeExports.push(name);
|
|
118
|
+
} else {
|
|
119
|
+
valueExports.push(name);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
exportPatterns[4].lastIndex = 0;
|
|
123
|
+
while ((match = exportPatterns[4].exec(content)) !== null) {
|
|
124
|
+
const exportsList = match[1].split(",").map((item) => item.trim()).filter((item) => item && !item.includes(" as "));
|
|
125
|
+
for (const name of exportsList) {
|
|
126
|
+
typeExports.push(name);
|
|
57
127
|
}
|
|
58
128
|
}
|
|
129
|
+
exportPatterns[5].lastIndex = 0;
|
|
130
|
+
while ((match = exportPatterns[5].exec(content)) !== null) {
|
|
131
|
+
const [, original, alias] = match;
|
|
132
|
+
typeExports.push(alias);
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
values: [...new Set(valueExports)].sort(),
|
|
136
|
+
types: [...new Set(typeExports)].sort()
|
|
137
|
+
};
|
|
59
138
|
}
|
|
60
139
|
|
|
61
140
|
// src/utils/import.ts
|
|
@@ -75,14 +154,10 @@ function assembleImport(declaration) {
|
|
|
75
154
|
if (namespaceImport) {
|
|
76
155
|
importClauses.push(`* as ${namespaceImport}`);
|
|
77
156
|
}
|
|
78
|
-
return `import ${importClauses.join(", ")} from '${source}'
|
|
79
|
-
}
|
|
80
|
-
function replaceImport(fileContent, origin, replaceTo) {
|
|
81
|
-
const replaceImportStatements = replaceTo.map(assembleImport);
|
|
82
|
-
return fileContent.replace(origin.statement, replaceImportStatements.join("\n"));
|
|
157
|
+
return `import ${importClauses.join(", ")} from '${source}';`;
|
|
83
158
|
}
|
|
84
159
|
function* traverseFileImports(fileContent) {
|
|
85
|
-
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*['"`]([^'"`]+)['"`]
|
|
160
|
+
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;
|
|
86
161
|
let match;
|
|
87
162
|
while ((match = importRegex.exec(fileContent)) !== null) {
|
|
88
163
|
const [fullMatch, defaultPart, namespacePart, namedPart, defaultPart2, source] = match;
|
|
@@ -127,9 +202,113 @@ function* traverseFileImports(fileContent) {
|
|
|
127
202
|
}
|
|
128
203
|
}
|
|
129
204
|
|
|
205
|
+
// src/utils/ts-file.ts
|
|
206
|
+
var TsFile = class extends File {
|
|
207
|
+
constructor(filePath) {
|
|
208
|
+
super(filePath);
|
|
209
|
+
this.exports = {
|
|
210
|
+
values: [],
|
|
211
|
+
types: []
|
|
212
|
+
};
|
|
213
|
+
this.imports = [];
|
|
214
|
+
this.exports = extractNamedExports(fs2.readFileSync(filePath, "utf-8"));
|
|
215
|
+
this.imports = Array.from(
|
|
216
|
+
traverseFileImports(fs2.readFileSync(filePath, "utf-8"))
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
get allExportNames() {
|
|
220
|
+
return [...this.exports.values, ...this.exports.types];
|
|
221
|
+
}
|
|
222
|
+
addImport(importDeclarations) {
|
|
223
|
+
importDeclarations.forEach((importDeclaration) => {
|
|
224
|
+
importDeclaration.statement = assembleImport(importDeclaration);
|
|
225
|
+
});
|
|
226
|
+
this.replace((content) => {
|
|
227
|
+
const lastImportStatement = this.imports[this.imports.length - 1];
|
|
228
|
+
return content.replace(
|
|
229
|
+
lastImportStatement.statement,
|
|
230
|
+
`${lastImportStatement?.statement}
|
|
231
|
+
${importDeclarations.map(
|
|
232
|
+
(item) => item.statement
|
|
233
|
+
)}
|
|
234
|
+
`
|
|
235
|
+
);
|
|
236
|
+
});
|
|
237
|
+
this.imports.push(...importDeclarations);
|
|
238
|
+
}
|
|
239
|
+
removeImport(importDeclarations) {
|
|
240
|
+
this.replace(
|
|
241
|
+
(content) => importDeclarations.reduce(
|
|
242
|
+
(prev, cur) => prev.replace(cur.statement, ""),
|
|
243
|
+
content
|
|
244
|
+
)
|
|
245
|
+
);
|
|
246
|
+
this.imports = this.imports.filter(
|
|
247
|
+
(item) => !importDeclarations.includes(item)
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
replaceImport(oldImports, newImports) {
|
|
251
|
+
newImports.forEach((importDeclaration) => {
|
|
252
|
+
importDeclaration.statement = assembleImport(importDeclaration);
|
|
253
|
+
});
|
|
254
|
+
this.replace((content) => {
|
|
255
|
+
oldImports.forEach((oldImport, idx) => {
|
|
256
|
+
const replaceTo = newImports[idx];
|
|
257
|
+
if (replaceTo) {
|
|
258
|
+
content = content.replace(oldImport.statement, replaceTo.statement);
|
|
259
|
+
this.imports.map((_import) => {
|
|
260
|
+
if (_import.statement === oldImport.statement) {
|
|
261
|
+
_import = replaceTo;
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
} else {
|
|
265
|
+
content = content.replace(oldImport.statement, "");
|
|
266
|
+
this.imports = this.imports.filter(
|
|
267
|
+
(_import) => _import.statement !== oldImport.statement
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
const restNewImports = newImports.slice(oldImports.length);
|
|
272
|
+
if (restNewImports.length > 0) {
|
|
273
|
+
const lastImportStatement = newImports[oldImports.length - 1].statement;
|
|
274
|
+
content = content.replace(
|
|
275
|
+
lastImportStatement,
|
|
276
|
+
`${lastImportStatement}
|
|
277
|
+
${restNewImports.map(
|
|
278
|
+
(item) => item.statement
|
|
279
|
+
)}
|
|
280
|
+
`
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
this.imports.push(...restNewImports);
|
|
284
|
+
return content;
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
function* traverseRecursiveTsFiles(folder) {
|
|
289
|
+
const files = fs2.readdirSync(folder);
|
|
290
|
+
for (const file of files) {
|
|
291
|
+
const filePath = path3.join(folder, file);
|
|
292
|
+
if (fs2.statSync(filePath).isDirectory()) {
|
|
293
|
+
yield* traverseRecursiveTsFiles(filePath);
|
|
294
|
+
} else {
|
|
295
|
+
if (file.endsWith(".ts") || file.endsWith(".tsx")) {
|
|
296
|
+
yield new TsFile(filePath);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
function getIndexTsFile(folder) {
|
|
302
|
+
const files = fs2.readdirSync(folder);
|
|
303
|
+
for (const file of files) {
|
|
304
|
+
if (file === "index.ts" || file === "index.tsx") {
|
|
305
|
+
return new TsFile(path3.join(folder, file));
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
return void 0;
|
|
309
|
+
}
|
|
310
|
+
|
|
130
311
|
// src/materials/materials.ts
|
|
131
|
-
var __filename2 = fileURLToPath2(import.meta.url);
|
|
132
|
-
var __dirname2 = path3.dirname(__filename2);
|
|
133
312
|
var _types = [
|
|
134
313
|
"components",
|
|
135
314
|
"effects",
|
|
@@ -143,9 +322,9 @@ var _types = [
|
|
|
143
322
|
function listAllMaterials(formMaterialSrc) {
|
|
144
323
|
const _materials = [];
|
|
145
324
|
for (const _type of _types) {
|
|
146
|
-
const materialsPath =
|
|
325
|
+
const materialsPath = path4.join(formMaterialSrc, _type);
|
|
147
326
|
_materials.push(
|
|
148
|
-
...
|
|
327
|
+
...fs3.readdirSync(materialsPath).map((_path) => {
|
|
149
328
|
if (_path === "index.ts") {
|
|
150
329
|
return null;
|
|
151
330
|
}
|
|
@@ -153,7 +332,7 @@ function listAllMaterials(formMaterialSrc) {
|
|
|
153
332
|
name: _path,
|
|
154
333
|
// Assuming the folder name is the material name
|
|
155
334
|
type: _type,
|
|
156
|
-
path:
|
|
335
|
+
path: path4.join(materialsPath, _path)
|
|
157
336
|
};
|
|
158
337
|
}).filter((material) => material !== null)
|
|
159
338
|
);
|
|
@@ -161,50 +340,47 @@ function listAllMaterials(formMaterialSrc) {
|
|
|
161
340
|
return _materials;
|
|
162
341
|
}
|
|
163
342
|
var getFormMaterialDependencies = (formMaterialPath) => {
|
|
164
|
-
const packageJsonPath =
|
|
165
|
-
const packageJson = JSON.parse(
|
|
343
|
+
const packageJsonPath = path4.join(formMaterialPath, "package.json");
|
|
344
|
+
const packageJson = JSON.parse(fs3.readFileSync(packageJsonPath, "utf8"));
|
|
166
345
|
return packageJson.dependencies;
|
|
167
346
|
};
|
|
168
347
|
var copyMaterial = (material, project, formMaterialPath) => {
|
|
169
348
|
const formMaterialDependencies = getFormMaterialDependencies(formMaterialPath);
|
|
170
349
|
const sourceDir = material.path;
|
|
171
|
-
const materialRoot =
|
|
350
|
+
const materialRoot = path4.join(
|
|
172
351
|
project.projectPath,
|
|
173
352
|
"src",
|
|
174
353
|
"form-materials",
|
|
175
354
|
`${material.type}`
|
|
176
355
|
);
|
|
177
|
-
const targetDir =
|
|
356
|
+
const targetDir = path4.join(materialRoot, material.name);
|
|
178
357
|
const packagesToInstall = /* @__PURE__ */ new Set();
|
|
179
|
-
|
|
180
|
-
for (const file of
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
} else {
|
|
206
|
-
packagesToInstall.add(`${dep}@${version}`);
|
|
207
|
-
}
|
|
358
|
+
fs3.cpSync(sourceDir, targetDir, { recursive: true });
|
|
359
|
+
for (const file of traverseRecursiveTsFiles(targetDir)) {
|
|
360
|
+
for (const importDeclaration of file.imports) {
|
|
361
|
+
const { source } = importDeclaration;
|
|
362
|
+
if (source.startsWith("@/")) {
|
|
363
|
+
console.log(
|
|
364
|
+
`Replace Import from ${source} to @flowgram.ai/form-materials`
|
|
365
|
+
);
|
|
366
|
+
file.replaceImport(
|
|
367
|
+
[importDeclaration],
|
|
368
|
+
[{ ...importDeclaration, source: "@flowgram.ai/form-materials" }]
|
|
369
|
+
);
|
|
370
|
+
packagesToInstall.add(
|
|
371
|
+
`@flowgram.ai/form-materials@${project.flowgramVersion}`
|
|
372
|
+
);
|
|
373
|
+
} else if (!source.startsWith(".") && !source.startsWith("react")) {
|
|
374
|
+
const [dep, version] = Object.entries(formMaterialDependencies).find(
|
|
375
|
+
([_key]) => source.startsWith(_key)
|
|
376
|
+
) || [];
|
|
377
|
+
if (!dep) {
|
|
378
|
+
continue;
|
|
379
|
+
}
|
|
380
|
+
if (dep.startsWith("@flowgram.ai/")) {
|
|
381
|
+
packagesToInstall.add(`${dep}@${project.flowgramVersion}`);
|
|
382
|
+
} else {
|
|
383
|
+
packagesToInstall.add(`${dep}@${version}`);
|
|
208
384
|
}
|
|
209
385
|
}
|
|
210
386
|
}
|
|
@@ -217,14 +393,14 @@ var copyMaterial = (material, project, formMaterialPath) => {
|
|
|
217
393
|
// src/utils/npm.ts
|
|
218
394
|
import { execSync } from "child_process";
|
|
219
395
|
import { existsSync } from "fs";
|
|
220
|
-
import
|
|
396
|
+
import path5 from "path";
|
|
221
397
|
import download from "download";
|
|
222
398
|
async function getLatestVersion(packageName) {
|
|
223
399
|
return execSync(`npm view ${packageName} version --tag=latest`).toString().trim();
|
|
224
400
|
}
|
|
225
401
|
async function loadNpm(packageName) {
|
|
226
402
|
const packageLatestVersion = await getLatestVersion(packageName);
|
|
227
|
-
const packagePath =
|
|
403
|
+
const packagePath = path5.join(
|
|
228
404
|
__dirname,
|
|
229
405
|
`./.download/${packageName}-${packageLatestVersion}`
|
|
230
406
|
);
|
|
@@ -244,25 +420,26 @@ async function loadNpm(packageName) {
|
|
|
244
420
|
}
|
|
245
421
|
|
|
246
422
|
// src/materials/index.ts
|
|
247
|
-
import
|
|
423
|
+
import path7 from "path";
|
|
248
424
|
|
|
249
425
|
// src/utils/project.ts
|
|
250
426
|
import { existsSync as existsSync2, readFileSync, writeFileSync } from "fs";
|
|
251
|
-
import
|
|
427
|
+
import path6 from "path";
|
|
252
428
|
import chalk from "chalk";
|
|
253
429
|
var Project = class _Project {
|
|
254
430
|
constructor() {
|
|
255
431
|
}
|
|
256
432
|
async init() {
|
|
257
433
|
let projectPath = process.cwd();
|
|
258
|
-
while (projectPath !== "/" && !existsSync2(
|
|
259
|
-
projectPath =
|
|
434
|
+
while (projectPath !== "/" && !existsSync2(path6.join(projectPath, "package.json"))) {
|
|
435
|
+
projectPath = path6.join(projectPath, "..");
|
|
260
436
|
}
|
|
261
437
|
if (projectPath === "/") {
|
|
262
438
|
throw new Error("Please run this command in a valid project");
|
|
263
439
|
}
|
|
264
440
|
this.projectPath = projectPath;
|
|
265
|
-
this.
|
|
441
|
+
this.srcPath = path6.join(projectPath, "src");
|
|
442
|
+
this.packageJsonPath = path6.join(projectPath, "package.json");
|
|
266
443
|
this.packageJson = JSON.parse(readFileSync(this.packageJsonPath, "utf8"));
|
|
267
444
|
this.flowgramVersion = this.packageJson.dependencies["@flowgram.ai/fixed-layout-editor"] || this.packageJson.dependencies["@flowgram.ai/free-layout-editor"] || this.packageJson.dependencies["@flowgram.ai/editor"];
|
|
268
445
|
}
|
|
@@ -303,18 +480,70 @@ var Project = class _Project {
|
|
|
303
480
|
}
|
|
304
481
|
};
|
|
305
482
|
|
|
483
|
+
// src/materials/refresh-project-import.ts
|
|
484
|
+
import chalk2 from "chalk";
|
|
485
|
+
function executeRefreshProjectImport(project, material) {
|
|
486
|
+
const materialFile = getIndexTsFile(material.path);
|
|
487
|
+
if (!materialFile) {
|
|
488
|
+
console.warn(`Material ${material.name} not found`);
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
const targetDir = `@/form-materials/${material.type}/${material.name}`;
|
|
492
|
+
const exportNames = materialFile.allExportNames;
|
|
493
|
+
console.log(`\u{1F440} The exports of ${material.name} is ${exportNames.join(",")}`);
|
|
494
|
+
for (const tsFile of traverseRecursiveTsFiles(project.srcPath)) {
|
|
495
|
+
for (const importDeclaration of tsFile.imports) {
|
|
496
|
+
if (importDeclaration.source === "@flowgram.ai/form-materials") {
|
|
497
|
+
const currentMaterialImports = importDeclaration.namedImports?.filter(
|
|
498
|
+
(item) => exportNames.includes(item.imported)
|
|
499
|
+
);
|
|
500
|
+
if (!currentMaterialImports?.length) {
|
|
501
|
+
continue;
|
|
502
|
+
}
|
|
503
|
+
const nextImports = [
|
|
504
|
+
{
|
|
505
|
+
...importDeclaration,
|
|
506
|
+
namedImports: currentMaterialImports,
|
|
507
|
+
source: targetDir
|
|
508
|
+
}
|
|
509
|
+
];
|
|
510
|
+
const keepImportNames = importDeclaration.namedImports?.filter(
|
|
511
|
+
(item) => !exportNames.includes(item.imported)
|
|
512
|
+
);
|
|
513
|
+
if (keepImportNames?.length) {
|
|
514
|
+
nextImports.unshift({
|
|
515
|
+
...importDeclaration,
|
|
516
|
+
namedImports: keepImportNames
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
tsFile.replaceImport([importDeclaration], nextImports);
|
|
520
|
+
console.log(chalk2.green(`\u{1F504} Refresh Imports In: ${tsFile.path}`));
|
|
521
|
+
console.log(
|
|
522
|
+
`From:
|
|
523
|
+
${importDeclaration.statement}
|
|
524
|
+
To:
|
|
525
|
+
${nextImports.map((item) => item.statement).join("\n")}`
|
|
526
|
+
);
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
|
|
306
532
|
// src/materials/index.ts
|
|
307
|
-
async function syncMaterial(
|
|
308
|
-
|
|
533
|
+
async function syncMaterial(opts) {
|
|
534
|
+
const { materialName, refreshProjectImports } = opts;
|
|
535
|
+
console.log(chalk3.bold("\u{1F680} Welcome to @flowgram.ai form-materials!"));
|
|
309
536
|
const project = await Project.getSingleton();
|
|
310
537
|
project.printInfo();
|
|
311
538
|
if (!project.flowgramVersion) {
|
|
312
539
|
throw new Error(
|
|
313
|
-
|
|
540
|
+
chalk3.red(
|
|
541
|
+
"\u274C Please install @flowgram.ai/fixed-layout-editor or @flowgram.ai/free-layout-editor"
|
|
542
|
+
)
|
|
314
543
|
);
|
|
315
544
|
}
|
|
316
545
|
const formMaterialPath = await loadNpm("@flowgram.ai/form-materials");
|
|
317
|
-
const formMaterialSrc =
|
|
546
|
+
const formMaterialSrc = path7.join(formMaterialPath, "src");
|
|
318
547
|
const materials = listAllMaterials(formMaterialSrc);
|
|
319
548
|
let material;
|
|
320
549
|
if (materialName) {
|
|
@@ -323,10 +552,10 @@ async function syncMaterial(materialName) {
|
|
|
323
552
|
);
|
|
324
553
|
if (selectedMaterial) {
|
|
325
554
|
material = selectedMaterial;
|
|
326
|
-
console.log(
|
|
555
|
+
console.log(chalk3.green(`Using material: ${materialName}`));
|
|
327
556
|
} else {
|
|
328
557
|
console.log(
|
|
329
|
-
|
|
558
|
+
chalk3.yellow(
|
|
330
559
|
`Material "${materialName}" not found. Please select from the list:`
|
|
331
560
|
)
|
|
332
561
|
);
|
|
@@ -349,30 +578,34 @@ async function syncMaterial(materialName) {
|
|
|
349
578
|
material = result.material;
|
|
350
579
|
}
|
|
351
580
|
if (!material) {
|
|
352
|
-
console.error(
|
|
581
|
+
console.error(chalk3.red("No material selected. Exiting."));
|
|
353
582
|
process.exit(1);
|
|
354
583
|
}
|
|
584
|
+
if (refreshProjectImports) {
|
|
585
|
+
console.log(chalk3.bold("\u{1F680} Refresh imports in your project"));
|
|
586
|
+
executeRefreshProjectImport(project, material);
|
|
587
|
+
}
|
|
355
588
|
console.log(
|
|
356
|
-
|
|
589
|
+
chalk3.bold("\u{1F680} The following materials will be added to your project")
|
|
357
590
|
);
|
|
358
591
|
console.log(material);
|
|
359
592
|
let { packagesToInstall } = copyMaterial(material, project, formMaterialPath);
|
|
360
593
|
await project.addDependencies(packagesToInstall);
|
|
361
594
|
console.log(
|
|
362
|
-
|
|
595
|
+
chalk3.bold("\u2705 These npm dependencies is added to your package.json")
|
|
363
596
|
);
|
|
364
597
|
packagesToInstall.forEach((_package) => {
|
|
365
598
|
console.log(`- ${_package}`);
|
|
366
599
|
});
|
|
367
|
-
console.log(
|
|
600
|
+
console.log(chalk3.bold("\n\u27A1\uFE0F Please run npm install to install dependencies\n"));
|
|
368
601
|
}
|
|
369
602
|
|
|
370
603
|
// src/create-app/index.ts
|
|
371
|
-
import
|
|
604
|
+
import path8 from "path";
|
|
372
605
|
import { execSync as execSync2 } from "child_process";
|
|
373
606
|
import inquirer2 from "inquirer";
|
|
374
|
-
import
|
|
375
|
-
import
|
|
607
|
+
import fs4 from "fs-extra";
|
|
608
|
+
import chalk4 from "chalk";
|
|
376
609
|
import download2 from "download";
|
|
377
610
|
import * as tar from "tar";
|
|
378
611
|
var args = process.argv.slice(2);
|
|
@@ -384,7 +617,7 @@ var updateFlowGramVersions = (dependencies, latestVersion) => {
|
|
|
384
617
|
}
|
|
385
618
|
};
|
|
386
619
|
var createApp = async (projectName) => {
|
|
387
|
-
console.log(
|
|
620
|
+
console.log(chalk4.green("Welcome to @flowgram.ai/create-app CLI!"));
|
|
388
621
|
const latest = execSync2("npm view @flowgram.ai/demo-fixed-layout version --tag=latest latest").toString().trim();
|
|
389
622
|
let folderName = "";
|
|
390
623
|
if (!projectName) {
|
|
@@ -414,19 +647,19 @@ var createApp = async (projectName) => {
|
|
|
414
647
|
}
|
|
415
648
|
}
|
|
416
649
|
try {
|
|
417
|
-
const targetDir =
|
|
650
|
+
const targetDir = path8.join(process.cwd());
|
|
418
651
|
const downloadPackage = async () => {
|
|
419
652
|
try {
|
|
420
653
|
const tarballBuffer = await download2(`https://registry.npmjs.org/@flowgram.ai/${folderName}/-/${folderName}-${latest}.tgz`);
|
|
421
|
-
|
|
422
|
-
const tempTarballPath =
|
|
423
|
-
|
|
654
|
+
fs4.ensureDirSync(targetDir);
|
|
655
|
+
const tempTarballPath = path8.join(process.cwd(), `${folderName}.tgz`);
|
|
656
|
+
fs4.writeFileSync(tempTarballPath, tarballBuffer);
|
|
424
657
|
await tar.x({
|
|
425
658
|
file: tempTarballPath,
|
|
426
659
|
C: targetDir
|
|
427
660
|
});
|
|
428
|
-
|
|
429
|
-
|
|
661
|
+
fs4.renameSync(path8.join(targetDir, "package"), path8.join(targetDir, folderName));
|
|
662
|
+
fs4.unlinkSync(tempTarballPath);
|
|
430
663
|
return true;
|
|
431
664
|
} catch (error) {
|
|
432
665
|
console.error(`Error downloading or extracting package: ${error}`);
|
|
@@ -434,8 +667,8 @@ var createApp = async (projectName) => {
|
|
|
434
667
|
}
|
|
435
668
|
};
|
|
436
669
|
const res = await downloadPackage();
|
|
437
|
-
const pkgJsonPath =
|
|
438
|
-
const data =
|
|
670
|
+
const pkgJsonPath = path8.join(targetDir, folderName, "package.json");
|
|
671
|
+
const data = fs4.readFileSync(pkgJsonPath, "utf-8");
|
|
439
672
|
const packageLatestVersion = execSync2("npm view @flowgram.ai/core version --tag=latest latest").toString().trim();
|
|
440
673
|
const jsonData = JSON.parse(data);
|
|
441
674
|
if (jsonData.dependencies) {
|
|
@@ -444,15 +677,15 @@ var createApp = async (projectName) => {
|
|
|
444
677
|
if (jsonData.devDependencies) {
|
|
445
678
|
updateFlowGramVersions(jsonData.devDependencies, packageLatestVersion);
|
|
446
679
|
}
|
|
447
|
-
|
|
680
|
+
fs4.writeFileSync(pkgJsonPath, JSON.stringify(jsonData, null, 2), "utf-8");
|
|
448
681
|
if (res) {
|
|
449
|
-
console.log(
|
|
450
|
-
console.log(
|
|
451
|
-
console.log(
|
|
452
|
-
console.log(
|
|
453
|
-
console.log(
|
|
682
|
+
console.log(chalk4.green(`${folderName} Demo project created successfully!`));
|
|
683
|
+
console.log(chalk4.yellow("Run the following commands to start:"));
|
|
684
|
+
console.log(chalk4.cyan(` cd ${folderName}`));
|
|
685
|
+
console.log(chalk4.cyan(" npm install"));
|
|
686
|
+
console.log(chalk4.cyan(" npm start"));
|
|
454
687
|
} else {
|
|
455
|
-
console.log(
|
|
688
|
+
console.log(chalk4.red("Download failed"));
|
|
456
689
|
}
|
|
457
690
|
} catch (error) {
|
|
458
691
|
console.error("Error downloading repo:", error);
|
|
@@ -466,7 +699,7 @@ program.name("flowgram-cli").version("1.0.0").description("Flowgram CLI");
|
|
|
466
699
|
program.command("create-app").description("Create a new flowgram project").argument("[string]", "Project name").action(async (projectName) => {
|
|
467
700
|
await createApp(projectName);
|
|
468
701
|
});
|
|
469
|
-
program.command("materials").description("Sync materials to the project").argument("[string]", "Material name").action(async (materialName) => {
|
|
470
|
-
await syncMaterial(materialName);
|
|
702
|
+
program.command("materials").description("Sync materials to the project").argument("[string]", "Material name").option("--refresh-project-imports", "Refresh project imports to copied materials", false).action(async (materialName, options) => {
|
|
703
|
+
await syncMaterial({ materialName, refreshProjectImports: options.refreshProjectImports });
|
|
471
704
|
});
|
|
472
705
|
program.parse(process.argv);
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -24,8 +24,9 @@ program
|
|
|
24
24
|
.command("materials")
|
|
25
25
|
.description("Sync materials to the project")
|
|
26
26
|
.argument('[string]', 'Material name')
|
|
27
|
-
.
|
|
28
|
-
|
|
27
|
+
.option('--refresh-project-imports', 'Refresh project imports to copied materials', false)
|
|
28
|
+
.action(async (materialName, options) => {
|
|
29
|
+
await syncMaterial({ materialName, refreshProjectImports: options.refreshProjectImports });
|
|
29
30
|
});
|
|
30
31
|
|
|
31
32
|
program.parse(process.argv);
|