@futurebrand/dev-tools 2.5.2 → 2.5.4

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.
@@ -19,28 +19,52 @@ const addCommand = new commander_1.Command('add')
19
19
  return;
20
20
  }
21
21
  const isAll = options.all === true;
22
- const choices = state.getAvailableBlocksNames({
23
- hidden: isAll ? undefined : false,
24
- generated: true,
25
- });
26
- if (!choices.length) {
27
- console.error('No blocks available to add');
28
- return;
29
- }
30
- const blockQuery = await inquirer_1.default.prompt([
22
+ const projects = state
23
+ .getData()
24
+ .projects.filter((p) => p.type === 'strapi' || p.type === 'next.js');
25
+ const userQuery = await inquirer_1.default.prompt([
26
+ {
27
+ type: 'select',
28
+ name: 'project',
29
+ message: 'Select the project to generate',
30
+ choices: projects.map((p) => ({
31
+ name: `${p.name} (${p.type})`,
32
+ value: p.name,
33
+ })),
34
+ },
31
35
  {
32
36
  type: 'select',
33
37
  name: 'block',
34
38
  message: 'Select the block to add',
35
- choices,
39
+ choices: async ({ project }) => {
40
+ const projectData = projects.find((p) => p.name === project);
41
+ if (!projectData) {
42
+ return [];
43
+ }
44
+ const allBlocks = state.getAvailableBlocks({
45
+ hidden: false,
46
+ });
47
+ const toGenerateBlocks = isAll
48
+ ? allBlocks
49
+ : await state.file.getAvailableBlocksToAdd(allBlocks, projectData);
50
+ if (!toGenerateBlocks.length) {
51
+ throw new Error('No blocks available to generate');
52
+ }
53
+ return toGenerateBlocks.map((block) => block.name).sort();
54
+ },
36
55
  },
37
56
  ]);
38
- const blocksToAdd = blockQuery.block;
57
+ const blocksToAdd = userQuery.block;
39
58
  if (!blocksToAdd) {
40
59
  console.error('No blocks selected');
41
60
  return;
42
61
  }
62
+ const project = projects.find((p) => p.name === userQuery.project);
63
+ if (!project) {
64
+ console.error('No project selected');
65
+ return;
66
+ }
43
67
  const projectAdder = new project_adder_1.default(state);
44
- await projectAdder.addBlock(blocksToAdd);
68
+ await projectAdder.addBlock(blocksToAdd, project);
45
69
  });
46
70
  exports.default = addCommand;
@@ -18,31 +18,53 @@ const generateCommand = new commander_1.Command('generate')
18
18
  return;
19
19
  }
20
20
  const isAll = options.all === true;
21
- const choices = state.getAvailableBlocksNames(isAll
22
- ? {}
23
- : {
24
- hidden: false,
25
- generated: false,
26
- });
27
- if (!choices.length) {
28
- console.error('No blocks available to generate');
29
- return;
30
- }
31
- const blockQuery = await inquirer_1.default.prompt([
21
+ const projects = state
22
+ .getData()
23
+ .projects.filter((p) => p.type === 'strapi' || p.type === 'next.js');
24
+ const userQuery = await inquirer_1.default.prompt([
25
+ {
26
+ type: 'select',
27
+ name: 'project',
28
+ message: 'Select the project to generate',
29
+ choices: projects.map((p) => ({
30
+ name: `${p.name} (${p.type})`,
31
+ value: p.name,
32
+ })),
33
+ },
32
34
  {
33
35
  type: 'checkbox',
34
36
  name: 'blocks',
35
37
  message: 'Select the blocks to generate',
36
- choices,
38
+ choices: async ({ project }) => {
39
+ const projectData = projects.find((p) => p.name === project);
40
+ if (!projectData) {
41
+ return [];
42
+ }
43
+ const allBlocks = state.getAvailableBlocks({
44
+ hidden: false,
45
+ });
46
+ const toGenerateBlocks = isAll
47
+ ? allBlocks
48
+ : await state.file.getAvailableBlocksToGenerate(allBlocks, projectData);
49
+ if (!toGenerateBlocks.length) {
50
+ throw new Error('No blocks available to generate');
51
+ }
52
+ return toGenerateBlocks.map((block) => block.name).sort();
53
+ },
37
54
  },
38
55
  ]);
39
- const blocksToGenerate = blockQuery.blocks;
56
+ const blocksToGenerate = userQuery.blocks;
40
57
  if (!blocksToGenerate.length) {
41
58
  console.error('No blocks selected');
42
59
  return;
43
60
  }
61
+ const project = projects.find((p) => p.name === userQuery.project);
62
+ if (!project) {
63
+ console.error('No project selected');
64
+ return;
65
+ }
44
66
  const generator = new generator_1.Generator(state);
45
- await generator.generateBlocks(blocksToGenerate);
67
+ await generator.generateBlocks(blocksToGenerate, project);
46
68
  });
47
69
  const generateStyleCommand = new commander_1.Command('styles')
48
70
  .alias('style')
@@ -11,7 +11,7 @@ class FigmaAPI {
11
11
  return id;
12
12
  }
13
13
  async getVariables(pageId) {
14
- const { variables } = await this.state.fetchApi(`/figma/${pageId}/blocks`);
14
+ const { variables } = await this.state.fetchApi(`/figma/${pageId}/variables`);
15
15
  return variables;
16
16
  }
17
17
  async getBlocks(pageId, canvasId) {
@@ -1,9 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const path = require("node:path");
4
- const files_1 = require("../../../../utils/files");
5
3
  const inquirer_1 = require("inquirer");
6
- const generator_1 = require("../generator");
7
4
  const api_1 = require("./api");
8
5
  class FigmaModule {
9
6
  state;
@@ -25,24 +22,16 @@ class FigmaModule {
25
22
  async getDefaultCheckedBlocks(blocks) {
26
23
  const data = this.state.getData();
27
24
  const defaultBlocks = [];
28
- const currentBlocks = data.blocks;
29
25
  const nextProject = data.projects.find((project) => project.type === 'next.js');
30
26
  for (const block of blocks) {
31
- const inCurrentBlocks = currentBlocks.find((b) => b.name === block.name);
32
- if (inCurrentBlocks) {
33
- block.hidden = inCurrentBlocks.hidden;
34
- block.generated = inCurrentBlocks.generated;
35
- }
36
- else {
37
- const tempFolder = await (0, files_1.getTempFilePath)(generator_1.GENERATOR_FOLDER_NAME, block.name);
38
- if (await (0, files_1.verifyPath)(tempFolder)) {
39
- block.generated = true;
27
+ if (nextProject) {
28
+ const alreadyGenerated = await this.state.file.verifyBlockAlreadyGenerated(block.name, nextProject);
29
+ if (alreadyGenerated) {
30
+ continue;
40
31
  }
41
- if (nextProject) {
42
- const blockFolder = path.join(nextProject.path, 'layouts', 'blocks', block.name);
43
- if (await (0, files_1.verifyPath)(blockFolder)) {
44
- block.hidden = true;
45
- }
32
+ const alreadyExist = await this.state.file.verifyBlockAlreadyExists(nextProject, block.name);
33
+ if (alreadyExist) {
34
+ continue;
46
35
  }
47
36
  }
48
37
  if (!block.hidden) {
@@ -0,0 +1,22 @@
1
+ import type { IProject } from '../../../../types/project';
2
+ import type { IBlockData } from '../state/types';
3
+ export declare const GENERATOR_FOLDER_NAME = "generated-blocks";
4
+ export declare const GENERATOR_STRAPI_FILE_NAME = "strapi.json";
5
+ export declare const GENERATOR_NEXTJS_FILE_NAME = "nextjs.tsx";
6
+ declare class FileManager {
7
+ private getBlockTempPath;
8
+ private getBlockTempFilePath;
9
+ private getStrapiFolders;
10
+ private getNextjsBlockFolder;
11
+ private getBlockPath;
12
+ verifyBlockAlreadyGenerated(blockName: string, project: IProject): Promise<boolean>;
13
+ verifyBlockAlreadyExists(project: IProject, blockName: string): Promise<boolean>;
14
+ getAvailableBlocksToGenerate(blocks: IBlockData[], project: IProject): Promise<IBlockData[]>;
15
+ getAvailableBlocksToAdd(blocks: IBlockData[], project: IProject): Promise<IBlockData[]>;
16
+ createBlockTempFolder(blockName: string): Promise<void>;
17
+ saveGeneratedBlock(blockName: string, project: IProject, content: any): Promise<void>;
18
+ loadGeneratedBlock(blockName: string, project: IProject): Promise<string>;
19
+ addNextBlockToProject(blockName: string, project: IProject): Promise<void>;
20
+ addStrapiBlockToProject(blockName: string, project: IProject): Promise<void>;
21
+ }
22
+ export default FileManager;
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GENERATOR_NEXTJS_FILE_NAME = exports.GENERATOR_STRAPI_FILE_NAME = exports.GENERATOR_FOLDER_NAME = void 0;
4
+ const fs = require("node:fs/promises");
5
+ const path = require("node:path");
6
+ const files_1 = require("../../../../utils/files");
7
+ exports.GENERATOR_FOLDER_NAME = 'generated-blocks';
8
+ exports.GENERATOR_STRAPI_FILE_NAME = 'strapi.json';
9
+ exports.GENERATOR_NEXTJS_FILE_NAME = 'nextjs.tsx';
10
+ class FileManager {
11
+ async getBlockTempPath(blockName) {
12
+ const tempFolder = await (0, files_1.getTempFilePath)(exports.GENERATOR_FOLDER_NAME, blockName);
13
+ await (0, files_1.verifyAndCreateFolder)(tempFolder);
14
+ return tempFolder;
15
+ }
16
+ async getBlockTempFilePath(project, blockName) {
17
+ const tempFolder = await this.getBlockTempPath(blockName);
18
+ const projectType = typeof project === 'string' ? project : project.type;
19
+ if (projectType === 'strapi') {
20
+ return path.join(tempFolder, exports.GENERATOR_STRAPI_FILE_NAME);
21
+ }
22
+ if (projectType === 'next.js') {
23
+ return path.join(tempFolder, exports.GENERATOR_NEXTJS_FILE_NAME);
24
+ }
25
+ throw new Error(`Unsupported project type: ${projectType}`);
26
+ }
27
+ getStrapiFolders(project) {
28
+ if (project.type !== 'strapi') {
29
+ throw new Error('Project is not a Strapi project');
30
+ }
31
+ const srcPath = project.srcPath || path.join(project.path, 'src');
32
+ const componentsFolder = path.join(srcPath, 'components');
33
+ const blocksFolder = path.join(componentsFolder, 'blocks');
34
+ const blocksAssetsFolder = path.join(componentsFolder, 'blocks-assets');
35
+ return {
36
+ blocks: blocksFolder,
37
+ assets: blocksAssetsFolder,
38
+ };
39
+ }
40
+ getNextjsBlockFolder(project, blockName) {
41
+ if (project.type !== 'next.js') {
42
+ throw new Error('Project is not a Next.js project');
43
+ }
44
+ const blockFolder = path.join(project.srcPath || project.path, 'layouts', 'blocks', blockName);
45
+ return blockFolder;
46
+ }
47
+ getBlockPath(project, blockName) {
48
+ if (project.type === 'strapi') {
49
+ const folders = this.getStrapiFolders(project);
50
+ const jsonName = blockName.replace('block-', '');
51
+ return path.join(folders.blocks, `${jsonName}.json`);
52
+ }
53
+ if (project.type === 'next.js') {
54
+ const blockFolder = this.getNextjsBlockFolder(project, blockName);
55
+ return path.join(blockFolder, `${blockName}.tsx`);
56
+ }
57
+ throw new Error(`Unsupported project type: ${project.type}`);
58
+ }
59
+ async verifyBlockAlreadyGenerated(blockName, project) {
60
+ const blockPath = await this.getBlockTempFilePath(project, blockName);
61
+ return await (0, files_1.verifyPath)(blockPath);
62
+ }
63
+ async verifyBlockAlreadyExists(project, blockName) {
64
+ const blockPath = this.getBlockPath(project, blockName);
65
+ return await (0, files_1.verifyPath)(blockPath);
66
+ }
67
+ async getAvailableBlocksToGenerate(blocks, project) {
68
+ const toGenerateBlocks = [];
69
+ for (const block of blocks) {
70
+ const alreadyExists = await this.verifyBlockAlreadyExists(project, block.name);
71
+ if (alreadyExists) {
72
+ continue;
73
+ }
74
+ const alreadyGenerated = await this.verifyBlockAlreadyGenerated(block.name, project);
75
+ if (alreadyGenerated) {
76
+ continue;
77
+ }
78
+ toGenerateBlocks.push(block);
79
+ }
80
+ return toGenerateBlocks;
81
+ }
82
+ async getAvailableBlocksToAdd(blocks, project) {
83
+ const toAddBlocks = [];
84
+ for (const block of blocks) {
85
+ const alreadyExists = await this.verifyBlockAlreadyExists(project, block.name);
86
+ if (alreadyExists) {
87
+ continue;
88
+ }
89
+ const alreadyGenerated = await this.verifyBlockAlreadyGenerated(block.name, project);
90
+ if (alreadyGenerated) {
91
+ toAddBlocks.push(block);
92
+ }
93
+ }
94
+ return toAddBlocks;
95
+ }
96
+ async createBlockTempFolder(blockName) {
97
+ const tempFolder = await this.getBlockTempPath(blockName);
98
+ await (0, files_1.verifyAndCreateFolder)(tempFolder);
99
+ }
100
+ async saveGeneratedBlock(blockName, project, content) {
101
+ const blockPath = await this.getBlockTempFilePath(project, blockName);
102
+ const stringContent = typeof content === 'string' ? content : JSON.stringify(content, null, 2);
103
+ await fs.writeFile(blockPath, stringContent);
104
+ }
105
+ async loadGeneratedBlock(blockName, project) {
106
+ const blockPath = await this.getBlockTempFilePath(project, blockName);
107
+ if (!(await (0, files_1.verifyPath)(blockPath))) {
108
+ throw new Error(`Generated block not found: ${blockPath}`);
109
+ }
110
+ return (0, files_1.loadFile)(blockPath);
111
+ }
112
+ async addNextBlockToProject(blockName, project) {
113
+ if (project.type !== 'next.js') {
114
+ throw new Error('Project is not a Next.js project');
115
+ }
116
+ const generatedPath = await this.getBlockTempFilePath(project, blockName);
117
+ if (!(await (0, files_1.verifyPath)(generatedPath))) {
118
+ throw new Error(`Generated block not found: ${generatedPath}`);
119
+ }
120
+ const content = await (0, files_1.loadFile)(generatedPath);
121
+ const blockFolder = this.getNextjsBlockFolder(project, blockName);
122
+ await (0, files_1.verifyAndCreateFolder)(blockFolder);
123
+ const mainFilePath = path.join(blockFolder, `${blockName}.tsx`);
124
+ const indexFilePath = path.join(blockFolder, 'index.ts');
125
+ const indexContent = `export { default } from './${blockName}'
126
+ `;
127
+ await fs.writeFile(mainFilePath, content);
128
+ await fs.writeFile(indexFilePath, indexContent);
129
+ }
130
+ async addStrapiBlockToProject(blockName, project) {
131
+ if (project.type !== 'strapi') {
132
+ throw new Error('Project is not a Strapi project');
133
+ }
134
+ const generatedPath = await this.getBlockTempFilePath(project, blockName);
135
+ if (!(await (0, files_1.verifyPath)(generatedPath))) {
136
+ throw new Error(`Generated block not found: ${generatedPath}`);
137
+ }
138
+ const content = await (0, files_1.loadFile)(generatedPath);
139
+ const blockData = JSON.parse(content);
140
+ const folders = this.getStrapiFolders(project);
141
+ await (0, files_1.verifyAndCreateFolder)(folders.blocks);
142
+ await (0, files_1.verifyAndCreateFolder)(folders.assets);
143
+ const blockNameClean = blockName.replace('block-', '');
144
+ const blockFilePath = path.join(folders.blocks, `${blockNameClean}.json`);
145
+ await fs.writeFile(blockFilePath, JSON.stringify(blockData.block, null, 2));
146
+ for (const asset of blockData.assets || []) {
147
+ const name = asset.info?.name;
148
+ if (!name) {
149
+ throw new Error(`Asset name is missing for block: ${blockName}`);
150
+ }
151
+ const assetFilePath = path.join(folders.assets, `${name}.json`);
152
+ await fs.writeFile(assetFilePath, JSON.stringify(asset, null, 2));
153
+ }
154
+ }
155
+ }
156
+ exports.default = FileManager;
@@ -0,0 +1,4 @@
1
+ export interface IStrapiFolders {
2
+ blocks: string;
3
+ assets: string;
4
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,5 +1,6 @@
1
1
  import type { IProject } from '../../../../types/project';
2
2
  import type AIState from '../state';
3
+ import type { IStrapiGenerateResponse } from './types';
3
4
  export declare const GENERATOR_FOLDER_NAME = "generated-blocks";
4
5
  export declare const GENERATOR_STRAPI_FILE_NAME = "strapi.json";
5
6
  export declare const GENERATOR_NEXTJS_FILE_NAME = "nextjs.tsx";
@@ -7,11 +8,13 @@ export declare class Generator {
7
8
  private state;
8
9
  constructor(state: AIState);
9
10
  private get data();
10
- private generateNextBlock;
11
- private generateStrapiBlock;
11
+ private fetchNextBlock;
12
+ private fetchStrapiBlock;
12
13
  loadProjectCSS(nextProject?: IProject): Promise<string | null>;
13
- generateBlock(blockName: string, strapiProject: IProject | null | undefined, nextProject: IProject | null | undefined, styles: string | null | undefined, onGenerateCallback: () => void): Promise<void>;
14
- generateBlocks(blockNames: string[]): Promise<void>;
14
+ private generateStrapiBlock;
15
+ private generateNextBlock;
16
+ generateBlock(blockName: string, project: IProject): Promise<IStrapiGenerateResponse | undefined>;
17
+ generateBlocks(blockNames: string[], project: IProject): Promise<void>;
15
18
  generateStyles(): Promise<void>;
16
19
  generateChecklist(): Promise<void>;
17
20
  }
@@ -16,7 +16,7 @@ class Generator {
16
16
  get data() {
17
17
  return this.state.getData();
18
18
  }
19
- async generateNextBlock(blockName, blockVariants, variables, styles, strapiComponent) {
19
+ async fetchNextBlock(blockName, blockVariants, variables, styles, strapiComponent) {
20
20
  const requestBody = {
21
21
  name: blockName.replace('block-', ''),
22
22
  variants: blockVariants,
@@ -34,10 +34,9 @@ class Generator {
34
34
  if (!data.result?.block) {
35
35
  throw new Error('Next.js block generation failed');
36
36
  }
37
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
38
37
  return data.result.block;
39
38
  }
40
- async generateStrapiBlock(blockName, blockVariants) {
39
+ async fetchStrapiBlock(blockName, blockVariants) {
41
40
  const requestBody = {
42
41
  name: blockName.replace('block-', ''),
43
42
  variants: blockVariants,
@@ -52,14 +51,13 @@ class Generator {
52
51
  if (!data.result) {
53
52
  throw new Error('Strapi block generation failed');
54
53
  }
55
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
56
54
  return data.result;
57
55
  }
58
56
  async loadProjectCSS(nextProject) {
59
57
  if (!nextProject) {
60
58
  return null;
61
59
  }
62
- const cssFile = path.join(nextProject.path, 'styles', 'index.css');
60
+ const cssFile = path.join(nextProject.srcPath, 'styles', 'index.css');
63
61
  try {
64
62
  const css = await fs.readFile(cssFile, 'utf-8');
65
63
  if (!css) {
@@ -72,52 +70,53 @@ class Generator {
72
70
  return null;
73
71
  }
74
72
  }
75
- async generateBlock(blockName, strapiProject, nextProject, styles, onGenerateCallback) {
73
+ async generateStrapiBlock(blockName, project, blockVariants) {
74
+ const isAlreadyGenerated = await this.state.file.verifyBlockAlreadyGenerated(blockName, project);
75
+ if (isAlreadyGenerated) {
76
+ const content = await this.state.file.loadGeneratedBlock(blockName, project);
77
+ return JSON.parse(content);
78
+ }
79
+ const response = await this.fetchStrapiBlock(blockName, blockVariants);
80
+ await this.state.file.saveGeneratedBlock(blockName, project, response);
81
+ return response;
82
+ }
83
+ async generateNextBlock(blockName, project, blockVariants) {
84
+ const strapiProject = this.data.projects.find((p) => p.type === 'strapi');
85
+ const strapiBlock = strapiProject
86
+ ? await this.generateStrapiBlock(blockName, strapiProject, blockVariants)
87
+ : undefined;
88
+ const styles = await this.loadProjectCSS(project);
89
+ const nextResponse = await this.fetchNextBlock(blockName, blockVariants, this.data.variables, styles, strapiBlock);
90
+ await this.state.file.saveGeneratedBlock(blockName, project, nextResponse);
91
+ }
92
+ async generateBlock(blockName, project) {
76
93
  try {
77
94
  const blockVariants = this.state.getBlockVariants(blockName);
78
- const tempFolder = await (0, files_1.getTempFilePath)(exports.GENERATOR_FOLDER_NAME, blockName);
79
- await (0, files_1.verifyAndCreateFolder)(tempFolder);
80
- let strapiResponse = null;
81
- if (strapiProject) {
82
- strapiResponse = await this.generateStrapiBlock(blockName, blockVariants);
83
- onGenerateCallback();
84
- const cachePath = path.join(tempFolder, exports.GENERATOR_STRAPI_FILE_NAME);
85
- await fs.writeFile(cachePath, JSON.stringify(strapiResponse, null, 2));
95
+ await this.state.file.createBlockTempFolder(blockName);
96
+ if (project.type === 'strapi') {
97
+ return this.generateStrapiBlock(blockName, project, blockVariants);
86
98
  }
87
- if (nextProject) {
88
- const nextResponse = await this.generateNextBlock(blockName, blockVariants, this.data.variables, styles, strapiResponse);
89
- onGenerateCallback();
90
- const cachePath = path.join(tempFolder, exports.GENERATOR_NEXTJS_FILE_NAME);
91
- await fs.writeFile(cachePath, nextResponse);
99
+ if (project.type === 'next.js') {
100
+ await this.generateNextBlock(blockName, project, blockVariants);
92
101
  }
93
- this.state.setBlockGenerated(blockName);
94
102
  }
95
103
  catch (error) {
96
104
  console.error(error);
97
105
  }
98
106
  }
99
- async generateBlocks(blockNames) {
107
+ async generateBlocks(blockNames, project) {
100
108
  if (!blockNames.length) {
101
- console.error('No blocks selected');
102
- return;
109
+ throw new Error('No blocks to generate');
110
+ }
111
+ if (project.type !== 'strapi' && project.type !== 'next.js') {
112
+ throw new Error('Project type not supported');
103
113
  }
104
114
  console.log('- Generating Blocks... Please wait');
105
- const strapiProject = this.data.projects.find((project) => project.type === 'strapi');
106
- const nextProject = this.data.projects.find((project) => project.type === 'next.js');
107
- const styles = await this.loadProjectCSS(nextProject);
108
115
  const progressBar = new cliProgress.SingleBar({}, cliProgress.Presets.legacy);
109
- let length = 0;
110
- if (strapiProject) {
111
- length += blockNames.length;
112
- }
113
- if (nextProject) {
114
- length += blockNames.length;
115
- }
116
- progressBar.start(length, 0);
116
+ progressBar.start(blockNames.length, 0);
117
117
  for (const block of blockNames) {
118
- await this.generateBlock(block, strapiProject, nextProject, styles, () => {
119
- progressBar.increment();
120
- });
118
+ await this.generateBlock(block, project);
119
+ progressBar.increment();
121
120
  }
122
121
  progressBar.stop();
123
122
  await this.state.save();
@@ -0,0 +1,17 @@
1
+ export interface IStrapiComponent {
2
+ collectionName: string;
3
+ info: {
4
+ name: string;
5
+ displayName: string;
6
+ description: string;
7
+ };
8
+ options: Record<string, unknown>;
9
+ attributes: Record<string, unknown>;
10
+ }
11
+ export interface IStrapiGenerateResponse {
12
+ block: IStrapiComponent;
13
+ assets: IStrapiComponent[];
14
+ }
15
+ export interface INextjsGenerateResponse {
16
+ block: string;
17
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,10 +1,9 @@
1
+ import type { IProject } from '../../../../types/project';
1
2
  import type AIState from '../state';
2
3
  declare class ProjectAdder {
3
4
  private state;
4
5
  constructor(state: AIState);
5
6
  private get data();
6
- private createStrapiFiles;
7
- private createNextjsFiles;
8
- addBlock(blockName: string): Promise<void>;
7
+ addBlock(blockName: string, project: IProject): Promise<void>;
9
8
  }
10
9
  export default ProjectAdder;
@@ -1,9 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const fs = require("node:fs/promises");
4
- const path = require("node:path");
5
- const files_1 = require("../../../../utils/files");
6
- const generator_1 = require("../generator");
7
3
  class ProjectAdder {
8
4
  state;
9
5
  constructor(state) {
@@ -12,67 +8,18 @@ class ProjectAdder {
12
8
  get data() {
13
9
  return this.state.getData();
14
10
  }
15
- async createStrapiFiles(filePath, block) {
16
- const strapiProject = this.data.projects.find((project) => project.type === 'strapi');
17
- if (!strapiProject) {
18
- throw new Error('Strapi project not found');
19
- // return
20
- }
21
- const srcPath = strapiProject.srcPath || path.join(strapiProject.path, 'src');
22
- const componentsFolder = path.join(srcPath, 'components');
23
- const blocksFolder = path.join(componentsFolder, 'blocks');
24
- const blocksAssetsFolder = path.join(componentsFolder, 'blocks-assets');
25
- const strapiResult = await (0, files_1.loadJSONFile)(filePath);
26
- const blockData = strapiResult.block;
27
- const assets = strapiResult.assets;
28
- await (0, files_1.verifyAndCreateFolder)(blocksFolder);
29
- await (0, files_1.verifyAndCreateFolder)(blocksAssetsFolder);
30
- for (const asset of assets) {
31
- const name = asset.info?.name;
32
- if (!name) {
33
- console.warn('Asset name is missing, skipping asset creation');
34
- continue;
35
- }
36
- await fs.writeFile(path.join(blocksAssetsFolder, `${name}.json`), JSON.stringify(asset, null, 2));
37
- }
38
- const blockName = block.name.replace('block-', '');
39
- await fs.writeFile(path.join(blocksFolder, `${blockName}.json`), JSON.stringify(blockData, null, 2));
40
- }
41
- async createNextjsFiles(filePath, block) {
42
- const project = this.data.projects.find((project) => project.type === 'next.js');
43
- if (!project) {
44
- throw new Error('Nextjs project not found');
45
- // return
46
- }
47
- const blockFolder = path.join(project.srcPath || project.path, 'layouts', 'blocks', block.name);
48
- await (0, files_1.verifyAndCreateFolder)(blockFolder);
49
- const nextjsResult = await (0, files_1.loadFile)(filePath);
50
- await fs.writeFile(path.join(blockFolder, `${block.name}.tsx`), nextjsResult);
51
- const indexContent = `export { default } from './${block.name}'`;
52
- await fs.writeFile(path.join(blockFolder, 'index.ts'), indexContent);
53
- }
54
- async addBlock(blockName) {
11
+ async addBlock(blockName, project) {
55
12
  const block = this.data.blocks.find((block) => block.name === blockName);
56
- if (!block || !block.generated) {
13
+ if (!block) {
57
14
  console.error(`Block ${blockName} not found`);
58
15
  return;
59
16
  }
60
- const strapiTempFilePath = await (0, files_1.getTempFilePath)(generator_1.GENERATOR_FOLDER_NAME, blockName, generator_1.GENERATOR_STRAPI_FILE_NAME);
61
- const nextTempFilePath = await (0, files_1.getTempFilePath)(generator_1.GENERATOR_FOLDER_NAME, blockName, generator_1.GENERATOR_NEXTJS_FILE_NAME);
62
- if (await (0, files_1.verifyPath)(strapiTempFilePath)) {
63
- await this.createStrapiFiles(strapiTempFilePath, block);
64
- }
65
- else {
66
- console.warn(`Strapi file for block ${blockName} not found in ${strapiTempFilePath}`);
67
- }
68
- if (await (0, files_1.verifyPath)(nextTempFilePath)) {
69
- await this.createNextjsFiles(nextTempFilePath, block);
17
+ if (project.type === 'strapi') {
18
+ await this.state.file.addStrapiBlockToProject(block.name, project);
70
19
  }
71
- else {
72
- console.warn(`Next.js file for block ${blockName} not found in ${nextTempFilePath}`);
20
+ else if (project.type === 'next.js') {
21
+ await this.state.file.addNextBlockToProject(block.name, project);
73
22
  }
74
- this.state.setBlockHidden(blockName, true);
75
- await this.state.save();
76
23
  console.log(`Block ${blockName} added successfully`);
77
24
  }
78
25
  }
@@ -1,8 +1,10 @@
1
+ import FileManager from '../file-manager';
1
2
  import type { IAIFileState, IAvailableFilters } from './types';
2
3
  declare class AIState {
3
4
  private filePath;
4
5
  private data;
5
6
  private server;
7
+ file: FileManager;
6
8
  constructor();
7
9
  private createOptions;
8
10
  create(): Promise<void>;
@@ -4,13 +4,16 @@ const ai_server_module_1 = require("../../../../modules/ai-server-module");
4
4
  const project_1 = require("../../../../utils/project");
5
5
  const inquirer_1 = require("inquirer");
6
6
  const files_1 = require("../../../../utils/files");
7
+ const file_manager_1 = require("../file-manager");
7
8
  const FILE_NAME = 'ai-state.json';
8
9
  class AIState {
9
10
  filePath = '';
10
11
  data = null;
11
12
  server;
13
+ file;
12
14
  constructor() {
13
15
  this.server = new ai_server_module_1.default();
16
+ this.file = new file_manager_1.default();
14
17
  }
15
18
  async createOptions() {
16
19
  const query = await inquirer_1.default.prompt([
@@ -94,9 +97,15 @@ class AIState {
94
97
  this.data.blocks = blocks;
95
98
  }
96
99
  setVariables(variables) {
100
+ if (!this.data) {
101
+ throw new Error('AI State not initialized');
102
+ }
97
103
  this.data.variables = variables;
98
104
  }
99
105
  setColors(colors) {
106
+ if (!this.data) {
107
+ throw new Error('AI State not initialized');
108
+ }
100
109
  this.data.colors = colors;
101
110
  }
102
111
  setBlockGenerated(blockName, generated = true) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@futurebrand/dev-tools",
3
- "version": "2.5.2",
3
+ "version": "2.5.4",
4
4
  "description": "FutureBrand Dev Tools",
5
5
  "scripts": {
6
6
  "build": "tsc && tsc-alias",