@futurebrand/dev-tools 2.5.4 → 2.7.0

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.
@@ -3,6 +3,5 @@ export declare class FigmaAPI {
3
3
  private state;
4
4
  constructor(state: AIState);
5
5
  getBlockCanvas(pageId: string): Promise<string>;
6
- getVariables(pageId: string): Promise<Record<string, any>>;
7
6
  getBlocks(pageId: string, canvasId: string): Promise<Record<string, import("./types").IFigmaNode[]>>;
8
7
  }
@@ -10,10 +10,6 @@ class FigmaAPI {
10
10
  const { id } = await this.state.fetchApi(`/figma/${pageId}/blocks`);
11
11
  return id;
12
12
  }
13
- async getVariables(pageId) {
14
- const { variables } = await this.state.fetchApi(`/figma/${pageId}/variables`);
15
- return variables;
16
- }
17
13
  async getBlocks(pageId, canvasId) {
18
14
  const { blocks } = await this.state.fetchApi(`/figma/${pageId}/blocks/${canvasId}`);
19
15
  return blocks;
@@ -47,10 +47,7 @@ class FigmaModule {
47
47
  const canvas = await this.api.getBlockCanvas(figmaPageID);
48
48
  console.log('- Loading pages blocks');
49
49
  const blocksData = [];
50
- const [blocks, variables] = await Promise.all([
51
- this.api.getBlocks(figmaPageID, canvas),
52
- this.api.getVariables(figmaPageID),
53
- ]);
50
+ const blocks = await this.api.getBlocks(figmaPageID, canvas);
54
51
  Object.keys(blocks).forEach((blockName) => {
55
52
  let block = blocksData.find((block) => block.name === blockName);
56
53
  if (!block) {
@@ -86,7 +83,6 @@ class FigmaModule {
86
83
  }
87
84
  }
88
85
  this.state.setBlocks(blocksData);
89
- this.state.setVariables(variables);
90
86
  console.log('- Figma blocks loaded successfully');
91
87
  }
92
88
  }
@@ -1,9 +1,6 @@
1
1
  export interface IDocumentResponse {
2
2
  id: string;
3
3
  }
4
- export interface IVariablesResponse {
5
- variables: Record<string, any>;
6
- }
7
4
  interface IFigmaProperties {
8
5
  value: string;
9
6
  type: string;
@@ -1,8 +1,11 @@
1
1
  import type { IProject } from '../../../../types/project';
2
+ import type { INextjsGenerateResponse, IStrapiGenerateResponse } from '../generator/types';
2
3
  import type { IBlockData } from '../state/types';
4
+ import type { IProjectFile, IProjectFileSegment } from './types';
3
5
  export declare const GENERATOR_FOLDER_NAME = "generated-blocks";
4
6
  export declare const GENERATOR_STRAPI_FILE_NAME = "strapi.json";
5
7
  export declare const GENERATOR_NEXTJS_FILE_NAME = "nextjs.tsx";
8
+ export declare const GENERATOR_NEXTJS_EXTRA_FILES = "nextjs-extra-files.json";
6
9
  declare class FileManager {
7
10
  private getBlockTempPath;
8
11
  private getBlockTempFilePath;
@@ -14,9 +17,13 @@ declare class FileManager {
14
17
  getAvailableBlocksToGenerate(blocks: IBlockData[], project: IProject): Promise<IBlockData[]>;
15
18
  getAvailableBlocksToAdd(blocks: IBlockData[], project: IProject): Promise<IBlockData[]>;
16
19
  createBlockTempFolder(blockName: string): Promise<void>;
17
- saveGeneratedBlock(blockName: string, project: IProject, content: any): Promise<void>;
20
+ saveGeneratedBlock(blockName: string, project: IProject, content: IStrapiGenerateResponse | INextjsGenerateResponse): Promise<void>;
18
21
  loadGeneratedBlock(blockName: string, project: IProject): Promise<string>;
19
22
  addNextBlockToProject(blockName: string, project: IProject): Promise<void>;
20
23
  addStrapiBlockToProject(blockName: string, project: IProject): Promise<void>;
24
+ loadFilesInPath(rootPath: string, relativeTo?: string, includeSubFolders?: boolean): Promise<IProjectFile[]>;
25
+ loadProjectFiles(project: IProject | null, subDir: string): Promise<IProjectFileSegment[]>;
26
+ loadCustomPrompts(blockName: string): Promise<string>;
27
+ loadProjectCSS(nextProject?: IProject): Promise<string | null>;
21
28
  }
22
29
  export default FileManager;
@@ -1,12 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GENERATOR_NEXTJS_FILE_NAME = exports.GENERATOR_STRAPI_FILE_NAME = exports.GENERATOR_FOLDER_NAME = void 0;
3
+ exports.GENERATOR_NEXTJS_EXTRA_FILES = exports.GENERATOR_NEXTJS_FILE_NAME = exports.GENERATOR_STRAPI_FILE_NAME = exports.GENERATOR_FOLDER_NAME = void 0;
4
4
  const fs = require("node:fs/promises");
5
5
  const path = require("node:path");
6
6
  const files_1 = require("../../../../utils/files");
7
7
  exports.GENERATOR_FOLDER_NAME = 'generated-blocks';
8
8
  exports.GENERATOR_STRAPI_FILE_NAME = 'strapi.json';
9
9
  exports.GENERATOR_NEXTJS_FILE_NAME = 'nextjs.tsx';
10
+ exports.GENERATOR_NEXTJS_EXTRA_FILES = 'nextjs-extra-files.json';
10
11
  class FileManager {
11
12
  async getBlockTempPath(blockName) {
12
13
  const tempFolder = await (0, files_1.getTempFilePath)(exports.GENERATOR_FOLDER_NAME, blockName);
@@ -98,9 +99,23 @@ class FileManager {
98
99
  await (0, files_1.verifyAndCreateFolder)(tempFolder);
99
100
  }
100
101
  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);
102
+ if (project.type === 'next.js') {
103
+ const blockPath = await this.getBlockTempFilePath(project, blockName);
104
+ await fs.writeFile(blockPath, content.block);
105
+ const blockDir = path.dirname(blockPath);
106
+ const definitionPath = path.join(blockDir, 'nextjs-definition.json');
107
+ await fs.writeFile(definitionPath, JSON.stringify(content.definition, null, 2));
108
+ const extraFiles = content.extraFiles || [];
109
+ if (extraFiles.length > 0) {
110
+ const extraFilesPath = path.join(blockDir, exports.GENERATOR_NEXTJS_EXTRA_FILES);
111
+ await fs.writeFile(extraFilesPath, JSON.stringify(extraFiles, null, 2));
112
+ }
113
+ }
114
+ if (project.type === 'strapi') {
115
+ const blockPath = await this.getBlockTempFilePath(project, blockName);
116
+ const stringContent = JSON.stringify(content, null, 2);
117
+ await fs.writeFile(blockPath, stringContent);
118
+ }
104
119
  }
105
120
  async loadGeneratedBlock(blockName, project) {
106
121
  const blockPath = await this.getBlockTempFilePath(project, blockName);
@@ -113,13 +128,34 @@ class FileManager {
113
128
  if (project.type !== 'next.js') {
114
129
  throw new Error('Project is not a Next.js project');
115
130
  }
131
+ const tempFolder = await this.getBlockTempPath(blockName);
132
+ // Verify generated block
116
133
  const generatedPath = await this.getBlockTempFilePath(project, blockName);
117
134
  if (!(await (0, files_1.verifyPath)(generatedPath))) {
118
135
  throw new Error(`Generated block not found: ${generatedPath}`);
119
136
  }
120
- const content = await (0, files_1.loadFile)(generatedPath);
137
+ // Create block folder
121
138
  const blockFolder = this.getNextjsBlockFolder(project, blockName);
122
139
  await (0, files_1.verifyAndCreateFolder)(blockFolder);
140
+ // Add Extra files
141
+ try {
142
+ const extraFilesPath = path.join(tempFolder, exports.GENERATOR_NEXTJS_EXTRA_FILES);
143
+ const hasExtraFiles = await (0, files_1.verifyPath)(extraFilesPath);
144
+ if (hasExtraFiles) {
145
+ const extraFilesContent = await (0, files_1.loadFile)(extraFilesPath);
146
+ const extraFiles = JSON.parse(extraFilesContent);
147
+ if (extraFiles && extraFiles.length > 0) {
148
+ for (const extraFile of extraFiles) {
149
+ const extraFilePath = path.join(blockFolder, extraFile.name);
150
+ await fs.writeFile(extraFilePath, extraFile.content);
151
+ }
152
+ }
153
+ }
154
+ }
155
+ catch (error) {
156
+ console.error('Failed to add extra files to Next.js block:', error);
157
+ }
158
+ const content = await (0, files_1.loadFile)(generatedPath);
123
159
  const mainFilePath = path.join(blockFolder, `${blockName}.tsx`);
124
160
  const indexFilePath = path.join(blockFolder, 'index.ts');
125
161
  const indexContent = `export { default } from './${blockName}'
@@ -152,5 +188,109 @@ class FileManager {
152
188
  await fs.writeFile(assetFilePath, JSON.stringify(asset, null, 2));
153
189
  }
154
190
  }
191
+ async loadFilesInPath(rootPath, relativeTo, includeSubFolders = true) {
192
+ const allFilesPath = await (0, files_1.getFilesInPath)(rootPath, includeSubFolders);
193
+ const files = [];
194
+ for (const filePath of allFilesPath) {
195
+ const content = await (0, files_1.loadFile)(filePath);
196
+ const relativePath = relativeTo
197
+ ? path.relative(relativeTo, filePath)
198
+ : filePath;
199
+ files.push({ path: relativePath, content });
200
+ }
201
+ return files;
202
+ }
203
+ async loadProjectFiles(project, subDir) {
204
+ if (!project) {
205
+ return [];
206
+ }
207
+ const rootFolder = path.join(project.srcPath, subDir);
208
+ const segments = [];
209
+ try {
210
+ if (!(await (0, files_1.verifyPath)(rootFolder))) {
211
+ throw new Error('Components folder does not exist');
212
+ }
213
+ const files = await this.loadFilesInPath(rootFolder, project.srcPath, false);
214
+ if (files.length > 0) {
215
+ for (const file of files) {
216
+ const name = path.basename(file.path, path.extname(file.path));
217
+ const segment = {
218
+ name,
219
+ files: [
220
+ {
221
+ ...file,
222
+ path: `@/${file.path}`.replace(/\/index.ts|\/index.tsx/g, ''),
223
+ },
224
+ ],
225
+ };
226
+ segments.push(segment);
227
+ }
228
+ }
229
+ const dirs = await (0, files_1.getDirectoriesInPath)(rootFolder);
230
+ for (const dir of dirs) {
231
+ const dirPath = path.join(rootFolder, dir);
232
+ const dirFiles = (await this.loadFilesInPath(dirPath, project.srcPath)).map((file) => ({
233
+ ...file,
234
+ path: `@/${file.path}`.replace(/\/index.ts|\/index.tsx/g, ''),
235
+ }));
236
+ const dirName = path.basename(dir);
237
+ const segment = {
238
+ name: dirName,
239
+ files: dirFiles,
240
+ };
241
+ segments.push(segment);
242
+ }
243
+ return segments;
244
+ }
245
+ catch (error) {
246
+ console.error(error);
247
+ return [];
248
+ }
249
+ }
250
+ async loadCustomPrompts(blockName) {
251
+ try {
252
+ const prompts = [];
253
+ const globalPromptPath = await (0, files_1.getTempFilePath)('prompts.md');
254
+ if (await (0, files_1.verifyPath)(globalPromptPath)) {
255
+ const globalPrompt = await (0, files_1.loadFile)(globalPromptPath);
256
+ if (globalPrompt) {
257
+ prompts.push(globalPrompt);
258
+ }
259
+ }
260
+ else {
261
+ await (0, files_1.writeFile)(globalPromptPath, '');
262
+ }
263
+ const blockFolder = await this.getBlockTempPath(blockName);
264
+ const blockPromptsPath = path.join(blockFolder, 'prompts.md');
265
+ if (await (0, files_1.verifyPath)(blockPromptsPath)) {
266
+ const blockPrompt = await (0, files_1.loadFile)(blockPromptsPath);
267
+ if (blockPrompt) {
268
+ prompts.push(blockPrompt);
269
+ }
270
+ }
271
+ return prompts.join('\n\n');
272
+ }
273
+ catch (error) {
274
+ console.error(error);
275
+ return '';
276
+ }
277
+ }
278
+ async loadProjectCSS(nextProject) {
279
+ if (!nextProject) {
280
+ return null;
281
+ }
282
+ const cssFile = path.join(nextProject.srcPath, 'styles', 'index.css');
283
+ try {
284
+ const css = await fs.readFile(cssFile, 'utf-8');
285
+ if (!css) {
286
+ return null;
287
+ }
288
+ return css;
289
+ }
290
+ catch (error) {
291
+ console.error(error);
292
+ return null;
293
+ }
294
+ }
155
295
  }
156
296
  exports.default = FileManager;
@@ -2,3 +2,11 @@ export interface IStrapiFolders {
2
2
  blocks: string;
3
3
  assets: string;
4
4
  }
5
+ export interface IProjectFileSegment {
6
+ name: string;
7
+ files: IProjectFile[];
8
+ }
9
+ export interface IProjectFile {
10
+ path: string;
11
+ content: string;
12
+ }
@@ -10,8 +10,8 @@ export declare class Generator {
10
10
  private get data();
11
11
  private fetchNextBlock;
12
12
  private fetchStrapiBlock;
13
- loadProjectCSS(nextProject?: IProject): Promise<string | null>;
14
13
  private generateStrapiBlock;
14
+ private getNextjsProjectFiles;
15
15
  private generateNextBlock;
16
16
  generateBlock(blockName: string, project: IProject): Promise<IStrapiGenerateResponse | undefined>;
17
17
  generateBlocks(blockNames: string[], project: IProject): Promise<void>;
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Generator = exports.GENERATOR_NEXTJS_FILE_NAME = exports.GENERATOR_STRAPI_FILE_NAME = exports.GENERATOR_FOLDER_NAME = void 0;
4
4
  const fs = require("node:fs/promises");
5
- const path = require("node:path");
6
5
  const files_1 = require("../../../../utils/files");
7
6
  const cliProgress = require("cli-progress");
8
7
  exports.GENERATOR_FOLDER_NAME = 'generated-blocks';
@@ -16,13 +15,14 @@ class Generator {
16
15
  get data() {
17
16
  return this.state.getData();
18
17
  }
19
- async fetchNextBlock(blockName, blockVariants, variables, styles, strapiComponent) {
18
+ async fetchNextBlock(blockName, blockVariants, files, strapiComponent, customPrompt) {
20
19
  const requestBody = {
21
20
  name: blockName.replace('block-', ''),
22
21
  variants: blockVariants,
23
- variables,
24
- styles,
22
+ files,
25
23
  strapiComponent,
24
+ customPrompt,
25
+ figma: this.data.configs.figma,
26
26
  };
27
27
  const data = await this.state.fetchApi('/generate/nextjs/block', {
28
28
  method: 'POST',
@@ -34,12 +34,13 @@ class Generator {
34
34
  if (!data.result?.block) {
35
35
  throw new Error('Next.js block generation failed');
36
36
  }
37
- return data.result.block;
37
+ return data.result;
38
38
  }
39
39
  async fetchStrapiBlock(blockName, blockVariants) {
40
40
  const requestBody = {
41
41
  name: blockName.replace('block-', ''),
42
42
  variants: blockVariants,
43
+ figma: this.data.configs.figma,
43
44
  };
44
45
  const data = await this.state.fetchApi('/generate/strapi/block', {
45
46
  method: 'POST',
@@ -53,23 +54,6 @@ class Generator {
53
54
  }
54
55
  return data.result;
55
56
  }
56
- async loadProjectCSS(nextProject) {
57
- if (!nextProject) {
58
- return null;
59
- }
60
- const cssFile = path.join(nextProject.srcPath, 'styles', 'index.css');
61
- try {
62
- const css = await fs.readFile(cssFile, 'utf-8');
63
- if (!css) {
64
- return null;
65
- }
66
- return css;
67
- }
68
- catch (error) {
69
- console.error(error);
70
- return null;
71
- }
72
- }
73
57
  async generateStrapiBlock(blockName, project, blockVariants) {
74
58
  const isAlreadyGenerated = await this.state.file.verifyBlockAlreadyGenerated(blockName, project);
75
59
  if (isAlreadyGenerated) {
@@ -80,13 +64,26 @@ class Generator {
80
64
  await this.state.file.saveGeneratedBlock(blockName, project, response);
81
65
  return response;
82
66
  }
67
+ async getNextjsProjectFiles(project) {
68
+ const styles = await this.state.file.loadProjectFiles(project, 'styles');
69
+ const components = await this.state.file.loadProjectFiles(project, 'components');
70
+ const types = await this.state.file.loadProjectFiles(project, 'types');
71
+ const layouts = await this.state.file.loadProjectFiles(project, 'layouts/shared');
72
+ return {
73
+ styles,
74
+ components,
75
+ types,
76
+ layouts,
77
+ };
78
+ }
83
79
  async generateNextBlock(blockName, project, blockVariants) {
84
80
  const strapiProject = this.data.projects.find((p) => p.type === 'strapi');
85
81
  const strapiBlock = strapiProject
86
82
  ? await this.generateStrapiBlock(blockName, strapiProject, blockVariants)
87
83
  : undefined;
88
- const styles = await this.loadProjectCSS(project);
89
- const nextResponse = await this.fetchNextBlock(blockName, blockVariants, this.data.variables, styles, strapiBlock);
84
+ const customPrompt = await this.state.file.loadCustomPrompts(blockName);
85
+ const files = await this.getNextjsProjectFiles(project);
86
+ const nextResponse = await this.fetchNextBlock(blockName, blockVariants, files, strapiBlock, customPrompt);
90
87
  await this.state.file.saveGeneratedBlock(blockName, project, nextResponse);
91
88
  }
92
89
  async generateBlock(blockName, project) {
@@ -101,7 +98,12 @@ class Generator {
101
98
  }
102
99
  }
103
100
  catch (error) {
101
+ console.log('------------------------------------');
102
+ console.log('------------------------------------');
103
+ console.log(`Error generating block: ${blockName}`);
104
104
  console.error(error);
105
+ console.log('------------------------------------');
106
+ console.log('------------------------------------');
105
107
  }
106
108
  }
107
109
  async generateBlocks(blockNames, project) {
@@ -124,7 +126,8 @@ class Generator {
124
126
  }
125
127
  async generateStyles() {
126
128
  console.log('- Generating Styles... Please wait');
127
- const variables = this.data.variables;
129
+ // TODO: get variables from blocks
130
+ const variables = {}; // this.data.variables
128
131
  const data = await this.state.fetchApi('/generate/styles', {
129
132
  method: 'POST',
130
133
  headers: {
@@ -150,13 +153,27 @@ class Generator {
150
153
  console.log('- Generating Checklist... Please wait');
151
154
  const lines = ['# Checklist', ''];
152
155
  const blocks = this.state.getData().blocks;
156
+ let project = this.state.getProjectByType('next.js');
157
+ if (!project) {
158
+ project = this.state.getProjectByType('strapi');
159
+ if (!project) {
160
+ throw new Error('No suitable project found for checklist generation');
161
+ }
162
+ }
153
163
  for (const block of blocks) {
164
+ const isChecked = block.hidden ||
165
+ (await this.state.file.verifyBlockAlreadyExists(project, block.name));
154
166
  const name = block.name
155
167
  .replace('block-', '')
156
168
  .split('-')
157
169
  .map((word) => word.length > 1 ? word.charAt(0).toUpperCase() + word.slice(1) : word)
158
170
  .join(' ');
159
- lines.push(`- [${block.generated || block.hidden ? 'x' : ' '}] Block | ${name} (\`${block.name}\`)`);
171
+ let nameContent = `Block | ${name} (\`${block.name}\`)`;
172
+ if (block.hidden) {
173
+ nameContent = `~~${nameContent}~~ <sup>hidden</sup>`;
174
+ }
175
+ const checkContent = isChecked ? 'x' : ' ';
176
+ lines.push(`- [${checkContent}] ${nameContent}`);
160
177
  }
161
178
  const listText = lines.join('\n');
162
179
  const tempPath = await (0, files_1.getTempFilePath)('checklist.md');
@@ -12,6 +12,18 @@ export interface IStrapiGenerateResponse {
12
12
  block: IStrapiComponent;
13
13
  assets: IStrapiComponent[];
14
14
  }
15
+ export interface IGenerationExtraFile {
16
+ name: string;
17
+ content: string;
18
+ type: string;
19
+ description: string;
20
+ }
15
21
  export interface INextjsGenerateResponse {
16
22
  block: string;
23
+ extraFiles: IGenerationExtraFile[];
24
+ definition: {
25
+ architecture: string[];
26
+ decisions: string[];
27
+ note: string;
28
+ };
17
29
  }
@@ -1,3 +1,4 @@
1
+ import type { IProject, ProjectType } from '../../../../types/project';
1
2
  import FileManager from '../file-manager';
2
3
  import type { IAIFileState, IAvailableFilters } from './types';
3
4
  declare class AIState {
@@ -13,10 +14,10 @@ declare class AIState {
13
14
  save(): Promise<void>;
14
15
  get isReady(): boolean;
15
16
  getData(): IAIFileState;
17
+ getProjectByType(type: ProjectType): IProject | null;
16
18
  getAvailableBlocks({ generated, hidden }?: IAvailableFilters): import("./types").IBlockData[];
17
19
  getAvailableBlocksNames(filters?: IAvailableFilters): string[];
18
20
  setBlocks(blocks: IAIFileState['blocks']): void;
19
- setVariables(variables: IAIFileState['variables']): void;
20
21
  setColors(colors: IAIFileState['colors']): void;
21
22
  setBlockGenerated(blockName: string, generated?: boolean): void;
22
23
  getBlockVariants(blockName: string): any[];
@@ -42,7 +42,6 @@ class AIState {
42
42
  },
43
43
  projects,
44
44
  blocks: [],
45
- variables: {},
46
45
  };
47
46
  }
48
47
  async create() {
@@ -74,6 +73,10 @@ class AIState {
74
73
  }
75
74
  return this.data;
76
75
  }
76
+ getProjectByType(type) {
77
+ const projects = this.getData().projects;
78
+ return projects.find((project) => project.type === type) || null;
79
+ }
77
80
  getAvailableBlocks({ generated, hidden } = {}) {
78
81
  let blocks = this.getData().blocks;
79
82
  if (hidden != null || generated != null) {
@@ -96,12 +99,6 @@ class AIState {
96
99
  setBlocks(blocks) {
97
100
  this.data.blocks = blocks;
98
101
  }
99
- setVariables(variables) {
100
- if (!this.data) {
101
- throw new Error('AI State not initialized');
102
- }
103
- this.data.variables = variables;
104
- }
105
102
  setColors(colors) {
106
103
  if (!this.data) {
107
104
  throw new Error('AI State not initialized');
@@ -23,6 +23,5 @@ export interface IAIFileState {
23
23
  configs: IStateConfigs;
24
24
  blocks: IBlockData[];
25
25
  projects: IProject[];
26
- variables: Record<string, any>;
27
26
  colors?: IProjectColor[];
28
27
  }
@@ -1,13 +1,25 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ const node_net_1 = require("node:net");
3
4
  const inquirer_1 = require("inquirer");
5
+ const undici_1 = require("undici");
4
6
  const files_1 = require("../../utils/files");
5
7
  const FILE_NAME = 'ai-server.json';
8
+ const TIMEOUT_LIMIT_TIME = 1000 * 60 * 60; // 60 minutes
9
+ const longTimeoutAgent = new undici_1.Agent({
10
+ connect: {
11
+ timeout: TIMEOUT_LIMIT_TIME,
12
+ },
13
+ headersTimeout: TIMEOUT_LIMIT_TIME,
14
+ bodyTimeout: TIMEOUT_LIMIT_TIME,
15
+ });
6
16
  class AIServerModule {
7
17
  filePath = '';
8
18
  api = '';
9
19
  token = '';
10
- constructor() { }
20
+ constructor() {
21
+ (0, node_net_1.setDefaultAutoSelectFamilyAttemptTimeout)(TIMEOUT_LIMIT_TIME);
22
+ }
11
23
  async createConfigs() {
12
24
  const query = await inquirer_1.default.prompt([
13
25
  {
@@ -46,6 +58,10 @@ class AIServerModule {
46
58
  Authorization: `Bearer ${this.token}`,
47
59
  ...init?.headers,
48
60
  },
61
+ signal: AbortSignal.timeout(TIMEOUT_LIMIT_TIME),
62
+ ...{
63
+ dispatcher: longTimeoutAgent,
64
+ },
49
65
  });
50
66
  if (!response.ok) {
51
67
  throw new Error(`Failed to fetch ${path}`);
@@ -9,4 +9,4 @@ export declare function writeRootFile(fileName: string, content: string): Promis
9
9
  export declare function writeFile(filePath: string, content: string): Promise<void>;
10
10
  export declare function loadFile(filePath: string): Promise<string>;
11
11
  export declare function getDirectoriesInPath(rootPath: string): Promise<string[]>;
12
- export declare function getFilesInPath(rootPath: string): Promise<string[]>;
12
+ export declare function getFilesInPath(rootPath: string, includeSubFolders?: boolean): Promise<string[]>;
@@ -102,7 +102,7 @@ async function getDirectoriesInPath(rootPath) {
102
102
  return directories;
103
103
  }
104
104
  }
105
- async function getFilesInPath(rootPath) {
105
+ async function getFilesInPath(rootPath, includeSubFolders = true) {
106
106
  const files = [];
107
107
  try {
108
108
  const allContent = await fs.readdir(rootPath);
@@ -113,8 +113,10 @@ async function getFilesInPath(rootPath) {
113
113
  files.push(contentPath);
114
114
  }
115
115
  else if (stats.isDirectory()) {
116
- const subFiles = await getFilesInPath(contentPath);
117
- files.push(...subFiles);
116
+ if (includeSubFolders) {
117
+ const subFiles = await getFilesInPath(contentPath);
118
+ files.push(...subFiles);
119
+ }
118
120
  }
119
121
  }
120
122
  return files;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@futurebrand/dev-tools",
3
- "version": "2.5.4",
3
+ "version": "2.7.0",
4
4
  "description": "FutureBrand Dev Tools",
5
5
  "scripts": {
6
6
  "build": "tsc && tsc-alias",
@@ -64,7 +64,8 @@
64
64
  "inquirer": "^12.6.3",
65
65
  "prettier": "^3.6.0",
66
66
  "prettier-plugin-tailwindcss": "^0.6.13",
67
- "typescript-eslint": "^8.35.0"
67
+ "typescript-eslint": "^8.35.0",
68
+ "undici": "^7.18.2"
68
69
  },
69
70
  "devDependencies": {
70
71
  "@types/cli-progress": "^3.11.6",