@flowgram.ai/cli 0.4.10 → 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
@@ -40,6 +40,7 @@ var import_fs2 = __toESM(require("fs"), 1);
40
40
  // src/utils/file.ts
41
41
  var import_path = __toESM(require("path"), 1);
42
42
  var import_fs = __toESM(require("fs"), 1);
43
+ var import_ignore = __toESM(require("ignore"), 1);
43
44
  var File = class {
44
45
  constructor(filePath, root = "/") {
45
46
  this.root = root;
@@ -65,7 +66,33 @@ var File = class {
65
66
  this.content = updater(this.content);
66
67
  import_fs.default.writeFileSync(this.path, this.content, "utf-8");
67
68
  }
69
+ write(nextContent) {
70
+ this.content = nextContent;
71
+ import_fs.default.writeFileSync(this.path, this.content, "utf-8");
72
+ }
68
73
  };
74
+ function* traverseRecursiveFilePaths(folder, ig = (0, import_ignore.default)().add(".git"), root = folder) {
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
+ }
79
+ for (const file of files) {
80
+ const filePath = import_path.default.join(folder, file);
81
+ if (ig.ignores(import_path.default.relative(root, filePath))) {
82
+ continue;
83
+ }
84
+ if (import_fs.default.statSync(filePath).isDirectory()) {
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
+ }
69
96
 
70
97
  // src/utils/export.ts
71
98
  function extractNamedExports(content) {
@@ -303,15 +330,9 @@ ${restNewImports.map(
303
330
  }
304
331
  };
305
332
  function* traverseRecursiveTsFiles(folder) {
306
- const files = import_fs2.default.readdirSync(folder);
307
- for (const file of files) {
308
- const filePath = import_path2.default.join(folder, file);
309
- if (import_fs2.default.statSync(filePath).isDirectory()) {
310
- yield* traverseRecursiveTsFiles(filePath);
311
- } else {
312
- if (file.endsWith(".ts") || file.endsWith(".tsx")) {
313
- yield new TsFile(filePath);
314
- }
333
+ for (const filePath of traverseRecursiveFilePaths(folder)) {
334
+ if (filePath.endsWith(".ts") || filePath.endsWith(".tsx")) {
335
+ yield new TsFile(filePath);
315
336
  }
316
337
  }
317
338
  }
@@ -485,6 +506,12 @@ var Project = class _Project {
485
506
  await this.addDependency(dependency);
486
507
  }
487
508
  }
509
+ writeToPackageJsonFile() {
510
+ (0, import_fs5.writeFileSync)(
511
+ this.packageJsonPath,
512
+ JSON.stringify(this.packageJson, null, 2)
513
+ );
514
+ }
488
515
  printInfo() {
489
516
  console.log(import_chalk.default.bold("Project Info:"));
490
517
  console.log(import_chalk.default.black(` - Flowgram Version: ${this.flowgramVersion}`));
@@ -710,13 +737,63 @@ var createApp = async (projectName) => {
710
737
  }
711
738
  };
712
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
+
713
780
  // src/index.ts
714
781
  var program = new import_commander.Command();
715
782
  program.name("flowgram-cli").version("1.0.0").description("Flowgram CLI");
716
783
  program.command("create-app").description("Create a new flowgram project").argument("[string]", "Project name").action(async (projectName) => {
717
784
  await createApp(projectName);
718
785
  });
719
- 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) => {
720
- await syncMaterial({ materialName, refreshProjectImports: options.refreshProjectImports });
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);
721
798
  });
722
799
  program.parse(process.argv);
package/dist/index.js CHANGED
@@ -23,6 +23,7 @@ import fs2 from "fs";
23
23
  // src/utils/file.ts
24
24
  import path2 from "path";
25
25
  import fs from "fs";
26
+ import ignore from "ignore";
26
27
  var File = class {
27
28
  constructor(filePath, root = "/") {
28
29
  this.root = root;
@@ -48,7 +49,33 @@ var File = class {
48
49
  this.content = updater(this.content);
49
50
  fs.writeFileSync(this.path, this.content, "utf-8");
50
51
  }
52
+ write(nextContent) {
53
+ this.content = nextContent;
54
+ fs.writeFileSync(this.path, this.content, "utf-8");
55
+ }
51
56
  };
57
+ function* traverseRecursiveFilePaths(folder, ig = ignore().add(".git"), root = folder) {
58
+ const files = fs.readdirSync(folder);
59
+ if (fs.existsSync(path2.join(folder, ".gitignore"))) {
60
+ ig.add(fs.readFileSync(path2.join(folder, ".gitignore"), "utf-8"));
61
+ }
62
+ for (const file of files) {
63
+ const filePath = path2.join(folder, file);
64
+ if (ig.ignores(path2.relative(root, filePath))) {
65
+ continue;
66
+ }
67
+ if (fs.statSync(filePath).isDirectory()) {
68
+ yield* traverseRecursiveFilePaths(filePath, ig, root);
69
+ } else {
70
+ yield filePath;
71
+ }
72
+ }
73
+ }
74
+ function* traverseRecursiveFiles(folder) {
75
+ for (const filePath of traverseRecursiveFilePaths(folder)) {
76
+ yield new File(filePath);
77
+ }
78
+ }
52
79
 
53
80
  // src/utils/export.ts
54
81
  function extractNamedExports(content) {
@@ -286,15 +313,9 @@ ${restNewImports.map(
286
313
  }
287
314
  };
288
315
  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
- }
316
+ for (const filePath of traverseRecursiveFilePaths(folder)) {
317
+ if (filePath.endsWith(".ts") || filePath.endsWith(".tsx")) {
318
+ yield new TsFile(filePath);
298
319
  }
299
320
  }
300
321
  }
@@ -468,6 +489,12 @@ var Project = class _Project {
468
489
  await this.addDependency(dependency);
469
490
  }
470
491
  }
492
+ writeToPackageJsonFile() {
493
+ writeFileSync(
494
+ this.packageJsonPath,
495
+ JSON.stringify(this.packageJson, null, 2)
496
+ );
497
+ }
471
498
  printInfo() {
472
499
  console.log(chalk.bold("Project Info:"));
473
500
  console.log(chalk.black(` - Flowgram Version: ${this.flowgramVersion}`));
@@ -693,13 +720,63 @@ var createApp = async (projectName) => {
693
720
  }
694
721
  };
695
722
 
723
+ // src/update-version/index.ts
724
+ import chalk5 from "chalk";
725
+ async function updateFlowgramVersion(inputVersion) {
726
+ console.log(chalk5.bold("\u{1F680} Welcome to @flowgram.ai update-version helper"));
727
+ const latestVersion = await getLatestVersion("@flowgram.ai/editor");
728
+ const currentPath = process.cwd();
729
+ console.log("- Latest flowgram version: ", latestVersion);
730
+ console.log("- Current Path: ", currentPath);
731
+ const flowgramVersion = inputVersion || latestVersion;
732
+ for (const file of traverseRecursiveFiles(currentPath)) {
733
+ if (file.path.endsWith("package.json")) {
734
+ console.log("\u{1F440} Find package.json: ", file.path);
735
+ let updated = false;
736
+ const json = JSON.parse(file.content);
737
+ if (json.dependencies) {
738
+ for (const key in json.dependencies) {
739
+ if (key.startsWith("@flowgram.ai/")) {
740
+ updated = true;
741
+ json.dependencies[key] = flowgramVersion;
742
+ console.log(`- Update ${key} to ${flowgramVersion}`);
743
+ }
744
+ }
745
+ }
746
+ if (json.devDependencies) {
747
+ for (const key in json.devDependencies) {
748
+ if (key.startsWith("@flowgram.ai/")) {
749
+ updated = true;
750
+ json.devDependencies[key] = flowgramVersion;
751
+ console.log(`- Update ${key} to ${flowgramVersion}`);
752
+ }
753
+ }
754
+ }
755
+ if (updated) {
756
+ file.write(JSON.stringify(json, null, 2));
757
+ console.log(`\u2705 ${file.path} Updated`);
758
+ }
759
+ }
760
+ }
761
+ }
762
+
696
763
  // src/index.ts
697
764
  var program = new Command();
698
765
  program.name("flowgram-cli").version("1.0.0").description("Flowgram CLI");
699
766
  program.command("create-app").description("Create a new flowgram project").argument("[string]", "Project name").action(async (projectName) => {
700
767
  await createApp(projectName);
701
768
  });
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 });
769
+ program.command("materials").description("Sync materials to the project").argument("[string]", "Material name").option(
770
+ "--refresh-project-imports",
771
+ "Refresh project imports to copied materials",
772
+ false
773
+ ).action(async (materialName, options) => {
774
+ await syncMaterial({
775
+ materialName,
776
+ refreshProjectImports: options.refreshProjectImports
777
+ });
778
+ });
779
+ program.command("update-version").description("Update flowgram version in the project").argument("[string]", "Flowgram version").action(async (version) => {
780
+ await updateFlowgramVersion(version);
704
781
  });
705
782
  program.parse(process.argv);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowgram.ai/cli",
3
- "version": "0.4.10",
3
+ "version": "0.4.11",
4
4
  "description": "A CLI tool to create demo projects or sync materials",
5
5
  "bin": {
6
6
  "flowgram-cli": "./bin/index.js"
@@ -17,7 +17,8 @@
17
17
  "chalk": "^5.3.0",
18
18
  "download": "8.0.0",
19
19
  "tar": "7.4.3",
20
- "inquirer": "^9.2.7"
20
+ "inquirer": "^9.2.7",
21
+ "ignore": "~7.0.5"
21
22
  },
22
23
  "devDependencies": {
23
24
  "@types/download": "8.0.5",
package/src/index.ts CHANGED
@@ -7,6 +7,7 @@ import { Command } from "commander";
7
7
 
8
8
  import { syncMaterial } from "./materials";
9
9
  import { createApp } from "./create-app";
10
+ import { updateFlowgramVersion } from "./update-version";
10
11
 
11
12
  const program = new Command();
12
13
 
@@ -15,7 +16,7 @@ program.name("flowgram-cli").version("1.0.0").description("Flowgram CLI");
15
16
  program
16
17
  .command("create-app")
17
18
  .description("Create a new flowgram project")
18
- .argument('[string]', 'Project name')
19
+ .argument("[string]", "Project name")
19
20
  .action(async (projectName) => {
20
21
  await createApp(projectName);
21
22
  });
@@ -23,10 +24,25 @@ program
23
24
  program
24
25
  .command("materials")
25
26
  .description("Sync materials to the project")
26
- .argument('[string]', 'Material name')
27
- .option('--refresh-project-imports', 'Refresh project imports to copied materials', false)
27
+ .argument("[string]", "Material name")
28
+ .option(
29
+ "--refresh-project-imports",
30
+ "Refresh project imports to copied materials",
31
+ false,
32
+ )
28
33
  .action(async (materialName, options) => {
29
- await syncMaterial({ materialName, refreshProjectImports: options.refreshProjectImports });
34
+ await syncMaterial({
35
+ materialName,
36
+ refreshProjectImports: options.refreshProjectImports,
37
+ });
38
+ });
39
+
40
+ program
41
+ .command("update-version")
42
+ .description("Update flowgram version in the project")
43
+ .argument("[string]", "Flowgram version")
44
+ .action(async (version) => {
45
+ await updateFlowgramVersion(version);
30
46
  });
31
47
 
32
48
  program.parse(process.argv);
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { getLatestVersion } from "../utils/npm";
7
+ import { traverseRecursiveFiles } from "../utils/file";
8
+ import chalk from "chalk";
9
+
10
+ export async function updateFlowgramVersion(inputVersion?: string) {
11
+ console.log(chalk.bold("🚀 Welcome to @flowgram.ai update-version helper"));
12
+
13
+ // Get latest version
14
+ const latestVersion = await getLatestVersion("@flowgram.ai/editor");
15
+ const currentPath = process.cwd();
16
+ console.log("- Latest flowgram version: ", latestVersion);
17
+ console.log("- Current Path: ", currentPath);
18
+
19
+ // User Input flowgram version, default is latestVersion
20
+ const flowgramVersion: string = inputVersion || latestVersion;
21
+
22
+ for (const file of traverseRecursiveFiles(currentPath)) {
23
+ if (file.path.endsWith("package.json")) {
24
+ console.log("👀 Find package.json: ", file.path);
25
+ let updated = false;
26
+ const json = JSON.parse(file.content);
27
+ if (json.dependencies) {
28
+ for (const key in json.dependencies) {
29
+ if (key.startsWith("@flowgram.ai/")) {
30
+ updated = true;
31
+ json.dependencies[key] = flowgramVersion;
32
+ console.log(`- Update ${key} to ${flowgramVersion}`);
33
+ }
34
+ }
35
+ }
36
+ if (json.devDependencies) {
37
+ for (const key in json.devDependencies) {
38
+ if (key.startsWith("@flowgram.ai/")) {
39
+ updated = true;
40
+ json.devDependencies[key] = flowgramVersion;
41
+ console.log(`- Update ${key} to ${flowgramVersion}`);
42
+ }
43
+ }
44
+ }
45
+
46
+ if (updated) {
47
+ file.write(JSON.stringify(json, null, 2));
48
+ console.log(`✅ ${file.path} Updated`);
49
+ }
50
+ }
51
+ }
52
+ }
package/src/utils/file.ts CHANGED
@@ -3,8 +3,9 @@
3
3
  * SPDX-License-Identifier: MIT
4
4
  */
5
5
 
6
- import path from 'path';
7
- import fs from 'fs';
6
+ import path from "path";
7
+ import fs from "fs";
8
+ import ignore, { Ignore } from "ignore";
8
9
 
9
10
  export class File {
10
11
  content: string;
@@ -17,7 +18,7 @@ export class File {
17
18
 
18
19
  suffix: string;
19
20
 
20
- constructor(filePath: string, public root: string = '/') {
21
+ constructor(filePath: string, public root: string = "/") {
21
22
  this.path = filePath;
22
23
  this.relativePath = path.relative(this.root, this.path);
23
24
  this.suffix = path.extname(this.path);
@@ -29,7 +30,7 @@ export class File {
29
30
 
30
31
  // If no utf-8, skip
31
32
  try {
32
- this.content = fs.readFileSync(this.path, 'utf-8');
33
+ this.content = fs.readFileSync(this.path, "utf-8");
33
34
  this.isUtf8 = true;
34
35
  } catch (e) {
35
36
  this.isUtf8 = false;
@@ -39,22 +40,48 @@ export class File {
39
40
 
40
41
  replace(updater: (content: string) => string) {
41
42
  if (!this.isUtf8) {
42
- console.warn('Not UTF-8 file skipped: ', this.path);
43
+ console.warn("Not UTF-8 file skipped: ", this.path);
43
44
  return;
44
45
  }
45
46
  this.content = updater(this.content);
46
- fs.writeFileSync(this.path, this.content, 'utf-8');
47
+ fs.writeFileSync(this.path, this.content, "utf-8");
48
+ }
49
+
50
+ write(nextContent: string) {
51
+ this.content = nextContent;
52
+ fs.writeFileSync(this.path, this.content, "utf-8");
47
53
  }
48
54
  }
49
55
 
50
- export function* traverseRecursiveFiles(folder: string): Generator<File> {
56
+ export function* traverseRecursiveFilePaths(
57
+ folder: string,
58
+ ig: Ignore = ignore().add(".git"),
59
+ root: string = folder,
60
+ ): Generator<string> {
51
61
  const files = fs.readdirSync(folder);
62
+
63
+ // add .gitignore to ignore if exists
64
+ if (fs.existsSync(path.join(folder, ".gitignore"))) {
65
+ ig.add(fs.readFileSync(path.join(folder, ".gitignore"), "utf-8"));
66
+ }
67
+
52
68
  for (const file of files) {
53
69
  const filePath = path.join(folder, file);
70
+
71
+ if (ig.ignores(path.relative(root, filePath))) {
72
+ continue;
73
+ }
74
+
54
75
  if (fs.statSync(filePath).isDirectory()) {
55
- yield* traverseRecursiveFiles(filePath);
76
+ yield* traverseRecursiveFilePaths(filePath, ig, root);
56
77
  } else {
57
- yield new File(filePath);
78
+ yield filePath;
58
79
  }
59
80
  }
60
81
  }
82
+
83
+ export function* traverseRecursiveFiles(folder: string): Generator<File> {
84
+ for (const filePath of traverseRecursiveFilePaths(folder)) {
85
+ yield new File(filePath);
86
+ }
87
+ }
@@ -89,6 +89,13 @@ export class Project {
89
89
  }
90
90
  }
91
91
 
92
+ writeToPackageJsonFile() {
93
+ writeFileSync(
94
+ this.packageJsonPath,
95
+ JSON.stringify(this.packageJson, null, 2),
96
+ );
97
+ }
98
+
92
99
  printInfo() {
93
100
  console.log(chalk.bold("Project Info:"));
94
101
  console.log(chalk.black(` - Flowgram Version: ${this.flowgramVersion}`));
@@ -5,7 +5,7 @@
5
5
 
6
6
  import path from "path";
7
7
  import fs from "fs";
8
- import { File } from "./file";
8
+ import { File, traverseRecursiveFilePaths } from "./file";
9
9
  import { extractNamedExports } from "./export";
10
10
  import {
11
11
  assembleImport,
@@ -109,15 +109,9 @@ class TsFile extends File {
109
109
  }
110
110
 
111
111
  export function* traverseRecursiveTsFiles(folder: string): Generator<TsFile> {
112
- const files = fs.readdirSync(folder);
113
- for (const file of files) {
114
- const filePath = path.join(folder, file);
115
- if (fs.statSync(filePath).isDirectory()) {
116
- yield* traverseRecursiveTsFiles(filePath);
117
- } else {
118
- if (file.endsWith(".ts") || file.endsWith(".tsx")) {
119
- yield new TsFile(filePath);
120
- }
112
+ for (const filePath of traverseRecursiveFilePaths(folder)) {
113
+ if (filePath.endsWith(".ts") || filePath.endsWith(".tsx")) {
114
+ yield new TsFile(filePath);
121
115
  }
122
116
  }
123
117
  }