@flowgram.ai/cli 0.1.8 → 0.4.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -22,25 +22,25 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
22
22
  mod
23
23
  ));
24
24
 
25
- // ../../common/temp/node_modules/.pnpm/tsup@8.3.5_typescript@5.8.3/node_modules/tsup/assets/cjs_shims.js
26
- var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.src || new URL("main.js", document.baseURI).href;
27
- var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
28
-
29
25
  // src/index.ts
30
26
  var import_commander = require("commander");
31
27
 
32
28
  // src/materials/index.ts
33
29
  var import_inquirer = __toESM(require("inquirer"), 1);
34
- var import_chalk2 = __toESM(require("chalk"), 1);
30
+ var import_chalk3 = __toESM(require("chalk"), 1);
35
31
 
36
32
  // src/materials/materials.ts
37
- var import_url = require("url");
33
+ var import_path3 = __toESM(require("path"), 1);
34
+ var import_fs3 = __toESM(require("fs"), 1);
35
+
36
+ // src/utils/ts-file.ts
38
37
  var import_path2 = __toESM(require("path"), 1);
39
38
  var import_fs2 = __toESM(require("fs"), 1);
40
39
 
41
- // src/utils/traverse-file.ts
40
+ // src/utils/file.ts
42
41
  var import_path = __toESM(require("path"), 1);
43
42
  var import_fs = __toESM(require("fs"), 1);
43
+ var import_ignore = __toESM(require("ignore"), 1);
44
44
  var File = class {
45
45
  constructor(filePath, root = "/") {
46
46
  this.root = root;
@@ -66,17 +66,119 @@ var File = class {
66
66
  this.content = updater(this.content);
67
67
  import_fs.default.writeFileSync(this.path, this.content, "utf-8");
68
68
  }
69
+ write(nextContent) {
70
+ this.content = nextContent;
71
+ import_fs.default.writeFileSync(this.path, this.content, "utf-8");
72
+ }
69
73
  };
70
- function* traverseRecursiveFiles(folder) {
74
+ function* traverseRecursiveFilePaths(folder, ig = (0, import_ignore.default)().add(".git"), root = folder) {
71
75
  const files = import_fs.default.readdirSync(folder);
76
+ if (import_fs.default.existsSync(import_path.default.join(folder, ".gitignore"))) {
77
+ ig.add(import_fs.default.readFileSync(import_path.default.join(folder, ".gitignore"), "utf-8"));
78
+ }
72
79
  for (const file of files) {
73
80
  const filePath = import_path.default.join(folder, file);
81
+ if (ig.ignores(import_path.default.relative(root, filePath))) {
82
+ continue;
83
+ }
74
84
  if (import_fs.default.statSync(filePath).isDirectory()) {
75
- yield* traverseRecursiveFiles(filePath);
85
+ yield* traverseRecursiveFilePaths(filePath, ig, root);
86
+ } else {
87
+ yield filePath;
88
+ }
89
+ }
90
+ }
91
+ function* traverseRecursiveFiles(folder) {
92
+ for (const filePath of traverseRecursiveFilePaths(folder)) {
93
+ yield new File(filePath);
94
+ }
95
+ }
96
+
97
+ // src/utils/export.ts
98
+ function extractNamedExports(content) {
99
+ const valueExports = [];
100
+ const typeExports = [];
101
+ const typeDefinitions = /* @__PURE__ */ new Set();
102
+ const typePatterns = [
103
+ /\b(?:type|interface)\s+(\w+)/g,
104
+ /\bexport\s+(?:type|interface)\s+(\w+)/g
105
+ ];
106
+ let match;
107
+ for (const pattern of typePatterns) {
108
+ while ((match = pattern.exec(content)) !== null) {
109
+ typeDefinitions.add(match[1]);
110
+ }
111
+ }
112
+ const exportPatterns = [
113
+ // export const/var/let/function/class/type/interface
114
+ /\bexport\s+(const|var|let|function|class|type|interface)\s+(\w+)/g,
115
+ // export { name1, name2 }
116
+ /\bexport\s*\{([^}]+)\}/g,
117
+ // export { name as alias }
118
+ /\bexport\s*\{[^}]*\b(\w+)\s+as\s+(\w+)[^}]*\}/g,
119
+ // export default function name()
120
+ /\bexport\s+default\s+(?:function|class)\s+(\w+)/g,
121
+ // export type { Type1, Type2 }
122
+ /\bexport\s+type\s*\{([^}]+)\}/g,
123
+ // export type { Original as Alias }
124
+ /\bexport\s+type\s*\{[^}]*\b(\w+)\s+as\s+(\w+)[^}]*\}/g
125
+ ];
126
+ exportPatterns[0].lastIndex = 0;
127
+ while ((match = exportPatterns[0].exec(content)) !== null) {
128
+ const [, kind, name] = match;
129
+ if (kind === "type" || kind === "interface" || typeDefinitions.has(name)) {
130
+ typeExports.push(name);
131
+ } else {
132
+ valueExports.push(name);
133
+ }
134
+ }
135
+ exportPatterns[1].lastIndex = 0;
136
+ while ((match = exportPatterns[1].exec(content)) !== null) {
137
+ const exportsList = match[1].split(",").map((item) => item.trim()).filter((item) => item && !item.includes(" as "));
138
+ for (const name of exportsList) {
139
+ if (name.startsWith("type ")) {
140
+ typeExports.push(name.replace("type ", "").trim());
141
+ } else if (typeDefinitions.has(name)) {
142
+ typeExports.push(name);
143
+ } else {
144
+ valueExports.push(name);
145
+ }
146
+ }
147
+ }
148
+ exportPatterns[2].lastIndex = 0;
149
+ while ((match = exportPatterns[2].exec(content)) !== null) {
150
+ const [, original, alias] = match;
151
+ if (typeDefinitions.has(original)) {
152
+ typeExports.push(alias);
76
153
  } else {
77
- yield new File(filePath);
154
+ valueExports.push(alias);
78
155
  }
79
156
  }
157
+ exportPatterns[3].lastIndex = 0;
158
+ while ((match = exportPatterns[3].exec(content)) !== null) {
159
+ const name = match[1];
160
+ if (typeDefinitions.has(name)) {
161
+ typeExports.push(name);
162
+ } else {
163
+ valueExports.push(name);
164
+ }
165
+ }
166
+ exportPatterns[4].lastIndex = 0;
167
+ while ((match = exportPatterns[4].exec(content)) !== null) {
168
+ const exportsList = match[1].split(",").map((item) => item.trim()).filter((item) => item && !item.includes(" as "));
169
+ for (const name of exportsList) {
170
+ typeExports.push(name);
171
+ }
172
+ }
173
+ exportPatterns[5].lastIndex = 0;
174
+ while ((match = exportPatterns[5].exec(content)) !== null) {
175
+ const [, original, alias] = match;
176
+ typeExports.push(alias);
177
+ }
178
+ return {
179
+ values: [...new Set(valueExports)].sort(),
180
+ types: [...new Set(typeExports)].sort()
181
+ };
80
182
  }
81
183
 
82
184
  // src/utils/import.ts
@@ -96,14 +198,10 @@ function assembleImport(declaration) {
96
198
  if (namespaceImport) {
97
199
  importClauses.push(`* as ${namespaceImport}`);
98
200
  }
99
- return `import ${importClauses.join(", ")} from '${source}'`;
100
- }
101
- function replaceImport(fileContent, origin, replaceTo) {
102
- const replaceImportStatements = replaceTo.map(assembleImport);
103
- return fileContent.replace(origin.statement, replaceImportStatements.join("\n"));
201
+ return `import ${importClauses.join(", ")} from '${source}';`;
104
202
  }
105
203
  function* traverseFileImports(fileContent) {
106
- 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;
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;
107
205
  let match;
108
206
  while ((match = importRegex.exec(fileContent)) !== null) {
109
207
  const [fullMatch, defaultPart, namespacePart, namedPart, defaultPart2, source] = match;
@@ -148,9 +246,107 @@ function* traverseFileImports(fileContent) {
148
246
  }
149
247
  }
150
248
 
249
+ // src/utils/ts-file.ts
250
+ var TsFile = class extends File {
251
+ constructor(filePath) {
252
+ super(filePath);
253
+ this.exports = {
254
+ values: [],
255
+ types: []
256
+ };
257
+ this.imports = [];
258
+ this.exports = extractNamedExports(import_fs2.default.readFileSync(filePath, "utf-8"));
259
+ this.imports = Array.from(
260
+ traverseFileImports(import_fs2.default.readFileSync(filePath, "utf-8"))
261
+ );
262
+ }
263
+ get allExportNames() {
264
+ return [...this.exports.values, ...this.exports.types];
265
+ }
266
+ addImport(importDeclarations) {
267
+ importDeclarations.forEach((importDeclaration) => {
268
+ importDeclaration.statement = assembleImport(importDeclaration);
269
+ });
270
+ this.replace((content) => {
271
+ const lastImportStatement = this.imports[this.imports.length - 1];
272
+ return content.replace(
273
+ lastImportStatement.statement,
274
+ `${lastImportStatement?.statement}
275
+ ${importDeclarations.map(
276
+ (item) => item.statement
277
+ )}
278
+ `
279
+ );
280
+ });
281
+ this.imports.push(...importDeclarations);
282
+ }
283
+ removeImport(importDeclarations) {
284
+ 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)
292
+ );
293
+ }
294
+ replaceImport(oldImports, newImports) {
295
+ newImports.forEach((importDeclaration) => {
296
+ importDeclaration.statement = assembleImport(importDeclaration);
297
+ });
298
+ this.replace((content) => {
299
+ oldImports.forEach((oldImport, idx) => {
300
+ const replaceTo = newImports[idx];
301
+ if (replaceTo) {
302
+ content = content.replace(oldImport.statement, replaceTo.statement);
303
+ this.imports.map((_import) => {
304
+ if (_import.statement === oldImport.statement) {
305
+ _import = replaceTo;
306
+ }
307
+ });
308
+ } else {
309
+ content = content.replace(oldImport.statement, "");
310
+ this.imports = this.imports.filter(
311
+ (_import) => _import.statement !== oldImport.statement
312
+ );
313
+ }
314
+ });
315
+ const restNewImports = newImports.slice(oldImports.length);
316
+ if (restNewImports.length > 0) {
317
+ const lastImportStatement = newImports[oldImports.length - 1].statement;
318
+ content = content.replace(
319
+ lastImportStatement,
320
+ `${lastImportStatement}
321
+ ${restNewImports.map(
322
+ (item) => item.statement
323
+ )}
324
+ `
325
+ );
326
+ }
327
+ this.imports.push(...restNewImports);
328
+ return content;
329
+ });
330
+ }
331
+ };
332
+ function* traverseRecursiveTsFiles(folder) {
333
+ for (const filePath of traverseRecursiveFilePaths(folder)) {
334
+ if (filePath.endsWith(".ts") || filePath.endsWith(".tsx")) {
335
+ yield new TsFile(filePath);
336
+ }
337
+ }
338
+ }
339
+ function getIndexTsFile(folder) {
340
+ const files = import_fs2.default.readdirSync(folder);
341
+ for (const file of files) {
342
+ if (file === "index.ts" || file === "index.tsx") {
343
+ return new TsFile(import_path2.default.join(folder, file));
344
+ }
345
+ }
346
+ return void 0;
347
+ }
348
+
151
349
  // src/materials/materials.ts
152
- var __filename2 = (0, import_url.fileURLToPath)(importMetaUrl);
153
- var __dirname2 = import_path2.default.dirname(__filename2);
154
350
  var _types = [
155
351
  "components",
156
352
  "effects",
@@ -164,9 +360,9 @@ var _types = [
164
360
  function listAllMaterials(formMaterialSrc) {
165
361
  const _materials = [];
166
362
  for (const _type of _types) {
167
- const materialsPath = import_path2.default.join(formMaterialSrc, _type);
363
+ const materialsPath = import_path3.default.join(formMaterialSrc, _type);
168
364
  _materials.push(
169
- ...import_fs2.default.readdirSync(materialsPath).map((_path) => {
365
+ ...import_fs3.default.readdirSync(materialsPath).map((_path) => {
170
366
  if (_path === "index.ts") {
171
367
  return null;
172
368
  }
@@ -174,7 +370,7 @@ function listAllMaterials(formMaterialSrc) {
174
370
  name: _path,
175
371
  // Assuming the folder name is the material name
176
372
  type: _type,
177
- path: import_path2.default.join(materialsPath, _path)
373
+ path: import_path3.default.join(materialsPath, _path)
178
374
  };
179
375
  }).filter((material) => material !== null)
180
376
  );
@@ -182,50 +378,47 @@ function listAllMaterials(formMaterialSrc) {
182
378
  return _materials;
183
379
  }
184
380
  var getFormMaterialDependencies = (formMaterialPath) => {
185
- const packageJsonPath = import_path2.default.join(formMaterialPath, "package.json");
186
- const packageJson = JSON.parse(import_fs2.default.readFileSync(packageJsonPath, "utf8"));
381
+ const packageJsonPath = import_path3.default.join(formMaterialPath, "package.json");
382
+ const packageJson = JSON.parse(import_fs3.default.readFileSync(packageJsonPath, "utf8"));
187
383
  return packageJson.dependencies;
188
384
  };
189
385
  var copyMaterial = (material, project, formMaterialPath) => {
190
386
  const formMaterialDependencies = getFormMaterialDependencies(formMaterialPath);
191
387
  const sourceDir = material.path;
192
- const materialRoot = import_path2.default.join(
388
+ const materialRoot = import_path3.default.join(
193
389
  project.projectPath,
194
390
  "src",
195
391
  "form-materials",
196
392
  `${material.type}`
197
393
  );
198
- const targetDir = import_path2.default.join(materialRoot, material.name);
394
+ const targetDir = import_path3.default.join(materialRoot, material.name);
199
395
  const packagesToInstall = /* @__PURE__ */ new Set();
200
- import_fs2.default.cpSync(sourceDir, targetDir, { recursive: true });
201
- for (const file of traverseRecursiveFiles(targetDir)) {
202
- if ([".ts", ".tsx"].includes(file.suffix)) {
203
- for (const importDeclaration of traverseFileImports(file.content)) {
204
- const { source } = importDeclaration;
205
- if (source.startsWith("@/")) {
206
- console.log(
207
- `Replace Import from ${source} to @flowgram.ai/form-materials`
208
- );
209
- file.replace(
210
- (content) => replaceImport(content, importDeclaration, [
211
- { ...importDeclaration, source: "@flowgram.ai/form-materials" }
212
- ])
213
- );
214
- packagesToInstall.add(
215
- `@flowgram.ai/form-materials@${project.flowgramVersion}`
216
- );
217
- } else if (!source.startsWith(".") && !source.startsWith("react")) {
218
- const [dep, version] = Object.entries(formMaterialDependencies).find(
219
- ([_key]) => source.startsWith(_key)
220
- ) || [];
221
- if (!dep) {
222
- continue;
223
- }
224
- if (dep.startsWith("@flowgram.ai/")) {
225
- packagesToInstall.add(`${dep}@${project.flowgramVersion}`);
226
- } else {
227
- packagesToInstall.add(`${dep}@${version}`);
228
- }
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;
417
+ }
418
+ if (dep.startsWith("@flowgram.ai/")) {
419
+ packagesToInstall.add(`${dep}@${project.flowgramVersion}`);
420
+ } else {
421
+ packagesToInstall.add(`${dep}@${version}`);
229
422
  }
230
423
  }
231
424
  }
@@ -237,19 +430,19 @@ var copyMaterial = (material, project, formMaterialPath) => {
237
430
 
238
431
  // src/utils/npm.ts
239
432
  var import_child_process = require("child_process");
240
- var import_fs3 = require("fs");
241
- var import_path3 = __toESM(require("path"), 1);
433
+ var import_fs4 = require("fs");
434
+ var import_path4 = __toESM(require("path"), 1);
242
435
  var import_download = __toESM(require("download"), 1);
243
436
  async function getLatestVersion(packageName) {
244
437
  return (0, import_child_process.execSync)(`npm view ${packageName} version --tag=latest`).toString().trim();
245
438
  }
246
439
  async function loadNpm(packageName) {
247
440
  const packageLatestVersion = await getLatestVersion(packageName);
248
- const packagePath = import_path3.default.join(
441
+ const packagePath = import_path4.default.join(
249
442
  __dirname,
250
443
  `./.download/${packageName}-${packageLatestVersion}`
251
444
  );
252
- if ((0, import_fs3.existsSync)(packagePath)) {
445
+ if ((0, import_fs4.existsSync)(packagePath)) {
253
446
  return packagePath;
254
447
  }
255
448
  try {
@@ -265,26 +458,27 @@ async function loadNpm(packageName) {
265
458
  }
266
459
 
267
460
  // src/materials/index.ts
268
- var import_path5 = __toESM(require("path"), 1);
461
+ var import_path6 = __toESM(require("path"), 1);
269
462
 
270
463
  // src/utils/project.ts
271
- var import_fs4 = require("fs");
272
- var import_path4 = __toESM(require("path"), 1);
464
+ var import_fs5 = require("fs");
465
+ var import_path5 = __toESM(require("path"), 1);
273
466
  var import_chalk = __toESM(require("chalk"), 1);
274
467
  var Project = class _Project {
275
468
  constructor() {
276
469
  }
277
470
  async init() {
278
471
  let projectPath = process.cwd();
279
- while (projectPath !== "/" && !(0, import_fs4.existsSync)(import_path4.default.join(projectPath, "package.json"))) {
280
- projectPath = import_path4.default.join(projectPath, "..");
472
+ while (projectPath !== "/" && !(0, import_fs5.existsSync)(import_path5.default.join(projectPath, "package.json"))) {
473
+ projectPath = import_path5.default.join(projectPath, "..");
281
474
  }
282
475
  if (projectPath === "/") {
283
476
  throw new Error("Please run this command in a valid project");
284
477
  }
285
478
  this.projectPath = projectPath;
286
- this.packageJsonPath = import_path4.default.join(projectPath, "package.json");
287
- this.packageJson = JSON.parse((0, import_fs4.readFileSync)(this.packageJsonPath, "utf8"));
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"));
288
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"];
289
483
  }
290
484
  async addDependency(dependency) {
@@ -302,7 +496,7 @@ var Project = class _Project {
302
496
  }
303
497
  }
304
498
  this.packageJson.dependencies[name] = version;
305
- (0, import_fs4.writeFileSync)(
499
+ (0, import_fs5.writeFileSync)(
306
500
  this.packageJsonPath,
307
501
  JSON.stringify(this.packageJson, null, 2)
308
502
  );
@@ -312,6 +506,12 @@ var Project = class _Project {
312
506
  await this.addDependency(dependency);
313
507
  }
314
508
  }
509
+ writeToPackageJsonFile() {
510
+ (0, import_fs5.writeFileSync)(
511
+ this.packageJsonPath,
512
+ JSON.stringify(this.packageJson, null, 2)
513
+ );
514
+ }
315
515
  printInfo() {
316
516
  console.log(import_chalk.default.bold("Project Info:"));
317
517
  console.log(import_chalk.default.black(` - Flowgram Version: ${this.flowgramVersion}`));
@@ -324,18 +524,70 @@ var Project = class _Project {
324
524
  }
325
525
  };
326
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
+ for (const tsFile of traverseRecursiveTsFiles(project.srcPath)) {
539
+ for (const importDeclaration of tsFile.imports) {
540
+ if (importDeclaration.source === "@flowgram.ai/form-materials") {
541
+ const currentMaterialImports = importDeclaration.namedImports?.filter(
542
+ (item) => exportNames.includes(item.imported)
543
+ );
544
+ if (!currentMaterialImports?.length) {
545
+ continue;
546
+ }
547
+ const nextImports = [
548
+ {
549
+ ...importDeclaration,
550
+ namedImports: currentMaterialImports,
551
+ source: targetDir
552
+ }
553
+ ];
554
+ const keepImportNames = importDeclaration.namedImports?.filter(
555
+ (item) => !exportNames.includes(item.imported)
556
+ );
557
+ if (keepImportNames?.length) {
558
+ nextImports.unshift({
559
+ ...importDeclaration,
560
+ namedImports: keepImportNames
561
+ });
562
+ }
563
+ tsFile.replaceImport([importDeclaration], nextImports);
564
+ console.log(import_chalk2.default.green(`\u{1F504} Refresh Imports In: ${tsFile.path}`));
565
+ console.log(
566
+ `From:
567
+ ${importDeclaration.statement}
568
+ To:
569
+ ${nextImports.map((item) => item.statement).join("\n")}`
570
+ );
571
+ }
572
+ }
573
+ }
574
+ }
575
+
327
576
  // src/materials/index.ts
328
- async function syncMaterial(materialName) {
329
- console.log(import_chalk2.default.bgGreenBright("Welcome to @flowgram.ai form-materials!"));
577
+ async function syncMaterial(opts) {
578
+ const { materialName, refreshProjectImports } = opts;
579
+ console.log(import_chalk3.default.bold("\u{1F680} Welcome to @flowgram.ai form-materials!"));
330
580
  const project = await Project.getSingleton();
331
581
  project.printInfo();
332
582
  if (!project.flowgramVersion) {
333
583
  throw new Error(
334
- "Please install @flowgram.ai/fixed-layout-editor or @flowgram.ai/free-layout-editor"
584
+ import_chalk3.default.red(
585
+ "\u274C Please install @flowgram.ai/fixed-layout-editor or @flowgram.ai/free-layout-editor"
586
+ )
335
587
  );
336
588
  }
337
589
  const formMaterialPath = await loadNpm("@flowgram.ai/form-materials");
338
- const formMaterialSrc = import_path5.default.join(formMaterialPath, "src");
590
+ const formMaterialSrc = import_path6.default.join(formMaterialPath, "src");
339
591
  const materials = listAllMaterials(formMaterialSrc);
340
592
  let material;
341
593
  if (materialName) {
@@ -344,10 +596,10 @@ async function syncMaterial(materialName) {
344
596
  );
345
597
  if (selectedMaterial) {
346
598
  material = selectedMaterial;
347
- console.log(import_chalk2.default.green(`Using material: ${materialName}`));
599
+ console.log(import_chalk3.default.green(`Using material: ${materialName}`));
348
600
  } else {
349
601
  console.log(
350
- import_chalk2.default.yellow(
602
+ import_chalk3.default.yellow(
351
603
  `Material "${materialName}" not found. Please select from the list:`
352
604
  )
353
605
  );
@@ -370,30 +622,34 @@ async function syncMaterial(materialName) {
370
622
  material = result.material;
371
623
  }
372
624
  if (!material) {
373
- console.error(import_chalk2.default.red("No material selected. Exiting."));
625
+ console.error(import_chalk3.default.red("No material selected. Exiting."));
374
626
  process.exit(1);
375
627
  }
628
+ if (refreshProjectImports) {
629
+ console.log(import_chalk3.default.bold("\u{1F680} Refresh imports in your project"));
630
+ executeRefreshProjectImport(project, material);
631
+ }
376
632
  console.log(
377
- import_chalk2.default.bold("The following materials will be added to your project")
633
+ import_chalk3.default.bold("\u{1F680} The following materials will be added to your project")
378
634
  );
379
635
  console.log(material);
380
636
  let { packagesToInstall } = copyMaterial(material, project, formMaterialPath);
381
637
  await project.addDependencies(packagesToInstall);
382
638
  console.log(
383
- import_chalk2.default.bold("These npm dependencies is added to your package.json")
639
+ import_chalk3.default.bold("\u2705 These npm dependencies is added to your package.json")
384
640
  );
385
641
  packagesToInstall.forEach((_package) => {
386
642
  console.log(`- ${_package}`);
387
643
  });
388
- console.log(import_chalk2.default.bold("\nPlease run npm install to install dependencies"));
644
+ console.log(import_chalk3.default.bold("\n\u27A1\uFE0F Please run npm install to install dependencies\n"));
389
645
  }
390
646
 
391
647
  // src/create-app/index.ts
392
- var import_path6 = __toESM(require("path"), 1);
648
+ var import_path7 = __toESM(require("path"), 1);
393
649
  var import_child_process2 = require("child_process");
394
650
  var import_inquirer2 = __toESM(require("inquirer"), 1);
395
651
  var import_fs_extra = __toESM(require("fs-extra"), 1);
396
- var import_chalk3 = __toESM(require("chalk"), 1);
652
+ var import_chalk4 = __toESM(require("chalk"), 1);
397
653
  var import_download2 = __toESM(require("download"), 1);
398
654
  var tar = __toESM(require("tar"), 1);
399
655
  var args = process.argv.slice(2);
@@ -405,7 +661,7 @@ var updateFlowGramVersions = (dependencies, latestVersion) => {
405
661
  }
406
662
  };
407
663
  var createApp = async (projectName) => {
408
- console.log(import_chalk3.default.green("Welcome to @flowgram.ai/create-app CLI!"));
664
+ console.log(import_chalk4.default.green("Welcome to @flowgram.ai/create-app CLI!"));
409
665
  const latest = (0, import_child_process2.execSync)("npm view @flowgram.ai/demo-fixed-layout version --tag=latest latest").toString().trim();
410
666
  let folderName = "";
411
667
  if (!projectName) {
@@ -435,18 +691,18 @@ var createApp = async (projectName) => {
435
691
  }
436
692
  }
437
693
  try {
438
- const targetDir = import_path6.default.join(process.cwd());
694
+ const targetDir = import_path7.default.join(process.cwd());
439
695
  const downloadPackage = async () => {
440
696
  try {
441
697
  const tarballBuffer = await (0, import_download2.default)(`https://registry.npmjs.org/@flowgram.ai/${folderName}/-/${folderName}-${latest}.tgz`);
442
698
  import_fs_extra.default.ensureDirSync(targetDir);
443
- const tempTarballPath = import_path6.default.join(process.cwd(), `${folderName}.tgz`);
699
+ const tempTarballPath = import_path7.default.join(process.cwd(), `${folderName}.tgz`);
444
700
  import_fs_extra.default.writeFileSync(tempTarballPath, tarballBuffer);
445
701
  await tar.x({
446
702
  file: tempTarballPath,
447
703
  C: targetDir
448
704
  });
449
- import_fs_extra.default.renameSync(import_path6.default.join(targetDir, "package"), import_path6.default.join(targetDir, folderName));
705
+ import_fs_extra.default.renameSync(import_path7.default.join(targetDir, "package"), import_path7.default.join(targetDir, folderName));
450
706
  import_fs_extra.default.unlinkSync(tempTarballPath);
451
707
  return true;
452
708
  } catch (error) {
@@ -455,7 +711,7 @@ var createApp = async (projectName) => {
455
711
  }
456
712
  };
457
713
  const res = await downloadPackage();
458
- const pkgJsonPath = import_path6.default.join(targetDir, folderName, "package.json");
714
+ const pkgJsonPath = import_path7.default.join(targetDir, folderName, "package.json");
459
715
  const data = import_fs_extra.default.readFileSync(pkgJsonPath, "utf-8");
460
716
  const packageLatestVersion = (0, import_child_process2.execSync)("npm view @flowgram.ai/core version --tag=latest latest").toString().trim();
461
717
  const jsonData = JSON.parse(data);
@@ -467,13 +723,13 @@ var createApp = async (projectName) => {
467
723
  }
468
724
  import_fs_extra.default.writeFileSync(pkgJsonPath, JSON.stringify(jsonData, null, 2), "utf-8");
469
725
  if (res) {
470
- console.log(import_chalk3.default.green(`${folderName} Demo project created successfully!`));
471
- console.log(import_chalk3.default.yellow("Run the following commands to start:"));
472
- console.log(import_chalk3.default.cyan(` cd ${folderName}`));
473
- console.log(import_chalk3.default.cyan(" npm install"));
474
- console.log(import_chalk3.default.cyan(" npm start"));
726
+ console.log(import_chalk4.default.green(`${folderName} Demo project created successfully!`));
727
+ console.log(import_chalk4.default.yellow("Run the following commands to start:"));
728
+ console.log(import_chalk4.default.cyan(` cd ${folderName}`));
729
+ console.log(import_chalk4.default.cyan(" npm install"));
730
+ console.log(import_chalk4.default.cyan(" npm start"));
475
731
  } else {
476
- console.log(import_chalk3.default.red("Download failed"));
732
+ console.log(import_chalk4.default.red("Download failed"));
477
733
  }
478
734
  } catch (error) {
479
735
  console.error("Error downloading repo:", error);
@@ -481,13 +737,63 @@ var createApp = async (projectName) => {
481
737
  }
482
738
  };
483
739
 
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
+
484
780
  // src/index.ts
485
781
  var program = new import_commander.Command();
486
782
  program.name("flowgram-cli").version("1.0.0").description("Flowgram CLI");
487
783
  program.command("create-app").description("Create a new flowgram project").argument("[string]", "Project name").action(async (projectName) => {
488
784
  await createApp(projectName);
489
785
  });
490
- program.command("materials").description("Sync materials to the project").argument("[string]", "Material name").action(async (materialName) => {
491
- await syncMaterial(materialName);
786
+ program.command("materials").description("Sync materials to the project").argument("[string]", "Material name").option(
787
+ "--refresh-project-imports",
788
+ "Refresh project imports to copied materials",
789
+ false
790
+ ).action(async (materialName, options) => {
791
+ await syncMaterial({
792
+ materialName,
793
+ refreshProjectImports: options.refreshProjectImports
794
+ });
795
+ });
796
+ program.command("update-version").description("Update flowgram version in the project").argument("[string]", "Flowgram version").action(async (version) => {
797
+ await updateFlowgramVersion(version);
492
798
  });
493
799
  program.parse(process.argv);