bio-dts 0.11.0 → 0.13.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 CHANGED
@@ -34,13 +34,15 @@ Checkout the [test fixtures](./test/fixtures) for full coverage.
34
34
 
35
35
  ## API
36
36
 
37
- ```javascript
37
+ ```js
38
38
  import {
39
39
  preTransform,
40
40
  postTransform,
41
41
  generateTypes
42
42
  } from 'bio-dts';
43
43
 
44
+ import * as typescript from 'typescript';
45
+
44
46
  // transform JS so it keeps the shape,
45
47
  // but is properly digestable by the typescript
46
48
  // compiler
@@ -54,5 +56,5 @@ const transformedCode = postTransform(tsCode);
54
56
  // typescript compiler
55
57
  generateTypes(files, {
56
58
  outDir: 'dist'
57
- });
59
+ }, typescript);
58
60
  ```
package/bin/cmd.js CHANGED
@@ -5,6 +5,7 @@ import Module from 'node:module';
5
5
  import glob from 'tiny-glob';
6
6
 
7
7
  import path from 'node:path';
8
+ import os from 'node:os';
8
9
  import fs from 'node:fs';
9
10
 
10
11
  import generateTypes from '../lib/generate-types.js';
@@ -21,9 +22,9 @@ async function run() {
21
22
  } = ts.parseCommandLine(args);
22
23
 
23
24
  const help = args.includes('--help') || args.includes('-h');
24
- const verboseMatch = /--verbose(?:=([^\s$]+))?(\s|$)/.exec(args);
25
+ const [ _verbose, _verboseGrep ] = args.flatMap(arg => /^--verbose(?:=(.*))?$/.exec(arg) || []);
25
26
 
26
- const verbose = verboseMatch ? verboseMatch[1] || true : false;
27
+ const verbose = _verbose ? _verboseGrep || true : false;
27
28
  const recursive = args.includes('--recursive') || args.includes('-r');
28
29
 
29
30
  if (help) {
@@ -70,9 +71,40 @@ async function run() {
70
71
 
71
72
  verbose && console.log('Using options ', generateOptions);
72
73
 
73
- generateTypes(files, generateOptions);
74
+ const {
75
+ diagnostics
76
+ } = generateTypes(files, generateOptions, ts);
77
+
78
+ const errors = diagnostics.filter(d => d.category === ts.DiagnosticCategory.Error);
79
+
80
+ if (errors.length) {
81
+
82
+ const formatHost = {
83
+ getNewLine() {
84
+ return os.EOL;
85
+ },
86
+
87
+ getCurrentDirectory() {
88
+ return process.cwd();
89
+ },
90
+
91
+ getCanonicalFileName(fileName) {
92
+ return fileName;
93
+ }
94
+ };
95
+
96
+ console.log('Done with errors:');
97
+ console.log();
98
+ console.log(
99
+ ts.formatDiagnosticsWithColorAndContext(errors, formatHost)
100
+ );
101
+
102
+ return 5;
103
+ }
74
104
 
75
105
  console.log('Done.');
106
+
107
+ return 0;
76
108
  }
77
109
 
78
110
  function isDir(fileName) {
@@ -103,7 +135,9 @@ function getTypescript() {
103
135
  }
104
136
  }
105
137
 
106
- run().catch(err => {
138
+ run().then(errorCode => {
139
+ process.exit(errorCode);
140
+ }, err => {
107
141
  console.error(err);
108
142
 
109
143
  process.exit(1);
@@ -1,17 +1,29 @@
1
1
  import path from 'node:path';
2
2
 
3
- import ts from 'typescript';
4
-
5
3
  import preTransform from './pre-transform.js';
6
4
 
7
5
  import postTransform from './post-transform.js';
8
6
 
7
+ /**
8
+ * @typedef { import('typescript').CompilerOptions } CompilerOptions
9
+ * @typedef { import('typescript').createCompilerHost } createCompilerHost
10
+ * @typedef { import('typescript').createProgram } createProgram
11
+ * @typedef { {
12
+ * createCompilerHost: createCompilerHost,
13
+ * createProgram: createProgram
14
+ * } } TypeScript
15
+ */
9
16
 
10
17
  /**
11
- * @param {string[]} fileNames
12
- * @param {ts.CompilerOptions} options
18
+ * @param { string[] } fileNames
19
+ * @param { CompilerOptions } options
20
+ * @param { TypeScript } ts
13
21
  */
14
- export default function generateTypes(fileNames, options) {
22
+ export default function generateTypes(fileNames, options, ts) {
23
+
24
+ if (!ts) {
25
+ throw new Error('must provide <ts=TypeScript>');
26
+ }
15
27
 
16
28
  const names = new Set(fileNames.map((p) => path.resolve(p)));
17
29
 
@@ -30,18 +42,18 @@ export default function generateTypes(fileNames, options) {
30
42
  // @ts-expect-error
31
43
  let src = host._readFile(fileName);
32
44
 
33
- isVerbose(options, fileName) && console.debug('[generate-types] [pre]', fileName, src);
34
-
35
45
  if (names.has(path.resolve(fileName))) {
46
+ isVerbose(options, fileName) && console.debug('[generate-types] [pre]', fileName, src);
47
+
36
48
  try {
37
49
  src = preTransform(src);
38
50
  } catch (err) {
39
- console.error(`failed to parse ${fileName} [pre] with contents ${src}`, err);
51
+ console.error(`[generate-types] [pre] failed to parse ${fileName} with contents ${src}`, err);
40
52
  throw err;
41
53
  }
42
- }
43
54
 
44
- isVerbose(options, fileName) && console.debug('[generate-types] [pre] [generated]', fileName, src);
55
+ isVerbose(options, fileName) && console.debug('[generate-types] [pre] [generated]', fileName, src);
56
+ }
45
57
 
46
58
  return src;
47
59
  };
@@ -52,14 +64,16 @@ export default function generateTypes(fileNames, options) {
52
64
  host.writeFile = (fileName, text, ...args) => {
53
65
  isVerbose(options, fileName) && console.debug('[generate-types] [post]', fileName, text);
54
66
 
55
- try {
56
- text = postTransform(text);
57
- } catch (err) {
58
- console.error(`failed to parse ${fileName} [post] with contents ${text}`, err);
59
- throw err;
60
- }
67
+ if (fileName.toLowerCase().endsWith('.d.ts')) {
68
+ try {
69
+ text = postTransform(text);
70
+ } catch (err) {
71
+ console.error(`[generate-types] [post] failed to parse ${fileName} with contents ${text}`, err);
72
+ throw err;
73
+ }
61
74
 
62
- isVerbose(options, fileName) && console.debug('[generate-types] [post] [generated]', fileName, text);
75
+ isVerbose(options, fileName) && console.debug('[generate-types] [post] [generated]', fileName, text);
76
+ }
63
77
 
64
78
  // @ts-expect-error
65
79
  host._writeFile(fileName, text, ...args);
@@ -67,7 +81,7 @@ export default function generateTypes(fileNames, options) {
67
81
 
68
82
  const program = ts.createProgram(fileNames, options, host);
69
83
 
70
- program.emit();
84
+ return program.emit();
71
85
  }
72
86
 
73
87
  function isVerbose(options, fileName) {
@@ -76,5 +90,9 @@ function isVerbose(options, fileName) {
76
90
  return options.verbose;
77
91
  }
78
92
 
93
+ if (typeof options.verbose === 'undefined') {
94
+ return false;
95
+ }
96
+
79
97
  return fileName.includes(options.verbose);
80
98
  }
@@ -127,7 +127,7 @@ export default function transform(src) {
127
127
 
128
128
  const actualName = param.argument?.name || param.name;
129
129
 
130
- if (actualName !== expectedName) {
130
+ if (isNamedParam(param) && actualName !== expectedName) {
131
131
  throw error(node, `documented parameter <${ expectedName }> differs from actual parameter <${ actualName }>`);
132
132
  }
133
133
 
@@ -210,7 +210,8 @@ export default function transform(src) {
210
210
  variations.forEach((variation) => {
211
211
  const builder = {
212
212
  'RestElement': b.restElement,
213
- 'Identifier': b.identifier
213
+ 'Identifier': b.identifier,
214
+ 'ObjectPattern': b.objectPattern
214
215
  }[param.type];
215
216
 
216
217
  variation.push(builder.from(param));
@@ -416,7 +417,7 @@ export default function transform(src) {
416
417
  return;
417
418
  }
418
419
 
419
- const replacements = overloads.slice().reverse().map(overload => {
420
+ const replacements = overloads.slice().map(overload => {
420
421
 
421
422
  const {
422
423
  comment,
@@ -502,7 +503,7 @@ declare function p${
502
503
 
503
504
  // remove full line including the non-TS tag
504
505
  if (
505
- /class|constructor|template|method|typedef|property|this|overlord/.test(tag.name) ||
506
+ /class|constructor|template|method|typedef|property|this|overlord|overload/.test(tag.name) ||
506
507
  tag.param?.name?.includes('.')
507
508
  ) {
508
509
  replacements.push([ { start: tag.start - 4, end: tag.end } ]);
@@ -682,6 +683,10 @@ function getHostPath(nodePath) {
682
683
  : nodePath;
683
684
  }
684
685
 
686
+ function isNamedParam(param) {
687
+ return param.type === 'Identifier' || param.type == 'RestElement';
688
+ }
689
+
685
690
  /**
686
691
  * @param { { loc: { start: { line: number, column: number } } } } node
687
692
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bio-dts",
3
- "version": "0.11.0",
3
+ "version": "0.13.0",
4
4
  "description": "Generate sane and clean types from JavaScript sources",
5
5
  "type": "module",
6
6
  "bin": "bin/cmd.js",
@@ -10,11 +10,12 @@
10
10
  "./package.json": "./package.json"
11
11
  },
12
12
  "scripts": {
13
- "all": "run-s lint check-types test test:dts",
13
+ "all": "run-s lint check-types test test:dts:*",
14
14
  "lint": "eslint .",
15
15
  "check-types": "tsc --noEmit",
16
16
  "test": "mocha test",
17
- "test:dts": "node bin/cmd.js --outDir dist -r test/fixtures"
17
+ "test:dts:default": "node bin/cmd.js --outDir test/fixtures/snapshots/default -r test/fixtures",
18
+ "test:dts:declaration-map": "node bin/cmd.js --declarationMap --outDir test/fixtures/snapshots/declaration-map -r test/fixtures"
18
19
  },
19
20
  "repository": {
20
21
  "type": "git",
@@ -23,20 +24,20 @@
23
24
  "author": "Nico Rehwaldt",
24
25
  "license": "MIT",
25
26
  "dependencies": {
26
- "@babel/parser": "^7.23.9",
27
- "recast": "^0.23.4",
27
+ "@babel/parser": "^7.26.3",
28
+ "recast": "^0.23.9",
28
29
  "tiny-glob": "^0.2.9"
29
30
  },
30
31
  "devDependencies": {
31
32
  "@babel/types": "^7.23.9",
32
- "@types/mocha": "^10.0.6",
33
- "@types/node": "^20.11.19",
34
- "chai": "^5.1.0",
33
+ "@types/mocha": "^10.0.10",
34
+ "@types/node": "^20.17.12",
35
+ "chai": "^5.1.2",
35
36
  "eslint": "^8.56.0",
36
37
  "eslint-plugin-bpmn-io": "^1.0.0",
37
- "mocha": "^10.2.0",
38
- "npm-run-all2": "^6.1.2",
39
- "typescript": "^5.3.3"
38
+ "mocha": "^10.8.2",
39
+ "npm-run-all2": "^7.0.2",
40
+ "typescript": "^5.7.3"
40
41
  },
41
42
  "files": [
42
43
  "bin",