@flowgram.ai/form-materials 0.1.0-alpha.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.
Files changed (100) hide show
  1. package/bin/index.ts +99 -0
  2. package/bin/materials.ts +156 -0
  3. package/bin/project.ts +91 -0
  4. package/dist/esm/index.js +3303 -0
  5. package/dist/esm/index.js.map +1 -0
  6. package/dist/index.d.mts +495 -0
  7. package/dist/index.d.ts +495 -0
  8. package/dist/index.js +3299 -0
  9. package/dist/index.js.map +1 -0
  10. package/package.json +75 -0
  11. package/src/components/batch-outputs/config.json +12 -0
  12. package/src/components/batch-outputs/index.tsx +61 -0
  13. package/src/components/batch-outputs/styles.tsx +19 -0
  14. package/src/components/batch-outputs/types.ts +22 -0
  15. package/src/components/batch-outputs/use-list.ts +86 -0
  16. package/src/components/batch-variable-selector/config.json +5 -0
  17. package/src/components/batch-variable-selector/index.tsx +24 -0
  18. package/src/components/code-editor/config.json +9 -0
  19. package/src/components/code-editor/index.tsx +74 -0
  20. package/src/components/code-editor/language-features.ts +24 -0
  21. package/src/components/code-editor/theme/dark.ts +119 -0
  22. package/src/components/code-editor/theme/index.ts +12 -0
  23. package/src/components/code-editor/theme/light.ts +119 -0
  24. package/src/components/code-editor/utils.ts +20 -0
  25. package/src/components/condition-row/config.json +5 -0
  26. package/src/components/condition-row/constants.ts +128 -0
  27. package/src/components/condition-row/hooks/useOp.tsx +50 -0
  28. package/src/components/condition-row/hooks/useRule.ts +31 -0
  29. package/src/components/condition-row/index.tsx +81 -0
  30. package/src/components/condition-row/styles.tsx +30 -0
  31. package/src/components/condition-row/types.ts +42 -0
  32. package/src/components/constant-input/config.json +6 -0
  33. package/src/components/constant-input/index.tsx +86 -0
  34. package/src/components/constant-input/types.ts +23 -0
  35. package/src/components/dynamic-value-input/config.json +5 -0
  36. package/src/components/dynamic-value-input/index.tsx +92 -0
  37. package/src/components/dynamic-value-input/styles.tsx +26 -0
  38. package/src/components/index.ts +18 -0
  39. package/src/components/json-editor-with-variables/config.json +13 -0
  40. package/src/components/json-editor-with-variables/extensions/variable-tag.tsx +173 -0
  41. package/src/components/json-editor-with-variables/extensions/variable-tree.tsx +83 -0
  42. package/src/components/json-editor-with-variables/index.tsx +19 -0
  43. package/src/components/json-editor-with-variables/styles.tsx +44 -0
  44. package/src/components/json-schema-editor/components/blur-input.tsx +27 -0
  45. package/src/components/json-schema-editor/config.json +13 -0
  46. package/src/components/json-schema-editor/default-value.tsx +135 -0
  47. package/src/components/json-schema-editor/hooks.tsx +166 -0
  48. package/src/components/json-schema-editor/index.tsx +267 -0
  49. package/src/components/json-schema-editor/styles.tsx +240 -0
  50. package/src/components/json-schema-editor/types.ts +26 -0
  51. package/src/components/json-schema-editor/utils.ts +29 -0
  52. package/src/components/prompt-editor/config.json +9 -0
  53. package/src/components/prompt-editor/extensions/jinja.tsx +58 -0
  54. package/src/components/prompt-editor/extensions/language-support.tsx +19 -0
  55. package/src/components/prompt-editor/extensions/markdown.tsx +75 -0
  56. package/src/components/prompt-editor/index.tsx +68 -0
  57. package/src/components/prompt-editor/styles.tsx +18 -0
  58. package/src/components/prompt-editor/types.tsx +18 -0
  59. package/src/components/prompt-editor-with-inputs/config.json +13 -0
  60. package/src/components/prompt-editor-with-inputs/extensions/inputs-tree.tsx +82 -0
  61. package/src/components/prompt-editor-with-inputs/index.tsx +22 -0
  62. package/src/components/prompt-editor-with-inputs/inputs-picker.tsx +100 -0
  63. package/src/components/prompt-editor-with-variables/config.json +13 -0
  64. package/src/components/prompt-editor-with-variables/extensions/variable-tag.tsx +179 -0
  65. package/src/components/prompt-editor-with-variables/extensions/variable-tree.tsx +83 -0
  66. package/src/components/prompt-editor-with-variables/index.tsx +19 -0
  67. package/src/components/prompt-editor-with-variables/styles.tsx +44 -0
  68. package/src/components/type-selector/config.json +5 -0
  69. package/src/components/type-selector/constants.tsx +364 -0
  70. package/src/components/type-selector/index.tsx +62 -0
  71. package/src/components/variable-selector/config.json +5 -0
  72. package/src/components/variable-selector/index.tsx +116 -0
  73. package/src/components/variable-selector/styles.tsx +59 -0
  74. package/src/components/variable-selector/use-variable-tree.tsx +103 -0
  75. package/src/effects/auto-rename-ref/config.json +5 -0
  76. package/src/effects/auto-rename-ref/index.ts +109 -0
  77. package/src/effects/index.ts +10 -0
  78. package/src/effects/provide-batch-input/config.json +5 -0
  79. package/src/effects/provide-batch-input/index.ts +43 -0
  80. package/src/effects/provide-batch-outputs/config.json +5 -0
  81. package/src/effects/provide-batch-outputs/index.ts +38 -0
  82. package/src/effects/provide-json-schema-outputs/config.json +8 -0
  83. package/src/effects/provide-json-schema-outputs/index.ts +28 -0
  84. package/src/effects/sync-variable-title/config.json +5 -0
  85. package/src/effects/sync-variable-title/index.ts +28 -0
  86. package/src/form-plugins/batch-outputs-plugin/config.json +7 -0
  87. package/src/form-plugins/batch-outputs-plugin/index.ts +104 -0
  88. package/src/form-plugins/index.ts +6 -0
  89. package/src/index.ts +10 -0
  90. package/src/typings/flow-value/config.json +5 -0
  91. package/src/typings/flow-value/index.ts +32 -0
  92. package/src/typings/index.ts +7 -0
  93. package/src/typings/json-schema/config.json +5 -0
  94. package/src/typings/json-schema/index.ts +36 -0
  95. package/src/utils/format-legacy-refs/config.json +5 -0
  96. package/src/utils/format-legacy-refs/index.ts +158 -0
  97. package/src/utils/format-legacy-refs/readme.md +38 -0
  98. package/src/utils/index.ts +7 -0
  99. package/src/utils/json-schema/config.json +5 -0
  100. package/src/utils/json-schema/index.ts +180 -0
package/bin/index.ts ADDED
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env -S npx tsx@latest
2
+
3
+ import inquirer from 'inquirer';
4
+ import { Command } from 'commander';
5
+ import chalk from 'chalk';
6
+
7
+ import { getProjectInfo, installDependencies, ProjectInfo } from './project.js';
8
+ import { bfsMaterials, copyMaterial, listAllMaterials, Material } from './materials.js';
9
+
10
+ const program = new Command();
11
+
12
+ program
13
+ .version('1.0.1')
14
+ .description('Add official materials to your project')
15
+ .argument('[materialName]', 'Optional material name to skip selection (format: type/name)')
16
+ .action(async (materialName?: string) => {
17
+ // materialName can be undefined
18
+ console.log(chalk.bgGreenBright('Welcome to @flowgram.ai/form-materials CLI!'));
19
+
20
+ const projectInfo: ProjectInfo = getProjectInfo();
21
+
22
+ console.log(chalk.bold('Project Info:'));
23
+ console.log(chalk.black(` - Flowgram Version: ${projectInfo.flowgramVersion}`));
24
+ console.log(chalk.black(` - Project Path: ${projectInfo.projectPath}`));
25
+
26
+ const materials: Material[] = listAllMaterials();
27
+
28
+ let material: Material | undefined; // material can be undefined
29
+
30
+ // Check if materialName is provided and exists in materials
31
+ if (materialName) {
32
+ const selectedMaterial = materials.find((m) => `${m.type}/${m.name}` === materialName);
33
+ if (selectedMaterial) {
34
+ material = selectedMaterial;
35
+ console.log(chalk.green(`Using material: ${materialName}`));
36
+ } else {
37
+ console.log(
38
+ chalk.yellow(`Material "${materialName}" not found. Please select from the list:`)
39
+ );
40
+ }
41
+ }
42
+
43
+ // If material not found or materialName not provided, prompt user to select
44
+ if (!material) {
45
+ // User select one component
46
+ const result = await inquirer.prompt<{
47
+ material: Material; // Specify type for prompt result
48
+ }>([
49
+ {
50
+ type: 'list',
51
+ name: 'material',
52
+ message: 'Select one material to add:',
53
+ choices: [
54
+ ...materials.map((_material) => ({
55
+ name: `${_material.type}/${_material.name}`,
56
+ value: _material,
57
+ })),
58
+ ],
59
+ },
60
+ ]);
61
+ material = result.material;
62
+ }
63
+ // Ensure material is defined before proceeding
64
+ if (!material) {
65
+ console.error(chalk.red('No material selected. Exiting.'));
66
+ process.exit(1);
67
+ }
68
+
69
+ console.log(material);
70
+
71
+ // 3. Get the component dependencies by BFS (include depMaterials and depPackages)
72
+ const { allMaterials, allPackages } = bfsMaterials(material!, materials);
73
+
74
+ // 4. Install the dependencies
75
+ let flowgramPackage = `@flowgram.ai/editor`;
76
+ if (projectInfo.flowgramVersion !== 'workspace:*') {
77
+ flowgramPackage = `@flowgram.ai/editor@${projectInfo.flowgramVersion}`;
78
+ }
79
+ const packagesToInstall: string[] = [flowgramPackage, ...allPackages];
80
+
81
+ console.log(chalk.bold('These npm dependencies will be added to your project'));
82
+ console.log(packagesToInstall);
83
+ installDependencies(packagesToInstall, projectInfo);
84
+
85
+ // 5. Copy the materials to the project
86
+ console.log(chalk.bold('These Materials will be added to your project'));
87
+ console.log(allMaterials);
88
+ copyMaterial(material, projectInfo, { overwrite: true });
89
+
90
+ allMaterials.forEach((mat: Material) => {
91
+ if (mat === material) {
92
+ return;
93
+ }
94
+ // Add type for mat
95
+ copyMaterial(mat, projectInfo, { overwrite: false });
96
+ });
97
+ });
98
+
99
+ program.parse(process.argv);
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { fileURLToPath } from 'url';
7
+ import path from 'path';
8
+ import fs from 'fs';
9
+
10
+ import { ProjectInfo } from './project'; // Import ProjectInfo
11
+
12
+ const __filename = fileURLToPath(import.meta.url);
13
+ const __dirname = path.dirname(__filename);
14
+
15
+ // Added type definitions
16
+ export interface Material {
17
+ name: string;
18
+ type: string;
19
+ path: string;
20
+ depPackages?: string[];
21
+ depMaterials?: string[];
22
+ [key: string]: any; // For other properties from config.json
23
+ }
24
+
25
+ const _types: string[] = ['components', 'effects', 'utils', 'typings', 'form-plugins'];
26
+
27
+ export function listAllMaterials(): Material[] {
28
+ const _materials: Material[] = [];
29
+
30
+ for (const _type of _types) {
31
+ // 在 Node.js 中,import.meta.dirname 不可用,可使用 import.meta.url 结合 url 模块来获取目录路径
32
+
33
+ const materialsPath: string = path.join(__dirname, '..', 'src', _type);
34
+ _materials.push(
35
+ ...fs
36
+ .readdirSync(materialsPath)
37
+ .map((_path: string) => {
38
+ if (_path === 'index.ts') {
39
+ return null;
40
+ }
41
+
42
+ const configPath = path.join(materialsPath, _path, 'config.json');
43
+ // Check if config.json exists before reading
44
+ if (!fs.existsSync(configPath)) {
45
+ console.warn(
46
+ `Warning: config.json not found for material at ${path.join(materialsPath, _path)}`
47
+ );
48
+ return null;
49
+ }
50
+ const configContent = fs.readFileSync(configPath, 'utf8');
51
+ const config = JSON.parse(configContent);
52
+
53
+ return {
54
+ ...config,
55
+ name: _path, // Assuming the folder name is the material name
56
+ type: _type,
57
+ path: path.join(materialsPath, _path),
58
+ } as Material;
59
+ })
60
+ .filter((material): material is Material => material !== null)
61
+ );
62
+ }
63
+
64
+ return _materials;
65
+ }
66
+
67
+ interface BfsResult {
68
+ allMaterials: Material[];
69
+ allPackages: string[];
70
+ }
71
+
72
+ export function bfsMaterials(material: Material, _materials: Material[] = []): BfsResult {
73
+ function findConfigByName(name: string): Material | undefined {
74
+ return _materials.find(
75
+ (_config) => _config.name === name || `${_config.type}/${_config.name}` === name
76
+ );
77
+ }
78
+
79
+ const queue: (Material | undefined)[] = [material]; // Queue can hold undefined if findConfigByName returns undefined
80
+ const allMaterials = new Set<Material>();
81
+ const allPackages = new Set<string>();
82
+
83
+ while (queue.length > 0) {
84
+ const _material = queue.shift();
85
+ if (!_material || allMaterials.has(_material)) {
86
+ // Check if _material is defined
87
+ continue;
88
+ }
89
+ allMaterials.add(_material);
90
+
91
+ if (_material.depPackages) {
92
+ for (const _package of _material.depPackages) {
93
+ allPackages.add(_package);
94
+ }
95
+ }
96
+
97
+ if (_material.depMaterials) {
98
+ for (const _materialName of _material.depMaterials) {
99
+ const depMaterial = findConfigByName(_materialName);
100
+ if (depMaterial) {
101
+ // Ensure dependent material is found before adding to queue
102
+ queue.push(depMaterial);
103
+ } else {
104
+ console.warn(
105
+ `Warning: Dependent material "${_materialName}" not found for material "${_material.name}".`
106
+ );
107
+ }
108
+ }
109
+ }
110
+ }
111
+
112
+ return {
113
+ allMaterials: Array.from(allMaterials),
114
+ allPackages: Array.from(allPackages),
115
+ };
116
+ }
117
+
118
+ export const copyMaterial = (
119
+ material: Material,
120
+ projectInfo: ProjectInfo,
121
+ {
122
+ overwrite,
123
+ }: {
124
+ overwrite?: boolean;
125
+ } = {}
126
+ ): void => {
127
+ const sourceDir: string = material.path;
128
+ const materialRoot: string = path.join(
129
+ projectInfo.projectPath,
130
+ 'src',
131
+ 'form-materials',
132
+ `${material.type}`
133
+ );
134
+ const targetDir = path.join(materialRoot, material.name);
135
+
136
+ if (!overwrite && fs.readdirSync(targetDir)?.length > 0) {
137
+ console.log(`Material ${material.name} already exists in ${materialRoot}, skip copying.`);
138
+ return;
139
+ }
140
+
141
+ fs.cpSync(sourceDir, targetDir, { recursive: true });
142
+
143
+ let materialRootIndexTs: string = '';
144
+ const indexTsPath = path.join(materialRoot, 'index.ts');
145
+ if (fs.existsSync(indexTsPath)) {
146
+ materialRootIndexTs = fs.readFileSync(indexTsPath, 'utf8');
147
+ }
148
+ if (!materialRootIndexTs.includes(material.name)) {
149
+ fs.writeFileSync(
150
+ indexTsPath,
151
+ `${materialRootIndexTs}${materialRootIndexTs.endsWith('\n') ? '' : '\n'}export * from './${
152
+ material.name
153
+ }';\n`
154
+ );
155
+ }
156
+ };
package/bin/project.ts ADDED
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import path from 'path';
7
+ import fs from 'fs';
8
+ import { execSync } from 'child_process';
9
+
10
+ // Added type definitions
11
+ interface PackageJson {
12
+ dependencies: { [key: string]: string };
13
+ devDependencies?: { [key: string]: string };
14
+ peerDependencies?: { [key: string]: string };
15
+ [key: string]: any;
16
+ }
17
+
18
+ export interface ProjectInfo {
19
+ projectPath: string;
20
+ packageJsonPath: string;
21
+ packageJson: PackageJson;
22
+ flowgramVersion: string;
23
+ }
24
+
25
+ export function getProjectInfo(): ProjectInfo {
26
+ // get nearest package.json
27
+ let projectPath: string = process.cwd();
28
+
29
+ while (projectPath !== '/' && !fs.existsSync(path.join(projectPath, 'package.json'))) {
30
+ projectPath = path.join(projectPath, '..');
31
+ }
32
+
33
+ if (projectPath === '/') {
34
+ throw new Error('Please run this command in a valid project');
35
+ }
36
+
37
+ const packageJsonPath: string = path.join(projectPath, 'package.json');
38
+ const packageJson: PackageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
39
+
40
+ // fixed layout or free layout
41
+ const flowgramVersion: string | undefined =
42
+ packageJson.dependencies['@flowgram.ai/fixed-layout-editor'] ||
43
+ packageJson.dependencies['@flowgram.ai/free-layout-editor'] ||
44
+ packageJson.dependencies['@flowgram.ai/editor'];
45
+
46
+ if (!flowgramVersion) {
47
+ throw new Error(
48
+ 'Please install @flowgram.ai/fixed-layout-editor or @flowgram.ai/free-layout-editor'
49
+ );
50
+ }
51
+
52
+ return {
53
+ projectPath,
54
+ packageJsonPath,
55
+ packageJson,
56
+ flowgramVersion, // TypeScript will ensure this is string due to the check above
57
+ };
58
+ }
59
+
60
+ export function findRushJson(startPath: string): string | null {
61
+ let currentPath: string = startPath;
62
+ while (currentPath !== '/' && !fs.existsSync(path.join(currentPath, 'rush.json'))) {
63
+ currentPath = path.join(currentPath, '..');
64
+ }
65
+ if (fs.existsSync(path.join(currentPath, 'rush.json'))) {
66
+ return path.join(currentPath, 'rush.json');
67
+ }
68
+ return null;
69
+ }
70
+
71
+ export function installDependencies(packages: string[], projectInfo: ProjectInfo): void {
72
+ if (fs.existsSync(path.join(projectInfo.projectPath, 'yarn.lock'))) {
73
+ execSync(`yarn add ${packages.join(' ')}`, { stdio: 'inherit' });
74
+ return;
75
+ }
76
+
77
+ if (fs.existsSync(path.join(projectInfo.projectPath, 'pnpm-lock.yaml'))) {
78
+ execSync(`pnpm add ${packages.join(' ')}`, { stdio: 'inherit' });
79
+ return;
80
+ }
81
+
82
+ // rush monorepo
83
+ if (findRushJson(projectInfo.projectPath)) {
84
+ execSync(`rush add ${packages.map((pkg) => `--package ${pkg}`).join(' ')}`, {
85
+ stdio: 'inherit',
86
+ });
87
+ return;
88
+ }
89
+
90
+ execSync(`npm install ${packages.join(' ')}`, { stdio: 'inherit' });
91
+ }