bio-dts 0.8.1 → 0.9.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/lib/generate-types.js +4 -0
- package/lib/parsers/jsdoc.js +35 -1
- package/lib/parsers/typescript-dts.js +4 -0
- package/lib/post-transform.js +19 -12
- package/lib/pre-transform.js +24 -15
- package/lib/util.js +23 -20
- package/package.json +17 -8
package/lib/generate-types.js
CHANGED
|
@@ -17,6 +17,7 @@ export default function generateTypes(fileNames, options) {
|
|
|
17
17
|
|
|
18
18
|
const host = ts.createCompilerHost(options);
|
|
19
19
|
|
|
20
|
+
// @ts-expect-error
|
|
20
21
|
host._readFile = host.readFile;
|
|
21
22
|
|
|
22
23
|
/**
|
|
@@ -26,6 +27,7 @@ export default function generateTypes(fileNames, options) {
|
|
|
26
27
|
*/
|
|
27
28
|
host.readFile = (fileName) => {
|
|
28
29
|
|
|
30
|
+
// @ts-expect-error
|
|
29
31
|
let src = host._readFile(fileName);
|
|
30
32
|
|
|
31
33
|
isVerbose(options, fileName) && console.debug('[generate-types] [pre]', fileName, src);
|
|
@@ -44,6 +46,7 @@ export default function generateTypes(fileNames, options) {
|
|
|
44
46
|
return src;
|
|
45
47
|
};
|
|
46
48
|
|
|
49
|
+
// @ts-expect-error
|
|
47
50
|
host._writeFile = host.writeFile;
|
|
48
51
|
|
|
49
52
|
host.writeFile = (fileName, text, ...args) => {
|
|
@@ -58,6 +61,7 @@ export default function generateTypes(fileNames, options) {
|
|
|
58
61
|
|
|
59
62
|
isVerbose(options, fileName) && console.debug('[generate-types] [post] [generated]', fileName, text);
|
|
60
63
|
|
|
64
|
+
// @ts-expect-error
|
|
61
65
|
host._writeFile(fileName, text, ...args);
|
|
62
66
|
};
|
|
63
67
|
|
package/lib/parsers/jsdoc.js
CHANGED
|
@@ -1,3 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef { {
|
|
3
|
+
* start: number,
|
|
4
|
+
* end: number,
|
|
5
|
+
* name: string,
|
|
6
|
+
* type?: {
|
|
7
|
+
* start: number,
|
|
8
|
+
* end: number,
|
|
9
|
+
* value: string
|
|
10
|
+
* },
|
|
11
|
+
* param: {
|
|
12
|
+
* start: number,
|
|
13
|
+
* end: number,
|
|
14
|
+
* name?: string,
|
|
15
|
+
* contents?: string,
|
|
16
|
+
* value: string
|
|
17
|
+
* },
|
|
18
|
+
* description?: {
|
|
19
|
+
* start: number,
|
|
20
|
+
* end: number,
|
|
21
|
+
* value: string
|
|
22
|
+
* }
|
|
23
|
+
* } } JsdocTag
|
|
24
|
+
*/
|
|
25
|
+
|
|
1
26
|
function skipWhitespace(str, pos) {
|
|
2
27
|
let i = pos;
|
|
3
28
|
|
|
@@ -65,11 +90,20 @@ function findNewline(str, pos) {
|
|
|
65
90
|
return i;
|
|
66
91
|
}
|
|
67
92
|
|
|
93
|
+
/**
|
|
94
|
+
* @param {string} str
|
|
95
|
+
*
|
|
96
|
+
* @return {JsdocTag[]}
|
|
97
|
+
*/
|
|
68
98
|
export function parse(str) {
|
|
69
99
|
|
|
70
100
|
var i = 0, j;
|
|
71
101
|
|
|
72
102
|
var tags = [];
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* @type { Partial<JsdocTag> }
|
|
106
|
+
*/
|
|
73
107
|
var tag;
|
|
74
108
|
|
|
75
109
|
while ((i = str.indexOf('@', i)) && i !== -1) {
|
|
@@ -133,7 +167,7 @@ export function parse(str) {
|
|
|
133
167
|
|
|
134
168
|
tag.end = j;
|
|
135
169
|
|
|
136
|
-
tags.push(tag);
|
|
170
|
+
tags.push(/** @type { JsdocTag } */ (tag));
|
|
137
171
|
|
|
138
172
|
i = j + 1;
|
|
139
173
|
}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { parser } from 'recast/parsers/babel.js';
|
|
2
2
|
import getBabelOptions from 'recast/parsers/_babel_options.js';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* @typedef { import('recast/parsers/_babel_options.js').Overrides } Overrides
|
|
6
|
+
*/
|
|
7
|
+
|
|
4
8
|
/**
|
|
5
9
|
* @param {string} source
|
|
6
10
|
* @param {Overrides} [options]
|
package/lib/post-transform.js
CHANGED
|
@@ -9,9 +9,14 @@ import {
|
|
|
9
9
|
replace as replaceJSDoc
|
|
10
10
|
} from './parsers/jsdoc.js';
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* @template T
|
|
14
|
+
*
|
|
15
|
+
* @typedef { import('./util.js').Path<T> } Path
|
|
16
|
+
*/
|
|
12
17
|
|
|
13
18
|
/**
|
|
14
|
-
* @param { { name: string, comments?: any[] } }
|
|
19
|
+
* @param { { name: string, key?: { name?: string }, comments?: any[] } } m
|
|
15
20
|
*
|
|
16
21
|
* @return {boolean}
|
|
17
22
|
*/
|
|
@@ -136,7 +141,7 @@ export default function transform(src) {
|
|
|
136
141
|
/**
|
|
137
142
|
* Ensure optional args methods are properly escaped
|
|
138
143
|
*
|
|
139
|
-
* @param {
|
|
144
|
+
* @param {Path<any>} nodePath
|
|
140
145
|
*
|
|
141
146
|
* @return {any[]} replacements
|
|
142
147
|
*/
|
|
@@ -286,7 +291,7 @@ export default function transform(src) {
|
|
|
286
291
|
* type Woop = import('./Woop').default;
|
|
287
292
|
* ```
|
|
288
293
|
*
|
|
289
|
-
* @param {
|
|
294
|
+
* @param {Path<any>} nodePath
|
|
290
295
|
*
|
|
291
296
|
* @return {any[]} replacements
|
|
292
297
|
*/
|
|
@@ -309,7 +314,7 @@ export default function transform(src) {
|
|
|
309
314
|
/**
|
|
310
315
|
* Ensure that only documented method parameters are used.
|
|
311
316
|
*
|
|
312
|
-
* @param {Path} nodePath
|
|
317
|
+
* @param {Path<any>} nodePath
|
|
313
318
|
*
|
|
314
319
|
* @return {boolean} true if modified
|
|
315
320
|
*/
|
|
@@ -356,7 +361,7 @@ export default function transform(src) {
|
|
|
356
361
|
* Our strategy is to parse for separate `@overlord` annotated tags,
|
|
357
362
|
* use the meta-data, and generate a completely new method from it.
|
|
358
363
|
*
|
|
359
|
-
* @param {Path} nodePath
|
|
364
|
+
* @param {Path<any>} nodePath
|
|
360
365
|
*
|
|
361
366
|
* @return {boolean} true if modified
|
|
362
367
|
*/
|
|
@@ -485,6 +490,9 @@ declare function p${
|
|
|
485
490
|
|
|
486
491
|
function cleanComment(comment) {
|
|
487
492
|
|
|
493
|
+
/**
|
|
494
|
+
* @type { [ { start: number, end: number }, replacement?: string ][] }
|
|
495
|
+
*/
|
|
488
496
|
const replacements = [];
|
|
489
497
|
|
|
490
498
|
const doc = comment.value.replace(/\n\s+/g, '\n ');
|
|
@@ -525,7 +533,6 @@ declare function p${
|
|
|
525
533
|
return null;
|
|
526
534
|
} else {
|
|
527
535
|
return b.commentBlock.from({
|
|
528
|
-
type: 'CommentBlock',
|
|
529
536
|
leading: true,
|
|
530
537
|
value: newDoc
|
|
531
538
|
});
|
|
@@ -533,7 +540,7 @@ declare function p${
|
|
|
533
540
|
}
|
|
534
541
|
|
|
535
542
|
/**
|
|
536
|
-
* @param {
|
|
543
|
+
* @param {Path<any>} nodePath
|
|
537
544
|
*/
|
|
538
545
|
function cleanComments(nodePath) {
|
|
539
546
|
|
|
@@ -602,7 +609,7 @@ function traverse(path, cb) {
|
|
|
602
609
|
}
|
|
603
610
|
|
|
604
611
|
for (const key of keys(val).reverse()) {
|
|
605
|
-
if ([ 'loc', 'start', 'end' ].includes(key)) {
|
|
612
|
+
if (typeof key === 'string' && [ 'loc', 'start', 'end' ].includes(key)) {
|
|
606
613
|
continue;
|
|
607
614
|
}
|
|
608
615
|
|
|
@@ -639,9 +646,9 @@ function getFunctionKind(node) {
|
|
|
639
646
|
/**
|
|
640
647
|
* Return host path for node (with attached comments).
|
|
641
648
|
*
|
|
642
|
-
* @param {Path} nodePath
|
|
649
|
+
* @param {Path<any>} nodePath
|
|
643
650
|
*
|
|
644
|
-
* @return {Path}
|
|
651
|
+
* @return {Path<any>}
|
|
645
652
|
*/
|
|
646
653
|
function getHostPath(nodePath) {
|
|
647
654
|
return [ 'ExportDefaultDeclaration', 'ExportNamedDeclaration' ].includes(nodePath.parentPath.value.type)
|
|
@@ -650,9 +657,9 @@ function getHostPath(nodePath) {
|
|
|
650
657
|
}
|
|
651
658
|
|
|
652
659
|
/**
|
|
653
|
-
* @param {
|
|
660
|
+
* @param { { loc: { start: { line: number, column: number } } } } node
|
|
654
661
|
*
|
|
655
|
-
* @return {
|
|
662
|
+
* @return {Error}
|
|
656
663
|
*/
|
|
657
664
|
function error(node, message) {
|
|
658
665
|
|
package/lib/pre-transform.js
CHANGED
|
@@ -6,7 +6,6 @@ import {
|
|
|
6
6
|
|
|
7
7
|
function superCall() {
|
|
8
8
|
return b.expressionStatement.from({
|
|
9
|
-
'type': 'ExpressionStatement',
|
|
10
9
|
'expression': {
|
|
11
10
|
'type': 'CallExpression',
|
|
12
11
|
'callee': {
|
|
@@ -21,7 +20,6 @@ function clazzConstructor(cls, comments) {
|
|
|
21
20
|
const constructor = cls.ctor.value;
|
|
22
21
|
|
|
23
22
|
return b.classMethod.from({
|
|
24
|
-
'type': 'ClassMethod',
|
|
25
23
|
'static': false,
|
|
26
24
|
'key': {
|
|
27
25
|
'type': 'Identifier',
|
|
@@ -100,7 +98,6 @@ function clazzDefinition(cls, ctor) {
|
|
|
100
98
|
});
|
|
101
99
|
|
|
102
100
|
return b.classDeclaration.from({
|
|
103
|
-
'type': 'ClassDeclaration',
|
|
104
101
|
'id': {
|
|
105
102
|
'type': 'Identifier',
|
|
106
103
|
'name': cls.name
|
|
@@ -153,6 +150,7 @@ function splitComment(cls) {
|
|
|
153
150
|
|
|
154
151
|
/**
|
|
155
152
|
* @param {string} src
|
|
153
|
+
*
|
|
156
154
|
* @return {string}
|
|
157
155
|
*/
|
|
158
156
|
export default function transform(src) {
|
|
@@ -162,21 +160,23 @@ export default function transform(src) {
|
|
|
162
160
|
|
|
163
161
|
const inheritsImports = findInheritsImports(body);
|
|
164
162
|
|
|
165
|
-
const classes = findConstructors(body);
|
|
166
|
-
|
|
167
163
|
// query
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
...
|
|
171
|
-
...findProtoMembers(cls, body)
|
|
172
|
-
];
|
|
164
|
+
const classes = findConstructors(body).map(cls => {
|
|
165
|
+
return {
|
|
166
|
+
...cls,
|
|
173
167
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
168
|
+
members: [
|
|
169
|
+
...findEmbeddedMembers(cls),
|
|
170
|
+
...findProtoMembers(cls, body)
|
|
171
|
+
],
|
|
177
172
|
|
|
178
|
-
|
|
179
|
-
|
|
173
|
+
staticMembers: [
|
|
174
|
+
...findStaticMembers(cls, body)
|
|
175
|
+
],
|
|
176
|
+
|
|
177
|
+
superDeclaration: findSuperDeclarations(cls, body, inheritsImports)
|
|
178
|
+
};
|
|
179
|
+
});
|
|
180
180
|
|
|
181
181
|
// transform
|
|
182
182
|
for (const cls of classes) {
|
|
@@ -273,6 +273,15 @@ function findSuperDeclarations(cls, nodes, importDeclarations) {
|
|
|
273
273
|
|
|
274
274
|
}
|
|
275
275
|
|
|
276
|
+
/**
|
|
277
|
+
* @param {any[]} nodes
|
|
278
|
+
*
|
|
279
|
+
* @return { {
|
|
280
|
+
* name: string,
|
|
281
|
+
* ctor: any,
|
|
282
|
+
* node: any
|
|
283
|
+
* }[] }
|
|
284
|
+
*/
|
|
276
285
|
function findConstructors(nodes) {
|
|
277
286
|
|
|
278
287
|
const fns = matcher`
|
package/lib/util.js
CHANGED
|
@@ -2,10 +2,8 @@ import { parse as recastParse, print as recastPrint } from 'recast';
|
|
|
2
2
|
import { Path as PathConstructor } from 'ast-types';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* @
|
|
6
|
-
*
|
|
7
|
-
* value: any
|
|
8
|
-
* } } Path
|
|
5
|
+
* @template T extends
|
|
6
|
+
* @typedef { import('ast-types/lib/path.js').Path<T> } Path
|
|
9
7
|
*/
|
|
10
8
|
|
|
11
9
|
import * as typescriptParser from './parsers/typescript.js';
|
|
@@ -17,7 +15,7 @@ const formatOptions = {
|
|
|
17
15
|
useTabs: false,
|
|
18
16
|
reuseWhitespace: false,
|
|
19
17
|
tabWidth: 2,
|
|
20
|
-
quote: 'single'
|
|
18
|
+
quote: /** @type { 'single' } */ ('single')
|
|
21
19
|
};
|
|
22
20
|
|
|
23
21
|
/**
|
|
@@ -75,19 +73,21 @@ export function print(node) {
|
|
|
75
73
|
}
|
|
76
74
|
|
|
77
75
|
/**
|
|
78
|
-
* @
|
|
76
|
+
* @template V
|
|
79
77
|
*
|
|
80
|
-
* @
|
|
78
|
+
* @param {V} node
|
|
79
|
+
*
|
|
80
|
+
* @return {Path<V>}
|
|
81
81
|
*/
|
|
82
82
|
export function path(node) {
|
|
83
83
|
return new PathConstructor(node);
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
/**
|
|
87
|
-
* @param {
|
|
87
|
+
* @param {TemplateStringsArray} strings
|
|
88
88
|
* @param {...any} args
|
|
89
89
|
*
|
|
90
|
-
* @return { (node) => [][] }
|
|
90
|
+
* @return { (node) => any[][] }
|
|
91
91
|
*/
|
|
92
92
|
export function matcher(strings, ...args) {
|
|
93
93
|
|
|
@@ -102,9 +102,7 @@ export function matcher(strings, ...args) {
|
|
|
102
102
|
return code;
|
|
103
103
|
}, '');
|
|
104
104
|
|
|
105
|
-
const ast = parse(code
|
|
106
|
-
parser: typescriptParser
|
|
107
|
-
});
|
|
105
|
+
const ast = parse(code);
|
|
108
106
|
|
|
109
107
|
const body = path(ast).get('program', 'body');
|
|
110
108
|
|
|
@@ -187,11 +185,13 @@ export function matcher(strings, ...args) {
|
|
|
187
185
|
}
|
|
188
186
|
|
|
189
187
|
/**
|
|
190
|
-
* @
|
|
191
|
-
* @
|
|
192
|
-
* @param {Path
|
|
188
|
+
* @template T
|
|
189
|
+
* @template V
|
|
190
|
+
* @param {Path<T>} node
|
|
191
|
+
* @param {Path<V>} expectedNode
|
|
192
|
+
* @param {Path<any>[]} results
|
|
193
193
|
*
|
|
194
|
-
* @return {Path[]
|
|
194
|
+
* @return {Path<any>[] | null}
|
|
195
195
|
*/
|
|
196
196
|
function matchNode(node, expectedNode, results = []) {
|
|
197
197
|
|
|
@@ -209,7 +209,7 @@ export function matcher(strings, ...args) {
|
|
|
209
209
|
}
|
|
210
210
|
|
|
211
211
|
for (const key of keys(expectedNode.value)) {
|
|
212
|
-
if ([ 'loc', 'start', 'end' ].includes(key)) {
|
|
212
|
+
if (typeof key === 'string' && [ 'loc', 'start', 'end' ].includes(key)) {
|
|
213
213
|
continue;
|
|
214
214
|
}
|
|
215
215
|
|
|
@@ -241,13 +241,16 @@ export function matcher(strings, ...args) {
|
|
|
241
241
|
DBG && console.log('BAIL no array match', key);
|
|
242
242
|
return;
|
|
243
243
|
}
|
|
244
|
-
}
|
|
245
|
-
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
else if (isNode(expectedVal.value)) {
|
|
246
247
|
if (!matchNode(nodeVal, expectedVal, results)) {
|
|
247
248
|
DBG && console.log('BAIL no match', key);
|
|
248
249
|
return;
|
|
249
250
|
}
|
|
250
|
-
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
else {
|
|
251
254
|
if (nodeVal.value !== expectedVal.value) {
|
|
252
255
|
DBG && console.log('BAIL no primitive match', key);
|
|
253
256
|
return;
|
package/package.json
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bio-dts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Generate sane and clean types from JavaScript sources",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "index.js",
|
|
7
6
|
"bin": "bin/cmd.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./index.js",
|
|
9
|
+
"./lib/*.js": "./lib/*.js",
|
|
10
|
+
"./package.json": "./package.json"
|
|
11
|
+
},
|
|
8
12
|
"scripts": {
|
|
9
|
-
"all": "
|
|
13
|
+
"all": "run-s lint check-types test test:dts",
|
|
10
14
|
"lint": "eslint .",
|
|
15
|
+
"check-types": "tsc --noEmit",
|
|
11
16
|
"test": "mocha test",
|
|
12
17
|
"test:dts": "node bin/cmd.js --outDir dist -r test/fixtures"
|
|
13
18
|
},
|
|
@@ -18,16 +23,20 @@
|
|
|
18
23
|
"author": "Nico Rehwaldt",
|
|
19
24
|
"license": "MIT",
|
|
20
25
|
"dependencies": {
|
|
21
|
-
"@babel/parser": "^7.
|
|
22
|
-
"recast": "^0.
|
|
26
|
+
"@babel/parser": "^7.23.9",
|
|
27
|
+
"recast": "^0.23.4",
|
|
23
28
|
"tiny-glob": "^0.2.9"
|
|
24
29
|
},
|
|
25
30
|
"devDependencies": {
|
|
26
|
-
"
|
|
27
|
-
"
|
|
31
|
+
"@babel/types": "^7.23.9",
|
|
32
|
+
"@types/mocha": "^10.0.6",
|
|
33
|
+
"@types/node": "^20.11.19",
|
|
34
|
+
"chai": "^5.1.0",
|
|
35
|
+
"eslint": "^8.56.0",
|
|
28
36
|
"eslint-plugin-bpmn-io": "^1.0.0",
|
|
29
37
|
"mocha": "^10.2.0",
|
|
30
|
-
"
|
|
38
|
+
"npm-run-all2": "^6.1.2",
|
|
39
|
+
"typescript": "^5.3.3"
|
|
31
40
|
},
|
|
32
41
|
"files": [
|
|
33
42
|
"bin",
|