-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathredux_code_generator.ts
172 lines (154 loc) · 6.37 KB
/
redux_code_generator.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
import { readFileStr } from 'https://deno.land/[email protected]/fs/read_file_str.ts';
import {
mapArgsToPoj,
space4,
capitalize,
appendFilerStr
} from './common/helper.ts';
import {
getActionKeyFilePath,
getActionCreatorFilePath,
getActionPayloadFilePath,
getReducerFilePath,
dirname,
getSagaFilePath
} from './common/file_path_helper.ts';
import {
enumRegExp,
insertToEnum,
getEnumName,
getInsertActionKeyContent
} from './action_key/helper.ts';
import { getInsertActionCreatorContent, getActionPayloadFileContent } from './action_creator/helper.ts';
import { getReducerFileContent, insertNewReducerHandler } from './reducer/helper.ts';
import { getSagaFileContent, getInsertSagaHandlerContent } from './saga/helper.ts';
async function reduxCodeGenerator(
{ baseDir = `${Deno.cwd()}`, actionPrefix, key, payload, saga = false }: {
baseDir?: string;
actionPrefix: string;
key: string;
payload: string;
saga: boolean
},
) {
/** insert action key */
const keyFilePath = getActionKeyFilePath(baseDir, actionPrefix);
insertOrCreate(keyFilePath, {
insertCallback: () => insertKey(keyFilePath, { prefix: actionPrefix, key }),
createCallback: () => createKeyFile(keyFilePath, { prefix: actionPrefix, key})
});
/** insert action creator */
const actionCreatorFilePath = getActionCreatorFilePath(baseDir, actionPrefix);
insertOrCreate(actionCreatorFilePath, {
insertCallback: () => insertActionCreator(actionCreatorFilePath, { prefix: actionPrefix, key, payload }),
createCallback: () => createActionCreatorFile(actionCreatorFilePath, { prefix: actionPrefix, key, payload })
});
/** insert action payload */
const actionPayloadFilePath = getActionPayloadFilePath(baseDir, actionPrefix);
insertOrCreate(actionPayloadFilePath, {
insertCallback: () => Promise.resolve(),
createCallback: () => createActionPayloadFile(actionPayloadFilePath, actionPrefix)
});
if (!saga) {
/** insert reducer */
const reducerFilePath = getReducerFilePath(baseDir, actionPrefix);
insertOrCreate(reducerFilePath, {
insertCallback: () => insertReducerFile(reducerFilePath, { prefix: actionPrefix, key }),
createCallback: () => createReducerFile(reducerFilePath, { prefix: actionPrefix, key })
});
} else {
/** insert saga */
const sagaFilePath = getSagaFilePath(baseDir, actionPrefix);
insertOrCreate(sagaFilePath, {
insertCallback: () => insertSagaFile(sagaFilePath, { prefix: actionPrefix, key }),
createCallback: () => createSagaFile(sagaFilePath, { prefix: actionPrefix, key })
});
}
}
function insertOrCreate(path: string, { insertCallback, createCallback }: { insertCallback: () => Promise<void>; createCallback: () => Promise<void> }) {
Deno.stat(path)
.then((result) => {
if (result.isFile) {
return insertCallback();
} else {
throw new Error('No such file');
}
})
.catch((error) => {
return Deno.stat(dirname(path)).then(
(result) => Promise.reject('exist dir'),
async (error) => {
await Deno.mkdir(dirname(path), { recursive: true });
return Promise.reject('after create dir');
}
);
})
.catch(() => {
return createCallback();
})
}
/**
* 在 key file 存在的前提下 插入新的 key
*/
async function insertKey(keyFilePath: string, opt: { prefix: string; key: string; }) {
const insertContent = getInsertActionKeyContent(opt.prefix, opt.key);
const enumName = getEnumName(keyFilePath);
const code = await readFileStr(keyFilePath);
if (enumRegExp(enumName).test(code)) {
console.log("在现有文件 %s 中插入 Key: %s", keyFilePath, capitalize(opt.key));
return Deno.writeTextFile(keyFilePath, insertToEnum(code, enumName, insertContent));
}
return Promise.resolve();
}
function createKeyFile(keyFilePath: string, opt: { prefix: string; key: string; }) {
console.log('创建新的 action key 文件: ', keyFilePath);
const insertContent = getInsertActionKeyContent(opt.prefix, opt.key);
return Deno.writeTextFile(keyFilePath, `export enum ${getEnumName(keyFilePath)} {\n${space4}${insertContent}\n}\n`);
}
async function insertActionCreator(
path: string,
opt: { prefix: string; key: string; payload: string }
) {
console.log('在现有文件 %s 中插入 action creator: %s', path, opt.key);
return appendFilerStr(path, getInsertActionCreatorContent(opt));
}
function createActionCreatorFile(
path: string,
opt: { prefix: string; key: string; payload: string }
) {
console.log('创建新的 action 文件', path);
/** 下面的代码 请不要格式化 */
const actionCreatorFileTpl = "import { #prefix#ActionKey } from './#_prefix#ActionKey';\n#content#";
const insertActionCreatorContent = getInsertActionCreatorContent(opt);
const prefix = opt.prefix;
const newActionCreator = actionCreatorFileTpl
.replace(/#_prefix#/g, prefix)
.replace(/#prefix#/g, capitalize(prefix))
.replace(/#content#/g, insertActionCreatorContent);
return Deno.writeTextFile(path, newActionCreator);
}
async function createActionPayloadFile(path: string, prefix: string) {
console.log('创建新的 action payload 文件', path);
return Deno.writeTextFile(path, getActionPayloadFileContent(prefix));
}
async function createReducerFile(path: string, opt: { prefix: string; key: string }) {
console.log('创建新的 action reducer 文件', path);
return Deno.writeTextFile(path, getReducerFileContent(opt.prefix, opt.key));
}
async function insertReducerFile(path: string, opt: { prefix: string; key: string }) {
console.log('在现有文件 %s 中插入 reducer handler: %s', path, `${opt.key}Handler`);
const dataExisted = await Deno.readTextFile(path);
return Deno.writeTextFile(path, insertNewReducerHandler(dataExisted, opt));
}
async function createSagaFile(path: string, opt: { prefix: string; key: string }) {
console.log('创建新的 saga 文件', path);
return Deno.writeTextFile(path, getSagaFileContent(opt.prefix, opt.key));
}
async function insertSagaFile(path: string, opt: { prefix: string; key: string }) {
console.log('在现有文件 %s 中插入 saga handler: %s', path, `${opt.key}Saga`);
return appendFilerStr(path, getInsertSagaHandlerContent(opt.prefix, opt.key));
}
if (import.meta.main) {
const args: any = mapArgsToPoj(Deno.args);
reduxCodeGenerator(args);
}