blend-r 1.1.6
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/README.md +213 -0
- package/dist/helper/ApiHelper.js +766 -0
- package/dist/helper/BasicHelper.js +43 -0
- package/dist/helper/DataHelper.js +231 -0
- package/dist/helper/FrontEndHelper.js +201 -0
- package/dist/helper/fileHelper.js +127 -0
- package/dist/helper/grammarHelper/BlendApiGrammarHelper.js +90 -0
- package/dist/helper/grammarHelper/BlendBasicGrammarHelper.js +135 -0
- package/dist/helper/grammarHelper/BlendDataGrammarHelper.js +47 -0
- package/dist/helper/grammarHelper/GrammarErrorHelper.js +16 -0
- package/dist/index.js +87 -0
- package/dist/parser/blendApi/src/grammar/BlendApiLexer.js +207 -0
- package/dist/parser/blendApi/src/grammar/BlendApiListener.js +3 -0
- package/dist/parser/blendApi/src/grammar/BlendApiParser.js +978 -0
- package/dist/parser/blendData/src/grammar/BlendDataLexer.js +154 -0
- package/dist/parser/blendData/src/grammar/BlendDataListener.js +3 -0
- package/dist/parser/blendData/src/grammar/BlendDataParser.js +642 -0
- package/dist/parser/blendRBasic/src/grammar/BlendRBasicListener.js +3 -0
- package/dist/parser/blendRBasic/src/grammar/blendRBasicLexer.js +184 -0
- package/dist/parser/blendRBasic/src/grammar/blendRBasicParser.js +993 -0
- package/dist/parser/blendRnBasic/src/grammar/BlendRnBasicLexer.js +214 -0
- package/dist/parser/blendRnBasic/src/grammar/BlendRnBasicListener.js +3 -0
- package/dist/parser/blendRnBasic/src/grammar/BlendRnBasicParser.js +1224 -0
- package/dist/types/apiOperationTypes.js +20 -0
- package/dist/types/basicOperationTypes.js +3 -0
- package/dist/types/dataOperationTypes.js +2 -0
- package/dist/types/frontendOperationTypes.js +4 -0
- package/dist/types/generalTypes.js +0 -0
- package/dist/types/mongoOperationTypes.js +12 -0
- package/package.json +36 -0
|
@@ -0,0 +1,766 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const path_1 = __importDefault(require("path"));
|
|
7
|
+
const fileHelper_1 = require("./fileHelper");
|
|
8
|
+
const BlendApiGrammarHelper_1 = __importDefault(require("./grammarHelper/BlendApiGrammarHelper"));
|
|
9
|
+
class ApiHelper {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.baseRoute = 'api';
|
|
12
|
+
this.folderPath = path_1.default.join(process.cwd());
|
|
13
|
+
this.folderName = path_1.default.basename(this.folderPath);
|
|
14
|
+
this.basicFilePath = path_1.default.join(this.folderPath, `${this.folderName}.basic`);
|
|
15
|
+
this.configPath = path_1.default.join(this.folderPath, '.basicConfig');
|
|
16
|
+
this.basicProjectContent = JSON.parse(fileHelper_1.FileHelper.readFile(`${this.configPath}/basicConfig.json`) || "{}");
|
|
17
|
+
}
|
|
18
|
+
parseSpec() {
|
|
19
|
+
let mainApiObjList = [];
|
|
20
|
+
this.basicProjectContent.apiModuleList.forEach(apiModule => {
|
|
21
|
+
const filePath = path_1.default.join(this.folderPath, `spec/api/${apiModule}.api`);
|
|
22
|
+
const specCode = fileHelper_1.FileHelper.readFile(filePath);
|
|
23
|
+
const json = new BlendApiGrammarHelper_1.default().parseBlendApi(specCode, this.basicProjectContent.dataModuleList || []);
|
|
24
|
+
if (!json.isValid) {
|
|
25
|
+
throw new Error("Error while parsing the syntax");
|
|
26
|
+
}
|
|
27
|
+
mainApiObjList.push(json.json);
|
|
28
|
+
});
|
|
29
|
+
fileHelper_1.FileHelper.writeFile(`${this.configPath}/apiConfig.json`, JSON.stringify(mainApiObjList));
|
|
30
|
+
}
|
|
31
|
+
doFrontEndApiGenerations() {
|
|
32
|
+
this.writeStoreFiles();
|
|
33
|
+
this.createRequiredFiles();
|
|
34
|
+
}
|
|
35
|
+
createRequiredFiles() {
|
|
36
|
+
const apiMainSectionList = JSON.parse(fileHelper_1.FileHelper.readFile(`${this.configPath}/apiConfig.json`));
|
|
37
|
+
// const rnSectionList: IReactSection[] = JSON.parse(FileHelper.readFile(`${this.configPath}/reactConfig.json`));
|
|
38
|
+
// rnSectionList.forEach(rnSection => {
|
|
39
|
+
// const rnFolderPath = path.join(this.folderPath, `module/${rnSection.name}/react`);
|
|
40
|
+
// rnSection.reactModuleList.forEach(rnModule => {
|
|
41
|
+
// let currentApiSection: IApiMainSection = apiMainSectionList.find(item => item.name === rnSection.name)
|
|
42
|
+
// const rnProjectPath = path.join(rnFolderPath, rnModule.name);
|
|
43
|
+
const rapcode = this.generateRmoteApiPointsCode();
|
|
44
|
+
fileHelper_1.FileHelper.createFile(`${this.folderPath}/src/remote-api-point.ts`, rapcode);
|
|
45
|
+
fileHelper_1.FileHelper.createFile(`${this.folderPath}/src-gen/data/common.ts`, commonApiDataCode);
|
|
46
|
+
fileHelper_1.FileHelper.createFile(`${this.folderPath}/src/redux/store/store.ts`, mainStoreCode);
|
|
47
|
+
// FileHelper.createFile(`${this.folderPath}/src/redux/store/saga.ts`, mainSagaCode);
|
|
48
|
+
fileHelper_1.FileHelper.createFile(`${this.folderPath}/src/redux/store/snackbar/snackbarSlice.ts`, snackbarSliceCode);
|
|
49
|
+
fileHelper_1.FileHelper.createFile(`${this.folderPath}/src/redux/hooks.ts`, hooksCode);
|
|
50
|
+
}
|
|
51
|
+
generateRmoteApiPointsCode() {
|
|
52
|
+
let code = `
|
|
53
|
+
import axios from 'axios';
|
|
54
|
+
const apiUrl = import.meta.env.VITE_API_URL;
|
|
55
|
+
${this.basicProjectContent.apiModuleList.reduce((acc, curVal) => {
|
|
56
|
+
acc = acc + `export const ${curVal}Api = axios.create({
|
|
57
|
+
baseURL: apiUrl||'http://localhost:8000', // Replace with your API base URL
|
|
58
|
+
headers: {
|
|
59
|
+
Authorization: localStorage.getItem("authToken")||""
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
\n
|
|
63
|
+
`;
|
|
64
|
+
return acc;
|
|
65
|
+
}, "")}
|
|
66
|
+
`;
|
|
67
|
+
return code;
|
|
68
|
+
}
|
|
69
|
+
generateRoleSliceCode() {
|
|
70
|
+
const code = `
|
|
71
|
+
import { createSlice, type PayloadAction } from "@reduxjs/toolkit";
|
|
72
|
+
import type { Role } from "./type";
|
|
73
|
+
|
|
74
|
+
interface RolesState {
|
|
75
|
+
roles: Role[];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
const initialState: RolesState = {
|
|
80
|
+
roles: []
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// ---- Slice
|
|
84
|
+
const rolesSlice = createSlice({
|
|
85
|
+
name: "roles",
|
|
86
|
+
initialState,
|
|
87
|
+
reducers: {
|
|
88
|
+
setRoles(state, action: PayloadAction<Role[]>) {
|
|
89
|
+
state.roles = action.payload;
|
|
90
|
+
},
|
|
91
|
+
addRole(state, action: PayloadAction<Role>) {
|
|
92
|
+
if (!state.roles.includes(action.payload)) {
|
|
93
|
+
state.roles.push(action.payload);
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
removeRole(state, action: PayloadAction<Role>) {
|
|
97
|
+
state.roles = state.roles.filter(r => r !== action.payload);
|
|
98
|
+
},
|
|
99
|
+
clearRoles(state) {
|
|
100
|
+
state.roles = [];
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// ---- Actions
|
|
106
|
+
export const { setRoles, addRole, removeRole, clearRoles } = rolesSlice.actions;
|
|
107
|
+
|
|
108
|
+
// ---- Reducer
|
|
109
|
+
export default rolesSlice.reducer;
|
|
110
|
+
|
|
111
|
+
`;
|
|
112
|
+
return code;
|
|
113
|
+
}
|
|
114
|
+
generateRolesGetterCode() {
|
|
115
|
+
const code = `
|
|
116
|
+
import type { RootState } from "@/redux/store/store";
|
|
117
|
+
import type { Role } from "./type";
|
|
118
|
+
export const selectRoles = (state: RootState) => state.roles.roles;
|
|
119
|
+
|
|
120
|
+
// Generic checker
|
|
121
|
+
export const hasRole = (role: Role) => (state: RootState) =>
|
|
122
|
+
state.roles.roles.includes(role);
|
|
123
|
+
export const hasAnyRole = (roles: Role[]) => (state: RootState) =>
|
|
124
|
+
roles.some(role => state.roles.roles.includes(role));
|
|
125
|
+
|
|
126
|
+
${this.basicProjectContent.frontend.roleList.reduce((acc, role) => {
|
|
127
|
+
acc = acc + `
|
|
128
|
+
export const has${role}Role = (state: RootState) =>
|
|
129
|
+
state.roles.roles.includes("${role}");
|
|
130
|
+
`;
|
|
131
|
+
return acc;
|
|
132
|
+
}, '')}
|
|
133
|
+
`;
|
|
134
|
+
return code;
|
|
135
|
+
}
|
|
136
|
+
generateRolesTypeCode() {
|
|
137
|
+
const code = `
|
|
138
|
+
export type Role = ${this.basicProjectContent.frontend.roleList.map(role => `"${role}"`).join(' | ')};
|
|
139
|
+
`;
|
|
140
|
+
return this.basicProjectContent.frontend.roleList.length > 0 ? code : '';
|
|
141
|
+
}
|
|
142
|
+
generateRoleRelatedFiles() {
|
|
143
|
+
const roleSliceCode = this.generateRoleSliceCode();
|
|
144
|
+
const rolesGetterCode = this.generateRolesGetterCode();
|
|
145
|
+
const rolesTypeCode = this.generateRolesTypeCode();
|
|
146
|
+
const rolePath = path_1.default.join(this.folderPath, `src-gen/redux/roles`);
|
|
147
|
+
fileHelper_1.FileHelper.writeFile(`${rolePath}/rolesSlice.ts`, roleSliceCode);
|
|
148
|
+
fileHelper_1.FileHelper.writeFile(`${rolePath}/rolesGetter.ts`, rolesGetterCode);
|
|
149
|
+
fileHelper_1.FileHelper.writeFile(`${rolePath}/type.ts`, rolesTypeCode);
|
|
150
|
+
}
|
|
151
|
+
writeStoreFiles() {
|
|
152
|
+
const apiMainSectionList = JSON.parse(fileHelper_1.FileHelper.readFile(`${this.configPath}/apiConfig.json`));
|
|
153
|
+
const allApiSections = apiMainSectionList.flatMap((section) => section.apiSectionList.map((api) => (Object.assign(Object.assign({}, api), { sectionName: section.name }))));
|
|
154
|
+
const reducerCode = this.generateReducersCode(allApiSections);
|
|
155
|
+
this.generateRoleRelatedFiles();
|
|
156
|
+
apiMainSectionList.forEach(expressSection => {
|
|
157
|
+
const rnApiPath = path_1.default.join(this.folderPath, `src-gen/redux/${expressSection.name}`);
|
|
158
|
+
const rnSelectorPath = path_1.default.join(this.folderPath, `src/redux/selectors/${expressSection.name}`);
|
|
159
|
+
const rnReducerPath = path_1.default.join(this.folderPath, `src-gen/redux/gen-reducers.ts`);
|
|
160
|
+
// const rnSagaPath = path.join(this.folderPath, `src-gen/redux/gen-root-saga.ts`);
|
|
161
|
+
const rootSagaCode = this.generateRootSagaCode(expressSection.apiSectionList, expressSection.name);
|
|
162
|
+
fileHelper_1.FileHelper.writeFile(rnReducerPath, reducerCode);
|
|
163
|
+
// FileHelper.writeFile(rnSagaPath, rootSagaCode);
|
|
164
|
+
expressSection.apiSectionList.forEach(apiSection => {
|
|
165
|
+
const apiSectionSlicePath = path_1.default.join(rnApiPath, apiSection.name, `${apiSection.name}Slice.ts`);
|
|
166
|
+
const apiSectionSelectorPath = path_1.default.join(rnApiPath, apiSection.name, `selector.ts`);
|
|
167
|
+
const apiSectionDataPath = path_1.default.join(rnApiPath, apiSection.name, `data.ts`);
|
|
168
|
+
const apiSectionActionPath = path_1.default.join(rnApiPath, apiSection.name, `action.ts`);
|
|
169
|
+
const apiSelectorPath = path_1.default.join(rnSelectorPath, `${apiSection.name}.ts`);
|
|
170
|
+
// const apiSectionSagaPath = path.join(rnApiPath, apiSection.name, `${apiSection.name}Saga.ts`);
|
|
171
|
+
const sliceCode = this.generateSliceCode(apiSection);
|
|
172
|
+
const dataCode = this.generateApiDatacode(apiSection);
|
|
173
|
+
const actionCode = this.generateApiActioncode(apiSection, expressSection);
|
|
174
|
+
const selectorCode = this.generateApiSelectorCode(apiSection);
|
|
175
|
+
// const sagaCode = this.generateSagaCode(apiSection);
|
|
176
|
+
fileHelper_1.FileHelper.writeFile(apiSectionSlicePath, sliceCode);
|
|
177
|
+
fileHelper_1.FileHelper.writeFile(apiSectionSelectorPath, selectorCode);
|
|
178
|
+
fileHelper_1.FileHelper.createFile(apiSelectorPath, `
|
|
179
|
+
import { RootState } from "@/redux/store/store";
|
|
180
|
+
import * as ${apiSection.name}Selector from "src-gen/redux/${expressSection.name}/${apiSection.name}/selector";`);
|
|
181
|
+
if (!this.isEmptyOrWhitespace(dataCode)) {
|
|
182
|
+
fileHelper_1.FileHelper.writeFile(apiSectionDataPath, dataCode);
|
|
183
|
+
}
|
|
184
|
+
fileHelper_1.FileHelper.writeFile(apiSectionActionPath, actionCode);
|
|
185
|
+
// FileHelper.writeFile(apiSectionSagaPath, sagaCode);
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
isEmptyOrWhitespace(str) {
|
|
190
|
+
return str.trim().length === 0;
|
|
191
|
+
}
|
|
192
|
+
generateSliceCode(apiSection) {
|
|
193
|
+
const filteredApiListForData = apiSection.apiList.filter(api => {
|
|
194
|
+
const inputKeyList = Object.keys(api.input);
|
|
195
|
+
const outputKeyList = Object.keys(api.output);
|
|
196
|
+
return inputKeyList.length > 0 || outputKeyList.length > 0;
|
|
197
|
+
});
|
|
198
|
+
const code = `
|
|
199
|
+
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
|
200
|
+
import {${apiSection.apiList.reduce((acc, curVal) => {
|
|
201
|
+
acc = acc + `${curVal.name}AsyncThunk,`;
|
|
202
|
+
return acc;
|
|
203
|
+
}, '')}} from './action';
|
|
204
|
+
|
|
205
|
+
${filteredApiListForData.length > 0 ? `import { ${filteredApiListForData.reduce((acc, curVal) => {
|
|
206
|
+
const inputKeyList = Object.keys(curVal.input);
|
|
207
|
+
const outputKeyList = Object.keys(curVal.output);
|
|
208
|
+
// const inputDataTypeName: string = (`${apiSection.name}_${curVal.name}_Input`).toUpperCase();
|
|
209
|
+
const outputDataTypeName = (`${apiSection.name}_${curVal.name}_Output`).toUpperCase();
|
|
210
|
+
// acc = acc + `${inputKeyList.length > 0 ? inputDataTypeName + `,I_${inputDataTypeName}`+ ',' : ''}`;
|
|
211
|
+
acc = acc + `${outputKeyList.length > 0 ? outputDataTypeName + `,I_${outputDataTypeName}` + ',' : ''}`;
|
|
212
|
+
return acc;
|
|
213
|
+
}, '')} } from "./data";` : ''}
|
|
214
|
+
|
|
215
|
+
${apiSection.apiList.reduce((acc, curVal) => {
|
|
216
|
+
var _a, _b, _c;
|
|
217
|
+
if ((_a = curVal === null || curVal === void 0 ? void 0 : curVal.directOutput) === null || _a === void 0 ? void 0 : _a.name) {
|
|
218
|
+
const [moduleName, dataName] = (_c = (_b = curVal === null || curVal === void 0 ? void 0 : curVal.directOutput) === null || _b === void 0 ? void 0 : _b.name) === null || _c === void 0 ? void 0 : _c.split("->");
|
|
219
|
+
console.log(dataName, moduleName, "DataName...........");
|
|
220
|
+
if (dataName) {
|
|
221
|
+
const dataTypeName = `${dataName === null || dataName === void 0 ? void 0 : dataName.replace("[]", "")}`;
|
|
222
|
+
acc = acc + `import {${dataTypeName},I_${dataTypeName}} from "../../../data/${moduleName}";`;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return acc;
|
|
226
|
+
}, '')}
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
import { ApiStatus } from "../../../data/common";
|
|
230
|
+
interface ${apiSection.name}State {
|
|
231
|
+
${apiSection.apiList.reduce((acc, curVal) => {
|
|
232
|
+
var _a, _b;
|
|
233
|
+
const [moduleName, dataName] = ((_b = (_a = curVal === null || curVal === void 0 ? void 0 : curVal.directOutput) === null || _a === void 0 ? void 0 : _a.name) === null || _b === void 0 ? void 0 : _b.split("->")) || [];
|
|
234
|
+
acc = acc + `${curVal.name}: {
|
|
235
|
+
data: ${Object.keys(curVal.output).length > 0 ? `I_${apiSection.name.toUpperCase()}_${curVal.name.toUpperCase()}_OUTPUT` : dataName ? `I_${dataName}` : "any"},\n
|
|
236
|
+
status: ApiStatus,
|
|
237
|
+
error:string|null
|
|
238
|
+
}
|
|
239
|
+
`;
|
|
240
|
+
return acc;
|
|
241
|
+
}, "")}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const initialState: ${apiSection.name}State = {
|
|
245
|
+
${apiSection.apiList.reduce((acc, curVal) => {
|
|
246
|
+
var _a, _b;
|
|
247
|
+
const [moduleName, dataName] = ((_b = (_a = curVal === null || curVal === void 0 ? void 0 : curVal.directOutput) === null || _a === void 0 ? void 0 : _a.name) === null || _b === void 0 ? void 0 : _b.split("->")) || [];
|
|
248
|
+
const isOutputDataArray = (dataName || "").includes("[]");
|
|
249
|
+
acc = acc + `${curVal.name}:{
|
|
250
|
+
data: ${Object.keys(curVal.output).length > 0 ? `new ${apiSection.name.toUpperCase()}_${curVal.name.toUpperCase()}_OUTPUT().toJSON()` : (dataName && !isOutputDataArray) ? `new ${dataName}().toJSON()` : (dataName && isOutputDataArray) ? '[]' : "null"},
|
|
251
|
+
status: ApiStatus.Idle,
|
|
252
|
+
error: null
|
|
253
|
+
},\n`;
|
|
254
|
+
return acc;
|
|
255
|
+
}, "")}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export const ${apiSection.name}Slice = createSlice({
|
|
259
|
+
name: "${apiSection.name}",
|
|
260
|
+
initialState,
|
|
261
|
+
reducers: {
|
|
262
|
+
reset${apiSection.name}Reducer: () => initialState
|
|
263
|
+
},
|
|
264
|
+
extraReducers: (builder) =>{
|
|
265
|
+
builder.
|
|
266
|
+
${apiSection.apiList.reduce((acc, curVal, currentIndex) => {
|
|
267
|
+
acc = acc + `addCase(${curVal.name}AsyncThunk.pending, state => {
|
|
268
|
+
state.${curVal.name}.status= ApiStatus.Loading;
|
|
269
|
+
state.${curVal.name}.error= null;
|
|
270
|
+
})\n\t\t.addCase(${curVal.name}AsyncThunk.fulfilled,(state, action) => {
|
|
271
|
+
state.${curVal.name}.status = ApiStatus.Success;
|
|
272
|
+
state.${curVal.name}.data = action.payload;
|
|
273
|
+
state.${curVal.name}.error = null;
|
|
274
|
+
})\n\t\t.addCase(${curVal.name}AsyncThunk.rejected, (state, action) => {
|
|
275
|
+
state.${curVal.name}.status = ApiStatus.Failed;
|
|
276
|
+
state.${curVal.name}.error = action.payload as string;
|
|
277
|
+
})\n\t\t${currentIndex < apiSection.apiList.length - 1 ? '.' : ''}`;
|
|
278
|
+
return acc;
|
|
279
|
+
}, "")}
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
export const {reset${apiSection.name}Reducer} = ${apiSection.name}Slice.actions;
|
|
284
|
+
export default ${apiSection.name}Slice.reducer;
|
|
285
|
+
`;
|
|
286
|
+
return code;
|
|
287
|
+
}
|
|
288
|
+
generateSagaCode(apiSection) {
|
|
289
|
+
const code = `
|
|
290
|
+
import { put, takeLatest } from "redux-saga/effects";
|
|
291
|
+
import { PayloadAction } from "@reduxjs/toolkit";
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
import { ${apiSection.apiList.reduce((acc, curVal) => {
|
|
295
|
+
acc = acc + `${curVal.name}Api,`;
|
|
296
|
+
return acc;
|
|
297
|
+
}, '')} }from './action';
|
|
298
|
+
|
|
299
|
+
import { ${apiSection.apiList.reduce((acc, curVal) => {
|
|
300
|
+
acc = acc + `${curVal.name}SuccessAction,${curVal.name}ErrorAction,`;
|
|
301
|
+
return acc;
|
|
302
|
+
}, '')} } from "./${apiSection.name}Slice";
|
|
303
|
+
|
|
304
|
+
${apiSection.apiList.reduce((acc, curVal) => {
|
|
305
|
+
const inputKeyList = Object.keys(curVal.input);
|
|
306
|
+
acc = acc + `
|
|
307
|
+
function* ${curVal.name}Saga(action: PayloadAction<any>): any {
|
|
308
|
+
try {
|
|
309
|
+
const response: any = yield ${curVal.name}Api(${inputKeyList.length > 0 ? `action.payload` : ``})
|
|
310
|
+
yield put(${curVal.name}SuccessAction(response.data))
|
|
311
|
+
} catch(e: any) {
|
|
312
|
+
yield put(${curVal.name}ErrorAction(e));
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
export function* watch${apiSection.name}${curVal.name}() {
|
|
317
|
+
yield takeLatest("${apiSection.name}/${curVal.name}Action", ${curVal.name}Saga);
|
|
318
|
+
}
|
|
319
|
+
`;
|
|
320
|
+
return acc;
|
|
321
|
+
}, '')}
|
|
322
|
+
|
|
323
|
+
`;
|
|
324
|
+
return code;
|
|
325
|
+
}
|
|
326
|
+
generateReducersCode(apiSectionList) {
|
|
327
|
+
const code = `
|
|
328
|
+
${apiSectionList.reduce((acc, curVal) => {
|
|
329
|
+
console.log(curVal.name, "APINAME!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
|
330
|
+
acc = acc + `
|
|
331
|
+
import ${curVal.name}Reducer from './${curVal.sectionName}/${curVal.name}/${curVal.name}Slice';\n`;
|
|
332
|
+
return acc;
|
|
333
|
+
}, '')}
|
|
334
|
+
|
|
335
|
+
export const GeneratedReducers = {
|
|
336
|
+
${apiSectionList.reduce((acc, curVal) => {
|
|
337
|
+
acc = acc + `${curVal.name.toLowerCase()}: ${curVal.name}Reducer,`;
|
|
338
|
+
return acc;
|
|
339
|
+
}, '')}
|
|
340
|
+
}
|
|
341
|
+
`;
|
|
342
|
+
return code;
|
|
343
|
+
}
|
|
344
|
+
generateApiActioncode(apiSection, expressSection) {
|
|
345
|
+
const filteredApiListForData = apiSection.apiList.filter(api => {
|
|
346
|
+
const inputKeyList = Object.keys(api.input);
|
|
347
|
+
const outputKeyList = Object.keys(api.output);
|
|
348
|
+
return inputKeyList.length > 0 || outputKeyList.length > 0;
|
|
349
|
+
});
|
|
350
|
+
const code = `
|
|
351
|
+
import { createAsyncThunk } from "@reduxjs/toolkit";
|
|
352
|
+
import axios, { AxiosError } from 'axios';
|
|
353
|
+
import {${expressSection.name}Api} from "../../../../src/remote-api-point";
|
|
354
|
+
${filteredApiListForData.length > 0 ? `import { ${filteredApiListForData.reduce((acc, curVal) => {
|
|
355
|
+
const inputKeyList = Object.keys(curVal.input);
|
|
356
|
+
const outputKeyList = Object.keys(curVal.output);
|
|
357
|
+
const inputDataTypeName = (`${apiSection.name}_${curVal.name}_Input`).toUpperCase();
|
|
358
|
+
const outputDataTypeName = (`${apiSection.name}_${curVal.name}_Output`).toUpperCase();
|
|
359
|
+
acc = acc + `${inputKeyList.length > 0 ? inputDataTypeName + ',' : ''}`;
|
|
360
|
+
acc = acc + `${outputKeyList.length > 0 ? outputDataTypeName + ',' : ''}`;
|
|
361
|
+
return acc;
|
|
362
|
+
}, '')} } from "./data";` : ''}
|
|
363
|
+
|
|
364
|
+
${apiSection.apiList.reduce((acc, curVal) => {
|
|
365
|
+
var _a, _b, _c;
|
|
366
|
+
if ((_a = curVal === null || curVal === void 0 ? void 0 : curVal.directOutput) === null || _a === void 0 ? void 0 : _a.name) {
|
|
367
|
+
const [moduleName, dataName] = (_c = (_b = curVal === null || curVal === void 0 ? void 0 : curVal.directOutput) === null || _b === void 0 ? void 0 : _b.name) === null || _c === void 0 ? void 0 : _c.split("->");
|
|
368
|
+
// console.log(dataName,moduleName,"DataName...........")
|
|
369
|
+
if (dataName) {
|
|
370
|
+
acc = acc + `import * as ${moduleName} from "../../../data/${moduleName}";`;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
return acc;
|
|
374
|
+
}, '')}
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
const showError = (err: AxiosError) => {
|
|
381
|
+
const errorResponse: any = err.response?.data;
|
|
382
|
+
if (errorResponse) {
|
|
383
|
+
return {status: err.status,data: errorResponse}
|
|
384
|
+
}
|
|
385
|
+
else {
|
|
386
|
+
return {status: err.status||500, data: err.message||"Unknown Error"}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
${apiSection.apiList.reduce((acc, curVal) => {
|
|
395
|
+
var _a, _b;
|
|
396
|
+
const inputKeyList = Object.keys(curVal.input);
|
|
397
|
+
const outputKeyList = Object.keys(curVal.output);
|
|
398
|
+
const inputDataTypeName = (`${apiSection.name}_${curVal.name}_Input`).toUpperCase();
|
|
399
|
+
const outputDataTypeName = (`${apiSection.name}_${curVal.name}_Output`).toUpperCase();
|
|
400
|
+
const [moduleName, dataName] = ((_b = (_a = curVal === null || curVal === void 0 ? void 0 : curVal.directOutput) === null || _a === void 0 ? void 0 : _a.name) === null || _b === void 0 ? void 0 : _b.split("->")) || [];
|
|
401
|
+
acc = acc + `
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
export const ${curVal.name}Api = async (${inputKeyList.length > 0 ? `input: ${inputDataTypeName},` : ``} ) => {
|
|
405
|
+
return ${expressSection.name}Api.${curVal.type.toLowerCase()}('${curVal.url}',${inputKeyList.length > 0 ? `${curVal.type == 'POST' ? 'input' : '{params: input.toJSON()}'}` : ''});
|
|
406
|
+
}
|
|
407
|
+
export const ${curVal.name}AsyncThunk = createAsyncThunk<${outputKeyList.length > 0 ? outputDataTypeName : dataName ? `${moduleName}.${dataName}` : 'any'},${inputKeyList.length > 0 ? `${inputDataTypeName}` : `void`},any>('${apiSection.name}/${curVal.name}', async (${inputKeyList.length > 0 ? `input: ${inputDataTypeName}` : `_`}, { rejectWithValue }) => {
|
|
408
|
+
return call${this.capitalizeFirstLetter(curVal.name)}Api(${inputKeyList.length > 0 ? `input,` : ''} output => {
|
|
409
|
+
return output
|
|
410
|
+
},error=> {
|
|
411
|
+
return rejectWithValue(error)
|
|
412
|
+
})
|
|
413
|
+
})
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
export const call${this.capitalizeFirstLetter(curVal.name)}Api = async (${inputKeyList.length > 0 ? `input: ${inputDataTypeName},` : ``} output: (output: ${outputKeyList.length > 0 ? outputDataTypeName : dataName ? `${moduleName}.${dataName}` : 'any'}) => any,error?: (errMsg: any) => void) => {
|
|
417
|
+
try {
|
|
418
|
+
//const { data } = await ${expressSection.name}Api.${curVal.type.toLowerCase()}('${this.getApiName(apiSection.name)}/${this.getApiName(curVal.name)}',${inputKeyList.length > 0 ? `${curVal.type == 'POST' ? 'input' : '{params: input.toJSON()}'}` : ''});
|
|
419
|
+
const { data } = await ${curVal.name}Api(${inputKeyList.length > 0 ? `${curVal.type == 'POST' ? 'input' : 'input'}` : ''});
|
|
420
|
+
return output(data);
|
|
421
|
+
} catch (err: any) {
|
|
422
|
+
if(error) {
|
|
423
|
+
return error(showError(err));
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
`;
|
|
429
|
+
return acc;
|
|
430
|
+
}, '')}
|
|
431
|
+
|
|
432
|
+
`;
|
|
433
|
+
return code;
|
|
434
|
+
}
|
|
435
|
+
generateApiSelectorCode(apiSection) {
|
|
436
|
+
const code = `
|
|
437
|
+
import { RootState } from "@/redux/store/store";
|
|
438
|
+
|
|
439
|
+
${apiSection.apiList.reduce((acc, curVal) => {
|
|
440
|
+
acc = acc +
|
|
441
|
+
`export const select${this.capitalizeFirstLetter(curVal.name)}Data = (state: RootState) => state.${apiSection.name.toLocaleLowerCase()}.${curVal.name}.data;\n`;
|
|
442
|
+
return acc;
|
|
443
|
+
}, '')}
|
|
444
|
+
`;
|
|
445
|
+
return code;
|
|
446
|
+
}
|
|
447
|
+
generateRootSagaCode(apiSectionList, expressSectionName) {
|
|
448
|
+
const code = `
|
|
449
|
+
import { all, fork } from "redux-saga/effects";
|
|
450
|
+
${apiSectionList.reduce((acc, curVal) => {
|
|
451
|
+
acc = acc + `
|
|
452
|
+
import{
|
|
453
|
+
${curVal.apiList.reduce((apiAcc, apiCurVal) => {
|
|
454
|
+
apiAcc = apiAcc + `
|
|
455
|
+
watch${curVal.name}${apiCurVal.name},
|
|
456
|
+
`;
|
|
457
|
+
return apiAcc;
|
|
458
|
+
}, '')}
|
|
459
|
+
} from './${expressSectionName}/${curVal.name}/${curVal.name}Saga';\n
|
|
460
|
+
`;
|
|
461
|
+
return acc;
|
|
462
|
+
}, '')}
|
|
463
|
+
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
const genRootSaga = [
|
|
468
|
+
|
|
469
|
+
${apiSectionList.reduce((acc, curVal) => {
|
|
470
|
+
acc = acc + `
|
|
471
|
+
|
|
472
|
+
${curVal.apiList.reduce((apiAcc, apiCurVal) => {
|
|
473
|
+
apiAcc = apiAcc + `
|
|
474
|
+
watch${curVal.name}${apiCurVal.name}()
|
|
475
|
+
,
|
|
476
|
+
`;
|
|
477
|
+
return apiAcc;
|
|
478
|
+
}, '')}
|
|
479
|
+
|
|
480
|
+
`;
|
|
481
|
+
return acc;
|
|
482
|
+
}, '')}
|
|
483
|
+
|
|
484
|
+
];
|
|
485
|
+
|
|
486
|
+
export default genRootSaga;
|
|
487
|
+
`;
|
|
488
|
+
return code;
|
|
489
|
+
}
|
|
490
|
+
getApiName(apiName) {
|
|
491
|
+
return apiName.replace(/[A-Z]/g, m => "-" + m.toLowerCase()).replace(/^-/, '');
|
|
492
|
+
}
|
|
493
|
+
capitalizeFirstLetter(val) {
|
|
494
|
+
return val.charAt(0).toUpperCase() + val.slice(1);
|
|
495
|
+
}
|
|
496
|
+
generateApiDatacode(apiSection) {
|
|
497
|
+
return this.generateSampleApiDataCode(apiSection, "react-native");
|
|
498
|
+
}
|
|
499
|
+
generateSampleApiDataCode(apiSection, type = "api") {
|
|
500
|
+
const imports = new Set(); // Collect unique imports
|
|
501
|
+
const code = `
|
|
502
|
+
${apiSection.apiList.reduce((acc, api) => {
|
|
503
|
+
const inputKeyList = Object.keys(api.input);
|
|
504
|
+
const outputKeyList = api.output ? Object.keys(api.output) : [];
|
|
505
|
+
const inputDataTypeName = (`${apiSection.name}_${api.name}_Input`).toUpperCase();
|
|
506
|
+
const outputDataTypeName = (`${apiSection.name}_${api.name}_Output`).toUpperCase();
|
|
507
|
+
inputKeyList.forEach(inputKey => {
|
|
508
|
+
const typeParts = api.input[inputKey].type.split("->");
|
|
509
|
+
if (typeParts.length === 2) {
|
|
510
|
+
const [module, typeName] = typeParts;
|
|
511
|
+
const baseTypeName = typeName.endsWith("[]") ? typeName.slice(0, -2) : typeName;
|
|
512
|
+
if (type === "api") {
|
|
513
|
+
imports.add(`import { ${baseTypeName} } from '../data/${module}';`);
|
|
514
|
+
}
|
|
515
|
+
else {
|
|
516
|
+
imports.add(`import { ${baseTypeName} } from 'src-gen/data/${module}';`);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
});
|
|
520
|
+
outputKeyList.forEach(outputKey => {
|
|
521
|
+
const typeParts = api.output[outputKey].type.split("->");
|
|
522
|
+
if (typeParts.length === 2) {
|
|
523
|
+
const [module, typeName] = typeParts;
|
|
524
|
+
const baseTypeName = typeName.endsWith("[]") ? typeName.slice(0, -2) : typeName;
|
|
525
|
+
if (type === "api") {
|
|
526
|
+
imports.add(`import { ${baseTypeName} } from '../data/${module}';`);
|
|
527
|
+
}
|
|
528
|
+
else {
|
|
529
|
+
imports.add(`import { ${baseTypeName} } from 'src-gen/data/${module}';`);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
});
|
|
533
|
+
acc = acc + `
|
|
534
|
+
|
|
535
|
+
${inputKeyList.length > 0 ? `
|
|
536
|
+
export class ${inputDataTypeName} {
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
constructor(
|
|
540
|
+
${inputKeyList
|
|
541
|
+
.map((inputKey) => ` public ${inputKey}: ${this.resolveType(api.input[inputKey].type)}${!api.input[inputKey].required ? '|undefined' : ''} = ${this.getDefaultValue(api.input[inputKey])},`)
|
|
542
|
+
.join('\n')}
|
|
543
|
+
) {}
|
|
544
|
+
|
|
545
|
+
static fromJSON(jsonObj: any):${inputDataTypeName} {
|
|
546
|
+
return new ${inputDataTypeName}(
|
|
547
|
+
${inputKeyList
|
|
548
|
+
.map((inputKey) => this.generateFromJSONField(Object.assign(Object.assign({}, api.input[inputKey]), { name: inputKey })))
|
|
549
|
+
.join(',\n')}
|
|
550
|
+
);
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
toJSON():any {
|
|
554
|
+
return {
|
|
555
|
+
${inputKeyList
|
|
556
|
+
.map((inputKey) => this.generateToJSONField(Object.assign(Object.assign({}, api.input[inputKey]), { name: inputKey })))
|
|
557
|
+
.join('\n')}
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
|
|
562
|
+
}\n
|
|
563
|
+
|
|
564
|
+
export interface I_${inputDataTypeName} {
|
|
565
|
+
${inputKeyList
|
|
566
|
+
.map((inputKey) => ` ${inputKey}: ${this.resolveType(api.input[inputKey].type)}${!api.input[inputKey].required ? '|undefined' : ''},`)
|
|
567
|
+
.join('\n')}
|
|
568
|
+
}
|
|
569
|
+
` : ''}
|
|
570
|
+
|
|
571
|
+
${outputKeyList.length > 0 ? `export class ${outputDataTypeName} {
|
|
572
|
+
|
|
573
|
+
constructor(
|
|
574
|
+
${outputKeyList
|
|
575
|
+
.map((outputKey) => ` public ${outputKey}: ${this.resolveType(api.output[outputKey].type)}${!api.output[outputKey].required ? '|undefined' : ''} = ${this.getDefaultValue(api.output[outputKey])},`)
|
|
576
|
+
.join('\n')}
|
|
577
|
+
) {}
|
|
578
|
+
|
|
579
|
+
static fromJSON(jsonObj: any):${outputDataTypeName} {
|
|
580
|
+
return new ${outputDataTypeName}(
|
|
581
|
+
${outputKeyList
|
|
582
|
+
.map((outputKey) => this.generateFromJSONField(Object.assign(Object.assign({}, api.output[outputKey]), { name: outputKey })))
|
|
583
|
+
.join(',\n')}
|
|
584
|
+
);
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
|
|
588
|
+
toJSON():any {
|
|
589
|
+
return {
|
|
590
|
+
${outputKeyList
|
|
591
|
+
.map((outputKey) => this.generateToJSONField(Object.assign(Object.assign({}, api.output[outputKey]), { name: outputKey })))
|
|
592
|
+
.join('\n')}
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
export interface I_${outputDataTypeName} {
|
|
597
|
+
${outputKeyList
|
|
598
|
+
.map((outputKey) => ` ${outputKey}: ${this.resolveType(api.output[outputKey].type)}${!api.output[outputKey].required ? '|undefined' : ''},`)
|
|
599
|
+
.join('\n')}
|
|
600
|
+
}
|
|
601
|
+
` : ''}
|
|
602
|
+
|
|
603
|
+
`;
|
|
604
|
+
return acc;
|
|
605
|
+
}, "")}
|
|
606
|
+
`;
|
|
607
|
+
return Array.from(imports).join('\n') + code;
|
|
608
|
+
}
|
|
609
|
+
resolveType(type) {
|
|
610
|
+
const typeParts = type.split("->");
|
|
611
|
+
const baseType = typeParts.length === 2 ? typeParts[1] : type;
|
|
612
|
+
return baseType.endsWith("[]") ? `${baseType.slice(0, -2)}[]` : baseType; // Handle array types
|
|
613
|
+
}
|
|
614
|
+
getDefaultValue(field) {
|
|
615
|
+
const typeParts = field.type.split("->");
|
|
616
|
+
const baseType = typeParts.length === 2 ? typeParts[1] : field.type;
|
|
617
|
+
if (baseType.endsWith("[]")) {
|
|
618
|
+
return "[]"; // Default value for arrays
|
|
619
|
+
}
|
|
620
|
+
if (typeParts.length === 2) {
|
|
621
|
+
const [, typeName] = typeParts;
|
|
622
|
+
const baseTypeName = typeName.endsWith("[]") ? typeName.slice(0, -2) : typeName;
|
|
623
|
+
return field.required ? `new ${baseTypeName}()` : "undefined"; // Instantiate the imported class
|
|
624
|
+
}
|
|
625
|
+
switch (field.type) {
|
|
626
|
+
case "string":
|
|
627
|
+
return field.required ? "''" : "undefined";
|
|
628
|
+
case "object":
|
|
629
|
+
return field.required ? "{}" : "undefined";
|
|
630
|
+
case "boolean":
|
|
631
|
+
return field.required ? "false" : "undefined";
|
|
632
|
+
case "number":
|
|
633
|
+
return field.required ? "0" : "undefined";
|
|
634
|
+
default:
|
|
635
|
+
return "null";
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
generateFromJSONField(field) {
|
|
639
|
+
console.log(field, "field");
|
|
640
|
+
const typeParts = field.type.split("->");
|
|
641
|
+
const baseType = typeParts.length === 2 ? typeParts[1] : field.type;
|
|
642
|
+
if (baseType.endsWith("[]")) {
|
|
643
|
+
const elementType = baseType.slice(0, -2);
|
|
644
|
+
if (["string", "number", "boolean"].includes(elementType)) {
|
|
645
|
+
return ` jsonObj.${field.name} ?? []`;
|
|
646
|
+
}
|
|
647
|
+
return ` (jsonObj.${field.name} != null) ? jsonObj.${field.name}.map((item: any) => ${elementType}.fromJSON(item)) : []`;
|
|
648
|
+
}
|
|
649
|
+
if (typeParts.length === 2) {
|
|
650
|
+
const [, typeName] = typeParts;
|
|
651
|
+
const baseTypeName = typeName.endsWith("[]") ? typeName.slice(0, -2) : typeName;
|
|
652
|
+
return ` (jsonObj.${field.name} != null) ? ${baseTypeName}.fromJSON(jsonObj.${field.name}) : new ${baseTypeName}()`;
|
|
653
|
+
}
|
|
654
|
+
return ` (jsonObj.${field.name} !== null) ? jsonObj?.${field.name} : undefined`;
|
|
655
|
+
}
|
|
656
|
+
generateToJSONField(field) {
|
|
657
|
+
// const typeParts = field.type.split("->");
|
|
658
|
+
// const baseType = typeParts.length === 2 ? typeParts[1] : field.type;
|
|
659
|
+
// if (baseType.endsWith("[]")) {
|
|
660
|
+
// const elementType = baseType.slice(0, -2);
|
|
661
|
+
// if (["string", "number", "boolean"].includes(elementType)) {
|
|
662
|
+
// return ` ${field.name}: this.${field.name} ?? [],`;
|
|
663
|
+
// }
|
|
664
|
+
// return ` ${field.name}: (this.${field.name} != null) ? this.${field.name}.map((x) => x.toJson()) : [],`;
|
|
665
|
+
// }
|
|
666
|
+
// return ` ${field.name}: this.${field.name} != null ? this.${field.name} : undefined,`;
|
|
667
|
+
const typeParts = field.type.split("->");
|
|
668
|
+
const baseType = typeParts.length === 2 ? typeParts[1] : field.type;
|
|
669
|
+
if (baseType.endsWith("[]")) {
|
|
670
|
+
const elementType = baseType.slice(0, -2);
|
|
671
|
+
if (["string", "number", "boolean", "object", "any"].includes(elementType)) {
|
|
672
|
+
return ` ${field.name}: this.${field.name} ?? [],`;
|
|
673
|
+
}
|
|
674
|
+
return ` ${field.name}: (this.${field.name} != null) ? this.${field.name}.map((x) => x.toJSON()) : [],`;
|
|
675
|
+
}
|
|
676
|
+
else {
|
|
677
|
+
if (["string", "number", "boolean", "object", "any"].includes(baseType)) {
|
|
678
|
+
return `${field.name}: this.${field.name} != null ? this.${field.name} : ${this.getDefaultValue(field)},`;
|
|
679
|
+
}
|
|
680
|
+
else {
|
|
681
|
+
return ` ${field.name}: this.${field.name} != null ? this.${field.name}.toJSON() : ${field.required ? `${this.getDefaultValue(field)}.toJSON()` : 'undefined'},`;
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
exports.default = ApiHelper;
|
|
687
|
+
const commonApiDataCode = `
|
|
688
|
+
export enum ApiStatus {
|
|
689
|
+
Success="Success",
|
|
690
|
+
Loading="Loading",
|
|
691
|
+
Failed="Failed",
|
|
692
|
+
Idle="Idle"
|
|
693
|
+
}
|
|
694
|
+
`;
|
|
695
|
+
const snackbarSliceCode = `
|
|
696
|
+
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
|
|
697
|
+
|
|
698
|
+
|
|
699
|
+
export interface SnackbarRequest {
|
|
700
|
+
type: SnackbarType,
|
|
701
|
+
message: string,
|
|
702
|
+
timing: number
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
export enum SnackbarType {
|
|
706
|
+
Success="success",
|
|
707
|
+
Error="error",
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
|
|
711
|
+
interface SnackbarState {
|
|
712
|
+
snackbarRequestList: SnackbarRequest[]
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
const initialState:SnackbarState = {
|
|
716
|
+
snackbarRequestList: []
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
|
|
720
|
+
export const snackbarSlice= createSlice({
|
|
721
|
+
name: "Snackbar",
|
|
722
|
+
initialState: initialState,
|
|
723
|
+
reducers: {
|
|
724
|
+
addSnackbar: (state, action: {type:String,payload: SnackbarRequest}) => {
|
|
725
|
+
state.snackbarRequestList.push(action.payload);
|
|
726
|
+
},
|
|
727
|
+
removeLastSnackbar: (state) => {
|
|
728
|
+
state.snackbarRequestList.pop();
|
|
729
|
+
},
|
|
730
|
+
}
|
|
731
|
+
});
|
|
732
|
+
|
|
733
|
+
|
|
734
|
+
export const {addSnackbar,removeLastSnackbar} = snackbarSlice.actions;
|
|
735
|
+
|
|
736
|
+
export default snackbarSlice.reducer;
|
|
737
|
+
`;
|
|
738
|
+
const mainStoreCode = `
|
|
739
|
+
|
|
740
|
+
|
|
741
|
+
import { configureStore } from '@reduxjs/toolkit'
|
|
742
|
+
import { GeneratedReducers } from 'src-gen/redux/gen-reducers';
|
|
743
|
+
const store = configureStore({
|
|
744
|
+
reducer: {
|
|
745
|
+
...GeneratedReducers,
|
|
746
|
+
},
|
|
747
|
+
|
|
748
|
+
})
|
|
749
|
+
|
|
750
|
+
|
|
751
|
+
|
|
752
|
+
export type RootState = ReturnType<typeof store.getState>
|
|
753
|
+
|
|
754
|
+
export type AppDispatch = typeof store.dispatch;
|
|
755
|
+
|
|
756
|
+
export default store;
|
|
757
|
+
`;
|
|
758
|
+
const hooksCode = `
|
|
759
|
+
import { useDispatch, useSelector } from 'react-redux'
|
|
760
|
+
import type { TypedUseSelectorHook } from 'react-redux'
|
|
761
|
+
import type { RootState, AppDispatch } from './store/store'
|
|
762
|
+
|
|
763
|
+
// Use throughout your app instead of plain useDispatch and useSelector
|
|
764
|
+
export const useAppDispatch: () => AppDispatch = useDispatch
|
|
765
|
+
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector
|
|
766
|
+
`;
|