@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.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 chalk2 from "chalk";
13
+ import chalk3 from "chalk";
14
14
 
15
15
  // src/materials/materials.ts
16
- import { fileURLToPath as fileURLToPath2 } from "url";
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/traverse-file.ts
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
- function* traverseRecursiveFiles(folder) {
50
- const files = fs.readdirSync(folder);
51
- for (const file of files) {
52
- const filePath = path2.join(folder, file);
53
- if (fs.statSync(filePath).isDirectory()) {
54
- yield* traverseRecursiveFiles(filePath);
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
- yield new File(filePath);
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*['"`]([^'"`]+)['"`]/g;
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 = path3.join(formMaterialSrc, _type);
325
+ const materialsPath = path4.join(formMaterialSrc, _type);
147
326
  _materials.push(
148
- ...fs2.readdirSync(materialsPath).map((_path) => {
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: path3.join(materialsPath, _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 = path3.join(formMaterialPath, "package.json");
165
- const packageJson = JSON.parse(fs2.readFileSync(packageJsonPath, "utf8"));
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 = path3.join(
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 = path3.join(materialRoot, material.name);
356
+ const targetDir = path4.join(materialRoot, material.name);
178
357
  const packagesToInstall = /* @__PURE__ */ new Set();
179
- fs2.cpSync(sourceDir, targetDir, { recursive: true });
180
- for (const file of traverseRecursiveFiles(targetDir)) {
181
- if ([".ts", ".tsx"].includes(file.suffix)) {
182
- for (const importDeclaration of traverseFileImports(file.content)) {
183
- const { source } = importDeclaration;
184
- if (source.startsWith("@/")) {
185
- console.log(
186
- `Replace Import from ${source} to @flowgram.ai/form-materials`
187
- );
188
- file.replace(
189
- (content) => replaceImport(content, importDeclaration, [
190
- { ...importDeclaration, source: "@flowgram.ai/form-materials" }
191
- ])
192
- );
193
- packagesToInstall.add(
194
- `@flowgram.ai/form-materials@${project.flowgramVersion}`
195
- );
196
- } else if (!source.startsWith(".") && !source.startsWith("react")) {
197
- const [dep, version] = Object.entries(formMaterialDependencies).find(
198
- ([_key]) => source.startsWith(_key)
199
- ) || [];
200
- if (!dep) {
201
- continue;
202
- }
203
- if (dep.startsWith("@flowgram.ai/")) {
204
- packagesToInstall.add(`${dep}@${project.flowgramVersion}`);
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 path4 from "path";
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 = path4.join(
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 path6 from "path";
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 path5 from "path";
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(path5.join(projectPath, "package.json"))) {
259
- projectPath = path5.join(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.packageJsonPath = path5.join(projectPath, "package.json");
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(materialName) {
308
- console.log(chalk2.bgGreenBright("Welcome to @flowgram.ai form-materials!"));
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
- "Please install @flowgram.ai/fixed-layout-editor or @flowgram.ai/free-layout-editor"
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 = path6.join(formMaterialPath, "src");
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(chalk2.green(`Using material: ${materialName}`));
555
+ console.log(chalk3.green(`Using material: ${materialName}`));
327
556
  } else {
328
557
  console.log(
329
- chalk2.yellow(
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(chalk2.red("No material selected. Exiting."));
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
- chalk2.bold("The following materials will be added to your project")
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
- chalk2.bold("These npm dependencies is added to your package.json")
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(chalk2.bold("\nPlease run npm install to install dependencies"));
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 path7 from "path";
604
+ import path8 from "path";
372
605
  import { execSync as execSync2 } from "child_process";
373
606
  import inquirer2 from "inquirer";
374
- import fs3 from "fs-extra";
375
- import chalk3 from "chalk";
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(chalk3.green("Welcome to @flowgram.ai/create-app CLI!"));
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 = path7.join(process.cwd());
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
- fs3.ensureDirSync(targetDir);
422
- const tempTarballPath = path7.join(process.cwd(), `${folderName}.tgz`);
423
- fs3.writeFileSync(tempTarballPath, tarballBuffer);
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
- fs3.renameSync(path7.join(targetDir, "package"), path7.join(targetDir, folderName));
429
- fs3.unlinkSync(tempTarballPath);
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 = path7.join(targetDir, folderName, "package.json");
438
- const data = fs3.readFileSync(pkgJsonPath, "utf-8");
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
- fs3.writeFileSync(pkgJsonPath, JSON.stringify(jsonData, null, 2), "utf-8");
680
+ fs4.writeFileSync(pkgJsonPath, JSON.stringify(jsonData, null, 2), "utf-8");
448
681
  if (res) {
449
- console.log(chalk3.green(`${folderName} Demo project created successfully!`));
450
- console.log(chalk3.yellow("Run the following commands to start:"));
451
- console.log(chalk3.cyan(` cd ${folderName}`));
452
- console.log(chalk3.cyan(" npm install"));
453
- console.log(chalk3.cyan(" npm start"));
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(chalk3.red("Download failed"));
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowgram.ai/cli",
3
- "version": "0.1.8",
3
+ "version": "0.4.10",
4
4
  "description": "A CLI tool to create demo projects or sync materials",
5
5
  "bin": {
6
6
  "flowgram-cli": "./bin/index.js"
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
- .action(async (materialName) => {
28
- await syncMaterial(materialName);
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);