@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.
- package/dist/commands/ai/add.js +36 -12
- package/dist/commands/ai/docs/index.d.ts +3 -0
- package/dist/commands/ai/docs/index.js +60 -0
- package/dist/commands/ai/docs/modules/generator/index.d.ts +17 -0
- package/dist/commands/ai/docs/modules/generator/index.js +88 -0
- package/dist/commands/ai/docs/types.d.ts +11 -0
- package/dist/commands/ai/docs/types.js +2 -0
- package/dist/commands/ai/generate.js +38 -14
- package/dist/commands/ai/modules/figma/index.js +7 -16
- package/dist/commands/ai/modules/file-manager/index.d.ts +22 -0
- package/dist/commands/ai/modules/file-manager/index.js +156 -0
- package/dist/commands/ai/modules/file-manager/types.d.ts +4 -0
- package/dist/commands/ai/modules/file-manager/types.js +2 -0
- package/dist/commands/ai/modules/generator/index.d.ts +7 -4
- package/dist/commands/ai/modules/generator/index.js +55 -73
- package/dist/commands/ai/modules/generator/types.d.ts +17 -0
- package/dist/commands/ai/modules/generator/types.js +2 -0
- package/dist/commands/ai/modules/project-adder/index.d.ts +2 -3
- package/dist/commands/ai/modules/project-adder/index.js +6 -58
- package/dist/commands/ai/modules/state/index.d.ts +3 -0
- package/dist/commands/ai/modules/state/index.js +15 -19
- package/dist/commands/ai/modules/state/types.d.ts +2 -3
- package/dist/modules/ai-server-module/index.d.ts +15 -0
- package/dist/modules/ai-server-module/index.js +86 -0
- package/dist/modules/ai-server-module/types.d.ts +4 -0
- package/dist/modules/ai-server-module/types.js +2 -0
- package/dist/modules/parallel/index.d.ts +1 -6
- package/dist/modules/parallel/index.js +11 -29
- package/dist/types/project.d.ts +1 -0
- package/dist/utils/files.d.ts +2 -0
- package/dist/utils/files.js +42 -0
- package/dist/utils/project.js +25 -5
- 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
|
|
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
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
|
39
|
+
async fetchStrapiBlock(blockName, blockVariants) {
|
|
47
40
|
const requestBody = {
|
|
48
41
|
name: blockName.replace('block-', ''),
|
|
49
42
|
variants: blockVariants,
|
|
50
43
|
};
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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.
|
|
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
|
|
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
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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 (
|
|
102
|
-
|
|
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
|
-
|
|
118
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
+
}
|
|
@@ -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
|
-
|
|
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
|
|
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
|
|
13
|
+
if (!block) {
|
|
56
14
|
console.error(`Block ${blockName} not found`);
|
|
57
15
|
return;
|
|
58
16
|
}
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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;
|
|
@@ -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
|
-
|
|
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 =
|
|
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
|
|
19
|
-
const promise
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
this.running
|
|
24
|
-
|
|
25
|
-
|
|
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 =
|
|
47
|
-
this.index = 0;
|
|
29
|
+
this.running = new Set();
|
|
48
30
|
}
|
|
49
31
|
}
|
|
50
32
|
exports.default = ParallelModule;
|
package/dist/types/project.d.ts
CHANGED
package/dist/utils/files.d.ts
CHANGED
|
@@ -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[]>;
|
package/dist/utils/files.js
CHANGED
|
@@ -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
|
+
}
|