@futurebrand/dev-tools 2.5.1 → 2.5.3

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 (33) hide show
  1. package/dist/commands/ai/add.js +36 -12
  2. package/dist/commands/ai/docs/index.d.ts +3 -0
  3. package/dist/commands/ai/docs/index.js +60 -0
  4. package/dist/commands/ai/docs/modules/generator/index.d.ts +17 -0
  5. package/dist/commands/ai/docs/modules/generator/index.js +88 -0
  6. package/dist/commands/ai/docs/types.d.ts +11 -0
  7. package/dist/commands/ai/docs/types.js +2 -0
  8. package/dist/commands/ai/generate.js +38 -14
  9. package/dist/commands/ai/modules/figma/index.js +7 -16
  10. package/dist/commands/ai/modules/file-manager/index.d.ts +22 -0
  11. package/dist/commands/ai/modules/file-manager/index.js +156 -0
  12. package/dist/commands/ai/modules/file-manager/types.d.ts +4 -0
  13. package/dist/commands/ai/modules/file-manager/types.js +2 -0
  14. package/dist/commands/ai/modules/generator/index.d.ts +7 -4
  15. package/dist/commands/ai/modules/generator/index.js +55 -73
  16. package/dist/commands/ai/modules/generator/types.d.ts +17 -0
  17. package/dist/commands/ai/modules/generator/types.js +2 -0
  18. package/dist/commands/ai/modules/project-adder/index.d.ts +2 -3
  19. package/dist/commands/ai/modules/project-adder/index.js +6 -58
  20. package/dist/commands/ai/modules/state/index.d.ts +3 -0
  21. package/dist/commands/ai/modules/state/index.js +15 -19
  22. package/dist/commands/ai/modules/state/types.d.ts +2 -3
  23. package/dist/modules/ai-server-module/index.d.ts +15 -0
  24. package/dist/modules/ai-server-module/index.js +86 -0
  25. package/dist/modules/ai-server-module/types.d.ts +4 -0
  26. package/dist/modules/ai-server-module/types.js +2 -0
  27. package/dist/modules/parallel/index.d.ts +1 -6
  28. package/dist/modules/parallel/index.js +11 -29
  29. package/dist/types/project.d.ts +1 -0
  30. package/dist/utils/files.d.ts +2 -0
  31. package/dist/utils/files.js +42 -0
  32. package/dist/utils/project.js +25 -5
  33. package/package.json +1 -1
@@ -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,
@@ -24,54 +24,40 @@ class Generator {
24
24
  styles,
25
25
  strapiComponent,
26
26
  };
27
- try {
28
- const data = await this.state.fetchApi('/generate/nextjs/block', {
29
- method: 'POST',
30
- headers: {
31
- 'Content-Type': 'application/json',
32
- },
33
- body: JSON.stringify(requestBody),
34
- });
35
- if (data.result?.block) {
36
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
37
- return data.result.block;
38
- }
39
- return null;
40
- }
41
- catch (error) {
42
- console.error(error);
43
- return null;
27
+ const data = await this.state.fetchApi('/generate/nextjs/block', {
28
+ method: 'POST',
29
+ headers: {
30
+ 'Content-Type': 'application/json',
31
+ },
32
+ body: JSON.stringify(requestBody),
33
+ });
34
+ if (!data.result?.block) {
35
+ throw new Error('Next.js block generation failed');
44
36
  }
37
+ return data.result.block;
45
38
  }
46
- async generateStrapiBlock(blockName, blockVariants) {
39
+ async fetchStrapiBlock(blockName, blockVariants) {
47
40
  const requestBody = {
48
41
  name: blockName.replace('block-', ''),
49
42
  variants: blockVariants,
50
43
  };
51
- try {
52
- const data = await this.state.fetchApi('/generate/strapi/block', {
53
- method: 'POST',
54
- headers: {
55
- 'Content-Type': 'application/json',
56
- },
57
- body: JSON.stringify(requestBody),
58
- });
59
- if (data.result) {
60
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
61
- return data.result;
62
- }
63
- return null;
64
- }
65
- catch (error) {
66
- console.error(error);
67
- return null;
44
+ const data = await this.state.fetchApi('/generate/strapi/block', {
45
+ method: 'POST',
46
+ headers: {
47
+ 'Content-Type': 'application/json',
48
+ },
49
+ body: JSON.stringify(requestBody),
50
+ });
51
+ if (!data.result) {
52
+ throw new Error('Strapi block generation failed');
68
53
  }
54
+ return data.result;
69
55
  }
70
56
  async loadProjectCSS(nextProject) {
71
57
  if (!nextProject) {
72
58
  return null;
73
59
  }
74
- const cssFile = path.join(nextProject.path, 'styles', 'index.css');
60
+ const cssFile = path.join(nextProject.srcPath, 'styles', 'index.css');
75
61
  try {
76
62
  const css = await fs.readFile(cssFile, 'utf-8');
77
63
  if (!css) {
@@ -84,56 +70,52 @@ class Generator {
84
70
  return null;
85
71
  }
86
72
  }
87
- 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) {
88
93
  try {
89
94
  const blockVariants = this.state.getBlockVariants(blockName);
90
- const tempFolder = await (0, files_1.getTempFilePath)(exports.GENERATOR_FOLDER_NAME, blockName);
91
- await (0, files_1.verifyAndCreateFolder)(tempFolder);
92
- let strapiResponse = null;
93
- if (strapiProject) {
94
- strapiResponse = await this.generateStrapiBlock(blockName, blockVariants);
95
- onGenerateCallback();
96
- if (strapiResponse) {
97
- const cachePath = path.join(tempFolder, exports.GENERATOR_STRAPI_FILE_NAME);
98
- await fs.writeFile(cachePath, JSON.stringify(strapiResponse, null, 2));
99
- }
95
+ await this.state.file.createBlockTempFolder(blockName);
96
+ if (project.type === 'strapi') {
97
+ return this.generateStrapiBlock(blockName, project, blockVariants);
100
98
  }
101
- if (nextProject) {
102
- const nextResponse = await this.generateNextBlock(blockName, blockVariants, this.data.variables, styles, strapiResponse);
103
- onGenerateCallback();
104
- if (nextResponse) {
105
- const cachePath = path.join(tempFolder, exports.GENERATOR_NEXTJS_FILE_NAME);
106
- await fs.writeFile(cachePath, nextResponse);
107
- }
99
+ if (project.type === 'next.js') {
100
+ await this.generateNextBlock(blockName, project, blockVariants);
108
101
  }
109
- this.state.setBlockGenerated(blockName);
110
102
  }
111
103
  catch (error) {
112
104
  console.error(error);
113
105
  }
114
106
  }
115
- async generateBlocks(blockNames) {
107
+ async generateBlocks(blockNames, project) {
116
108
  if (!blockNames.length) {
117
- console.error('No blocks selected');
118
- 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');
119
113
  }
120
114
  console.log('- Generating Blocks... Please wait');
121
- const strapiProject = this.data.projects.find((project) => project.type === 'strapi');
122
- const nextProject = this.data.projects.find((project) => project.type === 'next.js');
123
- const styles = await this.loadProjectCSS(nextProject);
124
115
  const progressBar = new cliProgress.SingleBar({}, cliProgress.Presets.legacy);
125
- let length = 0;
126
- if (strapiProject) {
127
- length += blockNames.length;
128
- }
129
- if (nextProject) {
130
- length += blockNames.length;
131
- }
132
- progressBar.start(length, 0);
116
+ progressBar.start(blockNames.length, 0);
133
117
  for (const block of blockNames) {
134
- await this.generateBlock(block, strapiProject, nextProject, styles, () => {
135
- progressBar.increment();
136
- });
118
+ await this.generateBlock(block, project);
137
119
  }
138
120
  progressBar.stop();
139
121
  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,66 +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 componentsFolder = path.join(strapiProject.path, 'src', 'components');
22
- const blocksFolder = path.join(componentsFolder, 'blocks');
23
- const blocksAssetsFolder = path.join(componentsFolder, 'blocks-assets');
24
- const strapiResult = await (0, files_1.loadJSONFile)(filePath);
25
- const blockData = strapiResult.block;
26
- const assets = strapiResult.assets;
27
- await (0, files_1.verifyAndCreateFolder)(blocksFolder);
28
- await (0, files_1.verifyAndCreateFolder)(blocksAssetsFolder);
29
- for (const asset of assets) {
30
- const name = asset.info?.name;
31
- if (!name) {
32
- console.warn('Asset name is missing, skipping asset creation');
33
- continue;
34
- }
35
- await fs.writeFile(path.join(blocksAssetsFolder, `${name}.json`), JSON.stringify(asset, null, 2));
36
- }
37
- const blockName = block.name.replace('block-', '');
38
- await fs.writeFile(path.join(blocksFolder, `${blockName}.json`), JSON.stringify(blockData, null, 2));
39
- }
40
- async createNextjsFiles(filePath, block) {
41
- const project = this.data.projects.find((project) => project.type === 'next.js');
42
- if (!project) {
43
- throw new Error('Nextjs project not found');
44
- // return
45
- }
46
- const blockFolder = path.join(project.path, 'layouts', 'blocks', block.name);
47
- await (0, files_1.verifyAndCreateFolder)(blockFolder);
48
- const nextjsResult = await (0, files_1.loadFile)(filePath);
49
- await fs.writeFile(path.join(blockFolder, `${block.name}.tsx`), nextjsResult);
50
- const indexContent = `export { default } from './${block.name}'`;
51
- await fs.writeFile(path.join(blockFolder, 'index.ts'), indexContent);
52
- }
53
- async addBlock(blockName) {
11
+ async addBlock(blockName, project) {
54
12
  const block = this.data.blocks.find((block) => block.name === blockName);
55
- if (!block || !block.generated) {
13
+ if (!block) {
56
14
  console.error(`Block ${blockName} not found`);
57
15
  return;
58
16
  }
59
- const strapiTempFilePath = await (0, files_1.getTempFilePath)(generator_1.GENERATOR_FOLDER_NAME, blockName, generator_1.GENERATOR_STRAPI_FILE_NAME);
60
- const nextTempFilePath = await (0, files_1.getTempFilePath)(generator_1.GENERATOR_FOLDER_NAME, blockName, generator_1.GENERATOR_NEXTJS_FILE_NAME);
61
- if (await (0, files_1.verifyPath)(strapiTempFilePath)) {
62
- await this.createStrapiFiles(strapiTempFilePath, block);
63
- }
64
- else {
65
- console.warn(`Strapi file for block ${blockName} not found in ${strapiTempFilePath}`);
66
- }
67
- if (await (0, files_1.verifyPath)(nextTempFilePath)) {
68
- await this.createNextjsFiles(nextTempFilePath, block);
17
+ if (project.type === 'strapi') {
18
+ await this.state.file.addStrapiBlockToProject(block.name, project);
69
19
  }
70
- else {
71
- 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);
72
22
  }
73
- this.state.setBlockHidden(blockName, true);
74
- await this.state.save();
75
23
  console.log(`Block ${blockName} added successfully`);
76
24
  }
77
25
  }
@@ -1,7 +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;
6
+ private server;
7
+ file: FileManager;
5
8
  constructor();
6
9
  private createOptions;
7
10
  create(): Promise<void>;
@@ -1,13 +1,20 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ const ai_server_module_1 = require("../../../../modules/ai-server-module");
3
4
  const project_1 = require("../../../../utils/project");
4
5
  const inquirer_1 = require("inquirer");
5
6
  const files_1 = require("../../../../utils/files");
7
+ const file_manager_1 = require("../file-manager");
6
8
  const FILE_NAME = 'ai-state.json';
7
9
  class AIState {
8
10
  filePath = '';
9
11
  data = null;
10
- constructor() { }
12
+ server;
13
+ file;
14
+ constructor() {
15
+ this.server = new ai_server_module_1.default();
16
+ this.file = new file_manager_1.default();
17
+ }
11
18
  async createOptions() {
12
19
  const query = await inquirer_1.default.prompt([
13
20
  {
@@ -40,34 +47,23 @@ class AIState {
40
47
  }
41
48
  async create() {
42
49
  this.data = await this.createOptions();
50
+ this.server.setApiConfigs(this.data.configs);
43
51
  }
44
52
  async fetchApi(path, init) {
45
- let apiUrl = this.getData().configs.api;
46
- if (apiUrl.endsWith('/')) {
47
- apiUrl = apiUrl.slice(0, -1);
48
- }
49
- const response = await fetch(`${apiUrl}${path}`, {
50
- ...init,
51
- headers: {
52
- 'Content-Type': 'application/json',
53
- Authorization: `Bearer ${this.getData().configs.token}`,
54
- ...init?.headers,
55
- },
56
- });
57
- if (!response.ok) {
58
- throw new Error(`Failed to fetch ${path}`);
59
- }
60
- const data = await response.json();
61
- return data;
53
+ return this.server.fetchApi(path, init);
62
54
  }
63
55
  async init() {
64
56
  this.filePath = await (0, files_1.getTempFilePath)(FILE_NAME);
65
57
  if (await (0, files_1.verifyPath)(this.filePath)) {
66
58
  this.data = await (0, files_1.loadJSONFile)(this.filePath);
59
+ this.server.setApiConfigs(this.data.configs);
67
60
  }
68
61
  }
69
62
  async save() {
70
- await (0, files_1.writeJSONFile)(this.filePath, this.data);
63
+ if (this.data) {
64
+ await (0, files_1.writeJSONFile)(this.filePath, this.data);
65
+ await this.server.save();
66
+ }
71
67
  }
72
68
  get isReady() {
73
69
  return this.data !== null;
@@ -1,8 +1,7 @@
1
+ import type { IServerConfigs } from '../../../../modules/ai-server-module/types';
1
2
  import type { IProject } from '../../../../types/project';
2
3
  import type { IFigmaNode } from '../figma/types';
3
- export interface IStateConfigs {
4
- api: string;
5
- token: string;
4
+ export interface IStateConfigs extends IServerConfigs {
6
5
  figma: string;
7
6
  }
8
7
  export interface IBlockData {
@@ -0,0 +1,15 @@
1
+ import type { IServerConfigs } from './types';
2
+ declare class AIServerModule implements IServerConfigs {
3
+ private filePath;
4
+ api: string;
5
+ token: string;
6
+ constructor();
7
+ private createConfigs;
8
+ create(): Promise<void>;
9
+ fetchApi<T = any>(path: string, init?: RequestInit): Promise<T>;
10
+ init(): Promise<void>;
11
+ setApiConfigs(configs: IServerConfigs): void;
12
+ save(): Promise<void>;
13
+ get isReady(): boolean;
14
+ }
15
+ export default AIServerModule;
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const inquirer_1 = require("inquirer");
4
+ const files_1 = require("../../utils/files");
5
+ const FILE_NAME = 'ai-server.json';
6
+ class AIServerModule {
7
+ filePath = '';
8
+ api = '';
9
+ token = '';
10
+ constructor() { }
11
+ async createConfigs() {
12
+ const query = await inquirer_1.default.prompt([
13
+ {
14
+ type: 'input',
15
+ name: 'apiUrl',
16
+ message: 'What is the AI API url?',
17
+ },
18
+ {
19
+ type: 'input',
20
+ name: 'apiToken',
21
+ message: 'What is the AI API token?',
22
+ },
23
+ ]);
24
+ return {
25
+ api: query.apiUrl,
26
+ token: query.apiToken,
27
+ };
28
+ }
29
+ async create() {
30
+ const configs = await this.createConfigs();
31
+ this.api = configs.api;
32
+ this.token = configs.token;
33
+ }
34
+ async fetchApi(path, init) {
35
+ if (!this.isReady) {
36
+ await this.init();
37
+ }
38
+ let apiUrl = this.api;
39
+ if (apiUrl.endsWith('/')) {
40
+ apiUrl = apiUrl.slice(0, -1);
41
+ }
42
+ const response = await fetch(`${apiUrl}${path}`, {
43
+ ...init,
44
+ headers: {
45
+ 'Content-Type': 'application/json',
46
+ Authorization: `Bearer ${this.token}`,
47
+ ...init?.headers,
48
+ },
49
+ });
50
+ if (!response.ok) {
51
+ throw new Error(`Failed to fetch ${path}`);
52
+ }
53
+ const data = await response.json();
54
+ return data;
55
+ }
56
+ async init() {
57
+ this.filePath = await (0, files_1.getTempFilePath)(FILE_NAME);
58
+ if (await (0, files_1.verifyPath)(this.filePath)) {
59
+ const configs = await (0, files_1.loadJSONFile)(this.filePath);
60
+ this.setApiConfigs(configs);
61
+ }
62
+ else {
63
+ const configs = await this.createConfigs();
64
+ this.setApiConfigs(configs);
65
+ await this.save();
66
+ }
67
+ }
68
+ setApiConfigs(configs) {
69
+ this.api = configs.api;
70
+ this.token = configs.token;
71
+ }
72
+ async save() {
73
+ if (!this.isReady) {
74
+ throw new Error('AIServerModule is not ready. Please initialize it first.');
75
+ }
76
+ const filePath = this.filePath || (await (0, files_1.getTempFilePath)(FILE_NAME));
77
+ await (0, files_1.writeJSONFile)(filePath, {
78
+ api: this.api,
79
+ token: this.token,
80
+ });
81
+ }
82
+ get isReady() {
83
+ return this.api !== '' && this.token !== '';
84
+ }
85
+ }
86
+ exports.default = AIServerModule;
@@ -0,0 +1,4 @@
1
+ export interface IServerConfigs {
2
+ api: string;
3
+ token: string;
4
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,16 +1,11 @@
1
1
  type ParallelCallback = () => Promise<void>;
2
- type CycleCallback = (index: number, total: number) => void;
3
2
  declare class ParallelModule {
4
3
  private readonly parallelCalls;
5
4
  private promises;
6
5
  private running;
7
- private index;
8
6
  constructor(parallelCalls: number);
9
7
  add(callback: ParallelCallback): void;
10
- private next;
11
- private wait;
12
- get total(): number;
13
- execute(callback: CycleCallback): Promise<void>;
8
+ execute(): Promise<void>;
14
9
  reset(): void;
15
10
  }
16
11
  export default ParallelModule;
@@ -1,50 +1,32 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const sleep_1 = require("../../utils/sleep");
4
3
  class ParallelModule {
5
4
  parallelCalls;
6
5
  promises;
7
6
  running;
8
- index;
9
7
  constructor(parallelCalls) {
10
8
  this.parallelCalls = parallelCalls;
11
9
  this.promises = [];
12
- this.running = 0;
13
- this.index = 0;
10
+ this.running = new Set();
14
11
  }
15
12
  add(callback) {
16
13
  this.promises.push(callback);
17
14
  }
18
- async next(callback) {
19
- const promise = this.promises.shift();
20
- if (promise) {
21
- this.running++;
22
- await promise();
23
- this.running--;
24
- }
25
- this.index++;
26
- callback(this.index, this.total);
27
- }
28
- async wait() {
29
- while (this.running >= this.parallelCalls) {
30
- await (0, sleep_1.sleep)(0);
31
- }
32
- }
33
- get total() {
34
- return this.promises.length;
35
- }
36
- async execute(callback) {
37
- while (this.promises.length > 0) {
38
- if (this.running >= this.parallelCalls) {
39
- await this.wait();
15
+ async execute() {
16
+ for (const promise of this.promises) {
17
+ const task = promise().then(() => {
18
+ this.running.delete(task);
19
+ });
20
+ this.running.add(task);
21
+ if (this.running.size >= this.parallelCalls) {
22
+ await Promise.race(this.running);
40
23
  }
41
- void this.next(callback);
42
24
  }
25
+ await Promise.all(this.running);
43
26
  }
44
27
  reset() {
45
28
  this.promises = [];
46
- this.running = 0;
47
- this.index = 0;
29
+ this.running = new Set();
48
30
  }
49
31
  }
50
32
  exports.default = ParallelModule;
@@ -2,6 +2,7 @@ export type ProjectType = 'next.js' | 'react' | 'strapi' | 'node';
2
2
  interface IDefaultProject {
3
3
  name: string;
4
4
  path: string;
5
+ srcPath: string;
5
6
  relativePath: string;
6
7
  type: ProjectType;
7
8
  }
@@ -8,3 +8,5 @@ export declare function writeJSONFile(filePath: string, data: unknown): Promise<
8
8
  export declare function writeRootFile(fileName: string, content: string): Promise<void>;
9
9
  export declare function writeFile(filePath: string, content: string): Promise<void>;
10
10
  export declare function loadFile(filePath: string): Promise<string>;
11
+ export declare function getDirectoriesInPath(rootPath: string): Promise<string[]>;
12
+ export declare function getFilesInPath(rootPath: string): Promise<string[]>;
@@ -10,6 +10,8 @@ exports.writeJSONFile = writeJSONFile;
10
10
  exports.writeRootFile = writeRootFile;
11
11
  exports.writeFile = writeFile;
12
12
  exports.loadFile = loadFile;
13
+ exports.getDirectoriesInPath = getDirectoriesInPath;
14
+ exports.getFilesInPath = getFilesInPath;
13
15
  const fs = require("node:fs/promises");
14
16
  const path = require("path");
15
17
  async function verifyPath(filePath) {
@@ -82,3 +84,43 @@ async function loadFile(filePath) {
82
84
  throw error;
83
85
  }
84
86
  }
87
+ async function getDirectoriesInPath(rootPath) {
88
+ const directories = [];
89
+ try {
90
+ const allContent = await fs.readdir(rootPath);
91
+ for (const content of allContent) {
92
+ const contentPath = path.join(rootPath, content);
93
+ const stats = await fs.stat(contentPath);
94
+ if (stats.isDirectory()) {
95
+ directories.push(content);
96
+ }
97
+ }
98
+ return directories;
99
+ }
100
+ catch (error) {
101
+ console.error(`Error reading directory ${rootPath}:`, error);
102
+ return directories;
103
+ }
104
+ }
105
+ async function getFilesInPath(rootPath) {
106
+ const files = [];
107
+ try {
108
+ const allContent = await fs.readdir(rootPath);
109
+ for (const content of allContent) {
110
+ const contentPath = path.join(rootPath, content);
111
+ const stats = await fs.stat(contentPath);
112
+ if (stats.isFile()) {
113
+ files.push(contentPath);
114
+ }
115
+ else if (stats.isDirectory()) {
116
+ const subFiles = await getFilesInPath(contentPath);
117
+ files.push(...subFiles);
118
+ }
119
+ }
120
+ return files;
121
+ }
122
+ catch (error) {
123
+ console.error(`Error reading directory ${rootPath}:`, error);
124
+ return files;
125
+ }
126
+ }