|
1 | | -import { spawn } from 'child_process'; |
2 | | -import fsPromises from 'fs/promises'; |
3 | | -import { existsSync } from 'fs'; |
4 | 1 | import async_hooks from 'async_hooks'; |
5 | 2 |
|
6 | 3 | import { |
7 | 4 | PREFIX_RESPONSE_BODY_DATA, |
8 | 5 | PREFIX_SERVER_RESPONSE |
9 | 6 | } from './constants'; |
10 | | -import RequestHook from './RequestHook'; |
11 | | -import APICollector from './APICollector'; |
12 | | -import APIGenerator from './APIGenerator'; |
13 | 7 |
|
14 | 8 | import type { |
15 | 9 | ObjectForResBodyArg, |
@@ -37,16 +31,6 @@ type serverResType = { |
37 | 31 | } |
38 | 32 | } |
39 | 33 |
|
40 | | -const rmTmpFileAndGetOriginalBack = async ( |
41 | | - tmpFilePath: string, |
42 | | - mainFilePath: string |
43 | | -) => { |
44 | | - if (existsSync(tmpFilePath)) { |
45 | | - await fsPromises.copyFile(tmpFilePath, mainFilePath); |
46 | | - await fsPromises.rm(tmpFilePath); |
47 | | - } |
48 | | -}; |
49 | | - |
50 | 34 | export class OutDoc { |
51 | 35 | public static init (): void { |
52 | 36 | const asyncHook = async_hooks.createHook({ |
@@ -80,7 +64,7 @@ export class OutDoc { |
80 | 64 | chunk |
81 | 65 | } |
82 | 66 | }; |
83 | | - console.log(PREFIX_RESPONSE_BODY_DATA + JSON.stringify(res)); |
| 67 | + process.stderr.write(PREFIX_RESPONSE_BODY_DATA + JSON.stringify(res) + "\n"); |
84 | 68 | } |
85 | 69 | } |
86 | 70 | } |
@@ -115,114 +99,12 @@ export class OutDoc { |
115 | 99 | } |
116 | 100 | }; |
117 | 101 | } |
118 | | - console.log(PREFIX_SERVER_RESPONSE + JSON.stringify(res)); |
| 102 | + |
| 103 | + process.stderr.write(PREFIX_SERVER_RESPONSE + JSON.stringify(res) + "\n"); |
119 | 104 | } |
120 | 105 | } |
121 | 106 | } |
122 | 107 | }); |
123 | 108 | asyncHook.enable(); |
124 | 109 | } |
125 | 110 | } |
126 | | - |
127 | | -export async function runner ( |
128 | | - args: Array<string>, |
129 | | - options: Record<string, string> |
130 | | -): Promise<void> { |
131 | | - if (args.length === 0) { |
132 | | - throw new Error('No arguments found'); |
133 | | - } |
134 | | - |
135 | | - const apiCollector = new APICollector(); |
136 | | - const requestHook = new RequestHook(apiCollector); |
137 | | - let mainFileAbsolutePath: string; |
138 | | - let tmpFileAbsoluteath: string; |
139 | | - |
140 | | - if (options.force) { |
141 | | - const projectCWD = process.cwd(); |
142 | | - const packageJSONStr = await fsPromises.readFile(projectCWD + '/package.json', 'utf8'); |
143 | | - const packageJSON = JSON.parse(packageJSONStr); |
144 | | - const mainFilePath = packageJSON?.outdoc?.main || packageJSON?.main; |
145 | | - if (!mainFilePath) throw new Error('Please define main or outdoc.main in package.json'); |
146 | | - |
147 | | - mainFileAbsolutePath = projectCWD + "/" + mainFilePath; |
148 | | - tmpFileAbsoluteath = projectCWD + "/outdoc_tmp_file"; |
149 | | - |
150 | | - const injectedCodes = RequestHook.getInjectedCodes(); |
151 | | - await fsPromises.copyFile(mainFileAbsolutePath, projectCWD + "/outdoc_tmp_file"); |
152 | | - await fsPromises.writeFile(mainFileAbsolutePath, injectedCodes, { flag: "a" }); |
153 | | - await fsPromises.appendFile(mainFileAbsolutePath, "// @ts-nocheck"); |
154 | | - } |
155 | | - |
156 | | - const childProcess = spawn(args[0], args.slice(1), { |
157 | | - detached: true, |
158 | | - stdio: ["inherit", "pipe", "inherit"] |
159 | | - }); |
160 | | - |
161 | | - childProcess.stdout.on('data', (data) => { |
162 | | - const dataStr = data.toString(); |
163 | | - |
164 | | - if (dataStr.startsWith(PREFIX_RESPONSE_BODY_DATA)) { |
165 | | - try { |
166 | | - const res = JSON.parse(dataStr.substr(PREFIX_RESPONSE_BODY_DATA.length)); |
167 | | - if (res.data?.encoding === 'buffer') { |
168 | | - res.data.chunk = new Buffer(res.data.chunk); |
169 | | - } |
170 | | - requestHook.handleResponseBodyData(res); |
171 | | - } catch (err) { |
172 | | - if (err instanceof Error) { |
173 | | - process.stderr.write(err.message); |
174 | | - } |
175 | | - } |
176 | | - return; |
177 | | - } |
178 | | - |
179 | | - if (dataStr.startsWith(PREFIX_SERVER_RESPONSE)) { |
180 | | - try { |
181 | | - const res = JSON.parse(dataStr.substr(PREFIX_SERVER_RESPONSE.length)); |
182 | | - if (res.data?.req?._readableState) { |
183 | | - const headData = res.data.req._readableState.buffer.head.data; |
184 | | - res.data.req._readableState.buffer.head.data = new Buffer(headData); |
185 | | - } |
186 | | - requestHook.handleServerResponse(res); |
187 | | - } catch (err) { |
188 | | - if (err instanceof Error) { |
189 | | - process.stderr.write(err.message); |
190 | | - } |
191 | | - } |
192 | | - return; |
193 | | - } |
194 | | - |
195 | | - process.stdout.write(data.toString()); |
196 | | - }); |
197 | | - |
198 | | - childProcess.on('close', async (code) => { |
199 | | - if (options.force) { |
200 | | - await rmTmpFileAndGetOriginalBack(tmpFileAbsoluteath, mainFileAbsolutePath); |
201 | | - } |
202 | | - |
203 | | - if (code === 0) { |
204 | | - try { |
205 | | - await APIGenerator.generate( |
206 | | - apiCollector, |
207 | | - { |
208 | | - output: options.output, |
209 | | - title: options.title, |
210 | | - version: options.version, |
211 | | - email: options.email |
212 | | - } |
213 | | - ); |
214 | | - console.log('Generate API document success'); |
215 | | - } catch (err) { |
216 | | - let message = ""; |
217 | | - if (err instanceof Error) message = err.message; |
218 | | - console.log('Generate API document failed: ', message); |
219 | | - } |
220 | | - } |
221 | | - }); |
222 | | - |
223 | | - process.on('SIGINT', async () => { |
224 | | - if (options.force) { |
225 | | - await rmTmpFileAndGetOriginalBack(tmpFileAbsoluteath, mainFileAbsolutePath); |
226 | | - } |
227 | | - }); |
228 | | -} |
0 commit comments