vivth 1.2.3 → 1.3.0
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 +608 -586
- package/README.src.md +5 -1
- package/bun.lock +6 -0
- package/index.mjs +10 -6
- package/package.json +3 -1
- package/src/bundler/CompileJS.mjs +11 -8
- package/src/bundler/EsBundler.mjs +4 -2
- package/src/bundler/FSInline.mjs +3 -0
- package/src/bundler/FSInlineAnalyzer.mjs +31 -7
- package/src/bundler/FSInlineBundled.mjs +5 -1
- package/src/bundler/adds/ToBundledJSPlugin.mjs +3 -4
- package/src/class/Console.mjs +12 -4
- package/src/class/Derived.mjs +5 -1
- package/src/class/Effect.mjs +6 -6
- package/src/class/EnvSignal.mjs +1 -8
- package/src/class/EventSignal.mjs +8 -7
- package/src/class/FileSafe.mjs +1 -1
- package/src/class/ListSignal.mjs +18 -10
- package/src/class/LitExp.mjs +241 -204
- package/src/class/Paths.mjs +10 -8
- package/src/class/QChannel.mjs +14 -7
- package/src/class/SafeExit.mjs +16 -7
- package/src/class/Signal.mjs +8 -7
- package/src/class/WorkerMainThread.mjs +45 -24
- package/src/class/WorkerMainThreadBundled.mjs +42 -24
- package/src/class/WorkerThread.mjs +21 -7
- package/src/common/Base64URL.mjs +2 -2
- package/src/common/Base64URLFromFile.mjs +1 -1
- package/src/doc/JSautoDOC.mjs +99 -62
- package/src/doc/correctBeforeParse.mjs +139 -0
- package/src/doc/parsedFile.mjs +127 -76
- package/src/function/CreateImmutable.mjs +12 -7
- package/src/function/GetRuntime.mjs +8 -3
- package/src/function/LazyFactory.mjs +10 -4
- package/src/function/Try.mjs +4 -1
- package/src/function/TryAsync.mjs +2 -1
- package/src/function/TrySync.mjs +3 -1
- package/src/function/TsToMjs.mjs +7 -4
- package/src/types/AnyButUndefined.mjs +1 -0
- package/src/types/LitExpResultType.mjs +7 -0
- package/src/types/Runtime.mjs +1 -1
- package/tsconfig.json +27 -5
- package/types/dev/workerThreadClass.d.mts +1 -1
- package/types/index.d.mts +7 -6
- package/types/src/bundler/CompileJS.d.mts +14 -9
- package/types/src/bundler/EsBundler.d.mts +1 -1
- package/types/src/class/Derived.d.mts +4 -64
- package/types/src/class/Effect.d.mts +8 -8
- package/types/src/class/EnvSignal.d.mts +0 -1
- package/types/src/class/EventSignal.d.mts +5 -5
- package/types/src/class/FileSafe.d.mts +2 -2
- package/types/src/class/ListSignal.d.mts +1 -1
- package/types/src/class/LitExp.d.mts +49 -53
- package/types/src/class/Paths.d.mts +4 -4
- package/types/src/class/QChannel.d.mts +1 -1
- package/types/src/class/SafeExit.d.mts +3 -3
- package/types/src/class/Signal.d.mts +3 -3
- package/types/src/class/WorkerMainThread.d.mts +13 -8
- package/types/src/class/WorkerMainThreadBundled.d.mts +13 -8
- package/types/src/class/WorkerThread.d.mts +4 -4
- package/types/src/common/Base64URL.d.mts +2 -2
- package/types/src/common/Base64URLFromFile.d.mts +2 -2
- package/types/src/doc/JSautoDOC.d.mts +33 -12
- package/types/src/doc/correctBeforeParse.d.mts +2 -0
- package/types/src/doc/parsedFile.d.mts +7 -10
- package/types/src/function/CreateImmutable.d.mts +2 -2
- package/types/src/function/Try.d.mts +2 -2
- package/types/src/function/TryAsync.d.mts +2 -2
- package/types/src/function/TrySync.d.mts +3 -2
- package/types/src/function/TsToMjs.d.mts +2 -2
- package/types/src/types/LitExpResultType.d.mts +7 -0
package/src/doc/JSautoDOC.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
3
|
import { extname, join } from 'node:path';
|
|
4
|
-
import { readFile
|
|
4
|
+
import { readFile } from 'node:fs/promises';
|
|
5
5
|
|
|
6
6
|
import chokidar from 'chokidar';
|
|
7
7
|
import { EventSignal } from '../class/EventSignal.mjs';
|
|
@@ -15,6 +15,7 @@ import { TryAsync } from '../function/TryAsync.mjs';
|
|
|
15
15
|
import { Console } from '../class/Console.mjs';
|
|
16
16
|
import { TsToMjs } from '../function/TsToMjs.mjs';
|
|
17
17
|
import { FileSafe } from '../class/FileSafe.mjs';
|
|
18
|
+
import { correctBeforeParse } from './correctBeforeParse.mjs';
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* @typedef {import('fs').Stats} Stats
|
|
@@ -46,21 +47,24 @@ const acceptableExt = new Set(['.mjs', '.mts', '.ts']);
|
|
|
46
47
|
* >>- first `"at"${string}` after `"at"description` until `"at"example` will be treated as `javascript` comment block on the `markdown`;
|
|
47
48
|
* >>- `"at"example` are treated as `javascript` block on the `markdown` file, and should be placed last on the same comment block;
|
|
48
49
|
* >>- you can always look at `vivth/src` files to check how the source, and the `README.md` and `index.mjs` documentation/generation results;
|
|
50
|
+
* >6) this types of arrow functions will be converted to regullar function, for concise type emition:
|
|
51
|
+
* >>- validly exported function;
|
|
52
|
+
* >>- static/instance method(s) with generic template;
|
|
49
53
|
*/
|
|
50
54
|
export class JSautoDOC {
|
|
51
55
|
/**
|
|
52
|
-
* @type {JSautoDOC}
|
|
56
|
+
* @type {JSautoDOC|undefined}
|
|
53
57
|
*/
|
|
54
|
-
static #instance
|
|
58
|
+
static #instance;
|
|
55
59
|
/**
|
|
56
60
|
* @description
|
|
57
61
|
* @param {Object} [options]
|
|
58
62
|
* @param {Object} [options.paths]
|
|
59
|
-
* @param {string}
|
|
63
|
+
* @param {string} options.paths.file
|
|
60
64
|
* - entry point;
|
|
61
|
-
* @param {string}
|
|
65
|
+
* @param {string} options.paths.readMe
|
|
62
66
|
* - readme target;
|
|
63
|
-
* @param {string}
|
|
67
|
+
* @param {string} options.paths.dir
|
|
64
68
|
* - source directory;
|
|
65
69
|
* @param {string} [options.copyright]
|
|
66
70
|
* @param {string} [options.tableOfContentTitle]
|
|
@@ -90,19 +94,22 @@ export class JSautoDOC {
|
|
|
90
94
|
this.#paths = paths;
|
|
91
95
|
this.#copyright = copyright;
|
|
92
96
|
const rootPath = Paths.root;
|
|
97
|
+
if (rootPath === undefined) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
93
100
|
const watchpath = join(rootPath, this.#paths.dir);
|
|
94
101
|
const watcher = chokidar.watch(watchpath, option);
|
|
95
102
|
const watcherReadme = chokidar.watch(join(rootPath, readmesrcname), option);
|
|
96
103
|
/**
|
|
97
|
-
* @type {(eventName: '
|
|
104
|
+
* @type {(eventName: import('chokidar/handler.js').EventName, path: string, stats?: import('fs').Stats) => void}
|
|
98
105
|
*/
|
|
99
106
|
const listener = (eventName, path, stats) => {
|
|
100
107
|
const ext = extname(path);
|
|
101
108
|
if (
|
|
102
|
-
|
|
109
|
+
acceptableExt.has(
|
|
103
110
|
// @ts-expect-error
|
|
104
111
|
ext
|
|
105
|
-
)
|
|
112
|
+
) === false
|
|
106
113
|
) {
|
|
107
114
|
return;
|
|
108
115
|
}
|
|
@@ -124,44 +131,47 @@ export class JSautoDOC {
|
|
|
124
131
|
};
|
|
125
132
|
watcher.on('all', listener);
|
|
126
133
|
watcherReadme.on('all', this.#readMeListener);
|
|
127
|
-
SafeExit.instance
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
134
|
+
if (SafeExit.instance) {
|
|
135
|
+
SafeExit.instance.addCallback(async () => {
|
|
136
|
+
watcher.close();
|
|
137
|
+
watcherReadme.close();
|
|
138
|
+
watcher.removeAllListeners();
|
|
139
|
+
watcherReadme.removeAllListeners();
|
|
140
|
+
watcher.removeListener('all', listener);
|
|
141
|
+
watcherReadme.removeAllListeners(this.#readMeListener);
|
|
142
|
+
watcherReadme.removeListener('all', this.#readMeListener);
|
|
143
|
+
});
|
|
144
|
+
}
|
|
136
145
|
}
|
|
137
146
|
/**
|
|
138
|
-
* @type {string}
|
|
147
|
+
* @type {string|undefined}
|
|
139
148
|
*/
|
|
140
|
-
#copyright
|
|
149
|
+
#copyright;
|
|
141
150
|
/**
|
|
142
151
|
* @type {{
|
|
143
|
-
* file
|
|
144
|
-
* readMe
|
|
145
|
-
* dir
|
|
146
|
-
* }}
|
|
152
|
+
* file: string;
|
|
153
|
+
* readMe: string;
|
|
154
|
+
* dir: string;
|
|
155
|
+
* }|undefined}
|
|
147
156
|
*/
|
|
148
157
|
#paths;
|
|
149
158
|
/**
|
|
150
|
-
* @type {string}
|
|
159
|
+
* @type {string|undefined}
|
|
151
160
|
*/
|
|
152
161
|
#tableOfContentTitle;
|
|
153
162
|
/**
|
|
154
|
-
* @param {
|
|
163
|
+
* @param {import('chokidar/handler.js').EventName} _eventName
|
|
155
164
|
* @param {string} path_
|
|
156
|
-
* @param {Stats} stats
|
|
157
|
-
* @returns {
|
|
165
|
+
* @param {Stats|undefined} stats
|
|
166
|
+
* @returns {void}
|
|
158
167
|
*/
|
|
159
|
-
#readMeListener =
|
|
160
|
-
if (
|
|
168
|
+
#readMeListener = (_eventName, path_, stats) => {
|
|
169
|
+
if (stats && stats.isFile() === false) {
|
|
161
170
|
return;
|
|
162
171
|
}
|
|
163
|
-
|
|
164
|
-
|
|
172
|
+
readFile(path_, { encoding }).then((content) => {
|
|
173
|
+
this.#readMESRCContent.value = content;
|
|
174
|
+
});
|
|
165
175
|
};
|
|
166
176
|
/**
|
|
167
177
|
* @type {Signal<Set<string>>}
|
|
@@ -170,32 +180,37 @@ export class JSautoDOC {
|
|
|
170
180
|
/**
|
|
171
181
|
* @type {Signal<string>}
|
|
172
182
|
*/
|
|
173
|
-
#readMESRCContent = LazyFactory(() => new Signal(
|
|
183
|
+
#readMESRCContent = LazyFactory(() => new Signal(''));
|
|
174
184
|
#generatedREADME_md = new Effect(async ({ subscribe, isLastCalled }) => {
|
|
175
185
|
const contentSRC = subscribe(this.#readMESRCContent).value;
|
|
176
186
|
const filepaths = subscribe(this.#filePaths).value;
|
|
177
|
-
if (
|
|
187
|
+
if ((await isLastCalled(100)) === false || !contentSRC || !filepaths) {
|
|
178
188
|
return;
|
|
179
189
|
}
|
|
180
|
-
const
|
|
181
|
-
if (
|
|
190
|
+
const res = await this.#generateFromSRC(contentSRC, filepaths);
|
|
191
|
+
if ((await isLastCalled()) === false || res === undefined) {
|
|
182
192
|
return;
|
|
183
193
|
}
|
|
184
|
-
const
|
|
185
|
-
const
|
|
194
|
+
const { readme, mjsFile } = res;
|
|
195
|
+
const rootPath = Paths.root;
|
|
196
|
+
if (rootPath === undefined || this.#paths === undefined) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
const readmePath = join(rootPath, this.#paths.readMe);
|
|
200
|
+
const mjsFilePath = join(rootPath, this.#paths.file);
|
|
186
201
|
const [[, errorWriteReadme], [, errorWriteMjsFile]] = await Promise.all([
|
|
187
202
|
FileSafe.write(readmePath, readme, { encoding }),
|
|
188
203
|
FileSafe.write(mjsFilePath, mjsFile, { encoding }),
|
|
189
204
|
]);
|
|
190
|
-
if (
|
|
191
|
-
Console.info({
|
|
205
|
+
if (errorWriteReadme === undefined) {
|
|
206
|
+
Console.info({ vivthJSautoDOC: `successfully generate '${readmePath}'` });
|
|
192
207
|
} else {
|
|
193
|
-
Console.error({
|
|
208
|
+
Console.error({ vivthJSautoDOC: `unable to generate '${readmePath}'`, errorWriteReadme });
|
|
194
209
|
}
|
|
195
|
-
if (
|
|
196
|
-
Console.info({
|
|
210
|
+
if (errorWriteMjsFile === undefined) {
|
|
211
|
+
Console.info({ vivthJSautoDOC: `successfully generate '${mjsFilePath}'` });
|
|
197
212
|
} else {
|
|
198
|
-
Console.error({
|
|
213
|
+
Console.error({ vivthJSautoDOC: `unable to generate '${mjsFilePath}'`, errorWriteMjsFile });
|
|
199
214
|
}
|
|
200
215
|
});
|
|
201
216
|
/**
|
|
@@ -216,9 +231,12 @@ export class JSautoDOC {
|
|
|
216
231
|
/**
|
|
217
232
|
* @param {string} contentSRC
|
|
218
233
|
* @param {Set<string>} filepaths
|
|
219
|
-
* @returns {Promise<generatedFromSRC>}
|
|
234
|
+
* @returns {Promise<generatedFromSRC|undefined>}
|
|
220
235
|
*/
|
|
221
236
|
#generateFromSRC = async (contentSRC, filepaths) => {
|
|
237
|
+
if (this.#tableOfContentTitle === undefined || this.#copyright === undefined) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
222
240
|
const tableID = this.#tableOfContentTitle.replace(/\s+/g, '-').toLowerCase();
|
|
223
241
|
const tableOfContent = [];
|
|
224
242
|
const apiDocuments = [];
|
|
@@ -232,7 +250,12 @@ export class JSautoDOC {
|
|
|
232
250
|
path: { relative: relativePath },
|
|
233
251
|
baseName: { noExt },
|
|
234
252
|
} = (await this.#parsedFilesRef.get(path_)).value;
|
|
235
|
-
const
|
|
253
|
+
const trueContent = await content.string();
|
|
254
|
+
if (trueContent === undefined) {
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
const hasNoAutoDoc = /\/\*\*[\s\*]*?@noautodoc[\s\*]*?\*\//.test(trueContent);
|
|
236
259
|
if (hasValidExportObject) {
|
|
237
260
|
mjsMain.push(
|
|
238
261
|
`export { ${noExt} } from '${
|
|
@@ -240,6 +263,9 @@ export class JSautoDOC {
|
|
|
240
263
|
}';`
|
|
241
264
|
);
|
|
242
265
|
}
|
|
266
|
+
/**
|
|
267
|
+
* @type {string[]}
|
|
268
|
+
*/
|
|
243
269
|
const currentDescription = [];
|
|
244
270
|
const { readme, typedef } = documented;
|
|
245
271
|
const [typedefString, error] = await TryAsync(async () => {
|
|
@@ -249,9 +275,9 @@ export class JSautoDOC {
|
|
|
249
275
|
const result = await typedef();
|
|
250
276
|
return result;
|
|
251
277
|
});
|
|
252
|
-
if (
|
|
278
|
+
if (error === undefined && typedefString) {
|
|
253
279
|
mjsTypes.push(typedefString.module);
|
|
254
|
-
if (
|
|
280
|
+
if (hasNoAutoDoc === false) {
|
|
255
281
|
const nameVarID = noExt.toLowerCase();
|
|
256
282
|
tableOfContent.push(`[${noExt}](#${nameVarID})`);
|
|
257
283
|
apiDocuments.push(
|
|
@@ -261,7 +287,7 @@ export class JSautoDOC {
|
|
|
261
287
|
);
|
|
262
288
|
}
|
|
263
289
|
}
|
|
264
|
-
if (
|
|
290
|
+
if (hasNoAutoDoc === false && hasValidExportObject) {
|
|
265
291
|
readme.forEach((ref) => {
|
|
266
292
|
const {
|
|
267
293
|
// fullDescription,
|
|
@@ -325,19 +351,30 @@ export class JSautoDOC {
|
|
|
325
351
|
*/
|
|
326
352
|
#addHandler = (eventName, path__, _stats) => {
|
|
327
353
|
TryAsync(async () => {
|
|
328
|
-
|
|
329
|
-
|
|
354
|
+
if (
|
|
355
|
+
//
|
|
356
|
+
!_stats?.isFile()
|
|
357
|
+
) {
|
|
330
358
|
return;
|
|
331
359
|
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
360
|
+
const res = await correctBeforeParse(path__, 'utf-8');
|
|
361
|
+
switch (res) {
|
|
362
|
+
case 'shouldProceedNextCheck':
|
|
363
|
+
const dispatch = await this.#parsedFilesRef.get(path__);
|
|
364
|
+
dispatch.value = new parsedFile(path__, _stats, encoding);
|
|
365
|
+
this.#filePaths.subscribers.notify(async ({ signalInstance }) => {
|
|
366
|
+
await dispatch.value.parse();
|
|
367
|
+
dispatch.subscribers.notify();
|
|
368
|
+
Console.info({ vivthJSautoDOC: `${eventName} '${path__}' to export and doc` });
|
|
369
|
+
signalInstance.value.add(path__);
|
|
370
|
+
});
|
|
371
|
+
break;
|
|
372
|
+
case 'waitForRewrite':
|
|
373
|
+
case 'doNotProcess':
|
|
374
|
+
break;
|
|
375
|
+
}
|
|
339
376
|
}).then(([, error]) => {
|
|
340
|
-
if (
|
|
377
|
+
if (error === undefined) {
|
|
341
378
|
return;
|
|
342
379
|
}
|
|
343
380
|
Console.error(error);
|
|
@@ -348,12 +385,12 @@ export class JSautoDOC {
|
|
|
348
385
|
*/
|
|
349
386
|
#removeHandler = (eventName, path__, _stats) => {
|
|
350
387
|
TryAsync(async () => {
|
|
351
|
-
if (
|
|
388
|
+
if (_stats?.isFile()) {
|
|
352
389
|
return true;
|
|
353
390
|
}
|
|
354
391
|
return false;
|
|
355
|
-
}).then(([
|
|
356
|
-
if (
|
|
392
|
+
}).then(([, error]) => {
|
|
393
|
+
if (error === undefined) {
|
|
357
394
|
return;
|
|
358
395
|
}
|
|
359
396
|
this.#filePaths.subscribers.notify(async ({ signalInstance }) => {
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import { basename } from 'node:path';
|
|
4
|
+
|
|
5
|
+
import { TryAsync } from '../function/TryAsync.mjs';
|
|
6
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
7
|
+
import { Console } from '../class/Console.mjs';
|
|
8
|
+
import { Timeout } from '../function/Timeout.mjs';
|
|
9
|
+
import { LitExp } from '../class/LitExp.mjs';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @typedef {'shouldProceedNextCheck'|'waitForRewrite'|'doNotProcess'} RetType
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @param {string} path
|
|
17
|
+
* @param {BufferEncoding} [encoding]
|
|
18
|
+
* @returns {Promise<RetType>}
|
|
19
|
+
*/
|
|
20
|
+
export const correctBeforeParse = async (path, encoding = 'utf-8') => {
|
|
21
|
+
const validExportName = basename(path).split('.')[0] ?? '';
|
|
22
|
+
const firstLetter = validExportName[0];
|
|
23
|
+
const isStartWithCapital = firstLetter?.toUpperCase() === firstLetter;
|
|
24
|
+
if (validExportName === '' || isStartWithCapital === false) {
|
|
25
|
+
return 'doNotProcess';
|
|
26
|
+
}
|
|
27
|
+
const content = (await readFile(path, { encoding: 'utf-8' })).toString();
|
|
28
|
+
const [resFunctionCheck, errorFunctionCheck] = await checkIsFunction(
|
|
29
|
+
content,
|
|
30
|
+
validExportName,
|
|
31
|
+
path,
|
|
32
|
+
encoding
|
|
33
|
+
);
|
|
34
|
+
if (errorFunctionCheck) {
|
|
35
|
+
return 'doNotProcess';
|
|
36
|
+
}
|
|
37
|
+
if (resFunctionCheck === 'waitForRewrite') {
|
|
38
|
+
return 'waitForRewrite';
|
|
39
|
+
}
|
|
40
|
+
const [resClassCheck, errorClassCheck] = await checkIsClass(
|
|
41
|
+
content,
|
|
42
|
+
validExportName,
|
|
43
|
+
path,
|
|
44
|
+
encoding
|
|
45
|
+
);
|
|
46
|
+
if (errorClassCheck) {
|
|
47
|
+
return 'doNotProcess';
|
|
48
|
+
}
|
|
49
|
+
return resClassCheck;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @type {(content:string,
|
|
54
|
+
* validExportName:string,
|
|
55
|
+
* ...options:Parameters<correctBeforeParse>)=>
|
|
56
|
+
* ReturnType<typeof TryAsync<RetType>>}
|
|
57
|
+
*/
|
|
58
|
+
const checkIsFunction = async (content, validExportName, path, encoding) => {
|
|
59
|
+
return await TryAsync(async () => {
|
|
60
|
+
const regexConst = new RegExp(
|
|
61
|
+
`export\\s+const\\s+${validExportName}\\s+\\=\\s*?(?:async|)\\s*?\\(([\\s\\S]*?)\\)\\s*?\=\>`,
|
|
62
|
+
'g'
|
|
63
|
+
);
|
|
64
|
+
const matches = content.matchAll(regexConst).toArray()[0];
|
|
65
|
+
const useConst = regexConst.test(content);
|
|
66
|
+
if (useConst && matches) {
|
|
67
|
+
const [fullString, parameters] = matches;
|
|
68
|
+
const declaratorReplaceMent = `export function ${validExportName}(${parameters})`;
|
|
69
|
+
const newContent = content.replace(fullString, declaratorReplaceMent);
|
|
70
|
+
await Timeout(100); // to wait for pretify on autoSave;
|
|
71
|
+
await writeFile(path, newContent, { encoding });
|
|
72
|
+
Console.info({
|
|
73
|
+
vivthJSAutoDoc: `successfully modify '${path}' exported function to regullar function declaration, for correct type emition;`,
|
|
74
|
+
});
|
|
75
|
+
return 'waitForRewrite';
|
|
76
|
+
}
|
|
77
|
+
return 'shouldProceedNextCheck';
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* @type {(content:string,
|
|
83
|
+
* validExportName:string,
|
|
84
|
+
* ...options:Parameters<correctBeforeParse>)=>
|
|
85
|
+
* ReturnType<typeof TryAsync<RetType>>}
|
|
86
|
+
*/
|
|
87
|
+
const checkIsClass = async (content, validExportName, path, encoding) => {
|
|
88
|
+
return await TryAsync(
|
|
89
|
+
/**
|
|
90
|
+
* @returns {Promise<RetType>}
|
|
91
|
+
*/
|
|
92
|
+
async () => {
|
|
93
|
+
const isAClassRegex = new RegExp(`export\\s+class\\s+${validExportName}`, 'g');
|
|
94
|
+
if (isAClassRegex.test(content) === false) {
|
|
95
|
+
return 'shouldProceedNextCheck';
|
|
96
|
+
}
|
|
97
|
+
let rewrite = false;
|
|
98
|
+
const jsdocCommentBlockRegex = /\/\*\*[\s\S]*?\*\//g;
|
|
99
|
+
content
|
|
100
|
+
.match(jsdocCommentBlockRegex)
|
|
101
|
+
?.filter((val) => {
|
|
102
|
+
return val.includes('@template');
|
|
103
|
+
})
|
|
104
|
+
.forEach((val) => {
|
|
105
|
+
const check = new RegExp(
|
|
106
|
+
`(?<opening>${LitExp.escape(val).replace(
|
|
107
|
+
/\s+/g,
|
|
108
|
+
`\\\s*`
|
|
109
|
+
)}\\\s*?(?:static\\\s+|))(?<funcname>(?:\#|)[a-zA-Z0-9]*)\\\s*?\\\=\\\s*?(?<async_>async\\\s*?|)\\\((?<parameters>[\\\s\\\S]*?)\\\)\\\s*?=>`,
|
|
110
|
+
'g'
|
|
111
|
+
);
|
|
112
|
+
const [checkContent] = content.matchAll(check).toArray();
|
|
113
|
+
if (checkContent === undefined) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const fullCaptured = checkContent[0];
|
|
117
|
+
const grouped = checkContent.groups;
|
|
118
|
+
if (grouped === undefined) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const { opening, funcname, async_, parameters } = grouped;
|
|
122
|
+
rewrite = true;
|
|
123
|
+
const modifiedFuncDeclaration = `${opening}${
|
|
124
|
+
async_ ? 'async ' : ''
|
|
125
|
+
}${funcname}(${parameters})`;
|
|
126
|
+
content = content.replace(fullCaptured, modifiedFuncDeclaration);
|
|
127
|
+
});
|
|
128
|
+
if (rewrite) {
|
|
129
|
+
await Timeout(100); // to wait for pretify on autoSave;
|
|
130
|
+
await writeFile(path, content, { encoding });
|
|
131
|
+
Console.info({
|
|
132
|
+
vivthJSAutoDoc: `successfully modify '${path}' class/instance method(s), that has generic template, for correct type emition;`,
|
|
133
|
+
});
|
|
134
|
+
return 'waitForRewrite';
|
|
135
|
+
}
|
|
136
|
+
return 'shouldProceedNextCheck';
|
|
137
|
+
}
|
|
138
|
+
);
|
|
139
|
+
};
|