Skip to content

jsdoc supporting typescript import style #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 10 additions & 72 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,84 +1,22 @@
# JSDoc
# jsdoc-import-typedef

[![Build Status](https://travis-ci.org/jsdoc/jsdoc.svg?branch=master)](http://travis-ci.org/jsdoc/jsdoc)
This is a fork of [json](https://github.com/jsdoc/jsdoc) to deal with typescript type check import way - https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html#import-types

An API documentation generator for JavaScript.
## Motivation

Want to contribute to JSDoc? Please read `CONTRIBUTING.md`.
There are some issues in jsdoc related to this problem and a feature is open here: https://github.com/jsdoc/jsdoc/issues/1645. But the feature will be very complex and maybe can take some time to be done. And I need this fix asap.

Installation and Usage
----------------------
## Cause

JSDoc supports stable versions of Node.js 8.15.0 and later. You can install
JSDoc globally or in your project's `node_modules` folder.
jsdoc uses [catharsis](https://github.com/hegemonic/catharsis) to parse the expressions and `catharsis.parse` doesn't accept the typescript `import` expression (ex: `@param p { import("./a").Pet }`).

To install the latest version on npm globally (might require `sudo`;
[learn how to fix this](https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally)):
This raises `Invalid type expression` like seem here https://github.com/hegemonic/catharsis/blob/master/bin/parse.js#L48

npm install -g jsdoc
Instead of patch catharsis, I apply the fix in jsdoc, using a regexp to remove this pattern before the string is parsed by `catharsis.parse`.

To install the latest version on npm locally and save it in your package's
`package.json` file:
In this case, `@param p { import("./a").Pet }` will be interpreted like `@param p { Pet }` in jsdoc.

npm install --save-dev jsdoc

**Note**: By default, npm adds your package using the caret operator in front of
the version number (for example, `^3.6.3`). We recommend using the tilde
operator instead (for example, `~3.6.3`), which limits updates to the most
recent patch-level version. See
[this Stack Overflow answer](https://stackoverflow.com/questions/22343224) for
more information about the caret and tilde operators.

To install the latest development version locally, without updating your
project's `package.json` file:

npm install git+https://github.com/jsdoc/jsdoc.git

If you installed JSDoc locally, the JSDoc command-line tool is available in
`./node_modules/.bin`. To generate documentation for the file
`yourJavaScriptFile.js`:

./node_modules/.bin/jsdoc yourJavaScriptFile.js

If you installed JSDoc globally, run the `jsdoc` command:

jsdoc yourJavaScriptFile.js

By default, the generated documentation is saved in a directory named `out`. You
can use the `--destination` (`-d`) option to specify another directory.

Run `jsdoc --help` for a complete list of command-line options.

## Templates and tools

The JSDoc community has created templates and other tools to help you generate
and customize your documentation. Here are a few of them:

### Templates

+ [jaguarjs-jsdoc](https://github.com/davidshimjs/jaguarjs-jsdoc)
+ [DocStrap](https://github.com/docstrap/docstrap)
([example](https://docstrap.github.io/docstrap))
+ [jsdoc3Template](https://github.com/DBCDK/jsdoc3Template)
([example](https://github.com/danyg/jsdoc3Template/wiki#wiki-screenshots))
+ [minami](https://github.com/Nijikokun/minami)
+ [docdash](https://github.com/clenemt/docdash)
([example](http://clenemt.github.io/docdash/))
+ [tui-jsdoc-template](https://github.com/nhnent/tui.jsdoc-template)
([example](https://nhnent.github.io/tui.jsdoc-template/latest/))
+ [better-docs](https://github.com/SoftwareBrothers/better-docs)
([example](https://softwarebrothers.github.io/admin-bro-dev/index.html))

### Build tools

+ [JSDoc Grunt plugin](https://github.com/krampstudio/grunt-jsdoc)
+ [JSDoc Gulp plugin](https://github.com/mlucool/gulp-jsdoc3)

### Other tools

+ [jsdoc-to-markdown](https://github.com/jsdoc2md/jsdoc-to-markdown)
+ [Integrating GitBook with
JSDoc](https://medium.com/@kevinast/integrate-gitbook-jsdoc-974be8df6fb3)
Works great if you are using Typescript to type check your jsdoc - (https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html) and is compatible with all jsdoc templates.

## For more information

Expand Down
12 changes: 9 additions & 3 deletions lib/jsdoc/tag/type.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,18 +234,24 @@ function getTypeStrings(parsedType, isOutermostType) {
*/
function parseTypeExpression(tagInfo) {
let parsedType;
let typeExpression = tagInfo.typeExpression;

// don't try to parse empty type expressions
if (!tagInfo.typeExpression) {
if (!typeExpression) {
return tagInfo;
}

// if expression has typescript import types. Ex: @typedef { import("./").Foo }
if (typeExpression.match(/import\(.*\)\./)) {
typeExpression = typeExpression.replace(/import\(.*\)\./, '');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be resolving the type not just replacing the string.
For example this doesn't work even though the index file is exporting a default.

/* @typedef { import('./index') } */

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've managed to bodge the problem by adding a regex check

// if expression has typescript inport types which exported by default. Ex @typedef {import("./foo")}
if (typeExpression.match(/import\(.*\)/)) {
        regex = /import\(['"]?(?:.+)\/([^/\.]+)?(?:\..+)?['"]\)/.exec(typeExpression)
        typeExpression = regex[1]
    }

That regex will capture filename of the import. This is very hacky and wont fix the problem if the filename is not the same as the export.
Should I do a pull request?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this would really need to parse the file for it to be usable as the default export may not be named exactly the same.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@debugmaster sorry for my delay, I enabled issues only now.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider improving how typeExpression is patched as is done here: https://github.com/polyforest/jsdoc-tsimport-plugin/blob/main/index.js#L134

}

try {
parsedType = catharsis.parse(tagInfo.typeExpression, {jsdoc: true});
parsedType = catharsis.parse(typeExpression, {jsdoc: true});
}
catch (e) {
// always re-throw so the caller has a chance to report which file was bad
throw new Error(`Invalid type expression "${tagInfo.typeExpression}": ${e.message}`);
throw new Error(`Invalid type expression "${typeExpression}": ${e.message}`);
}

tagInfo.type = tagInfo.type.concat( getTypeStrings(parsedType, true) );
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "jsdoc",
"version": "4.0.0-dev",
"name": "jsdoc-import-typedef",
"version": "1.0.0",
"revision": "1563126982480",
"description": "An API documentation generator for JavaScript.",
"keywords": [
Expand Down
10 changes: 10 additions & 0 deletions test/specs/jsdoc/tag/type.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,16 @@ describe('jsdoc/tag/type', () => {
expect(info.optional).toBe(true);
expect(info.defaultvalue).toBe('hooray');
});

it('should parse Typescript JSDoc-style import files', () => {
const name = 'pet';
const desc = '{import("./a").Pet} SomePet'
const info = type.parse( buildText(null, name, desc), true, true);

expect(info.type[0]).toEqual('Pet');
expect(info.text).toBe('SomePet');
expect(info.name).toBe('pet');
});
});

// TODO: add more tests related to how JSDoc mangles the Catharsis parse results
Expand Down