Coder Social home page Coder Social logo

deno_doc's Introduction

deno_doc

A Rust crate to generate documentation for JavaScript and TypeScript modules.

This crate powers deno doc, but is not Deno specific and can be used to write documentation generators for other targets like Node or the browser as well.

Usage from Deno CLI or Deploy

See js/README.md.

Rust Example

examples/ddoc/main.rs provides a minimal standalone binary demonstrating how deno_doc can be used as a crate.

$ cargo run --example ddoc ../deno_std/http/mod.ts

Developing

# build all targets
$ cargo build --all-targets

# test it
$ cargo test

# build js api
$ deno task build

# test it
$ deno task test

Contributing

  • If you are going to work on an issue, mention so in the issue comments before you start working on the issue.

  • Please be professional in the forums. See our Code of Conduct.

  • Ask for help in the community chat room.

Submitting a Pull Request

Before submitting, please make sure the following is done:

  1. That there is a related issue and it is referenced in the PR text.
  2. There are tests that cover the changes.
  3. Ensure cargo test and deno task test passes.
  4. Format your code with rustfmt --check src/lib.rs
  5. Make sure cargo clippy --all-targets --release --locked -- -D clippy::all passes.

deno_doc's People

Contributors

aninternettroll avatar bartlomieju avatar caspervonb avatar chansuke avatar clo4 avatar crowlkats avatar denobot avatar dsherret avatar furkankly avatar josh-collinsworth avatar kitsonk avatar kt3k avatar liamolucko avatar lino-levan avatar littledivy avatar lucacasonato avatar magurotuna avatar marvinhagemeister avatar mlafeldt avatar not-my-profile avatar peaceiris avatar roj1512 avatar satyarohith avatar spencerisgiddy avatar ssssota avatar sunng87 avatar uki00a avatar ultirequiem avatar vehmloewff avatar zhmushan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

deno_doc's Issues

Feature request: Support bare (import-mappable) module identifiers.

As an author of a browser-targetted library I would like to publish it as ESM with the dependency imports using bare module specifiers, e.g. "react", so the users could specify the exact version that should be used with import maps.

Unfortunately, I cannot use https://doc.deno.land/ to generate my documentation because obviously, it doesn't know what should it resolve "react" to.

Example:

import * as React from "react"

export function foo() {
  console.log({ React })
}

https://doc.deno.land/https/gist.githubusercontent.com/vovacodes/65c626be8aec4062feed0f7f38b852d4/raw/cdbb6daeb0a0e0fddeace63f61535a118541d6ab/uses-bare-specifier.ts

This issue is a question/discussion about how could we allow for such use-case?
Possible options:

  1. Annotate the import with // @deno-types="$path to the types file$"
  • This can be quite tedious to maintain on the library side unless you use a "deps.ts" approach
  1. Provide mapping through a query param: https://doc.deno.land/https/../uses-bare-specifier.ts?importmap={"react": "$resolution URL$"}
  • The URLs can and will become too long, what can we do about that?
  1. Provide a query parameter that points to an import map in the same host as the target module, something like: ?import-map=../import_map.json (by @kitsonk)

I, personally, believe the second and/or third options are the best in terms of UX and I could try implementing it as a proposal but I'd love to hear the opinion of the others.

Cheers folks!

`deno doc` doesn't respect compiler hints

At the moment, deno doc doesn't respect /// <reference types="..." /> nor X-TypeScript-Types nor @deno-types.

Example:

foo.js

/// <reference types="./foo.d.ts" />
export const foo = "foo";

foo.d.ts

export const foo: string;

Expected output of deno doc foo.js:

const foo: string

Actual:

const foo

I originally posted this issue as #53, but these compiler hints are CLI specific.

Things deno doc should support

  • reexports (export { foo } from "./bar.ts" and export * from "./bar.ts") (#4625)
  • colored output (#4518)
  • declare and d.ts (#4573)
  • parent class information and inherited fields in classes (class Bar extends Foo) (#4595)
  • jsdoc for fields in interfaces
  • prettier jsdoc for console output (maybe https://github.com/Canop/termimad?)
  • better detail output for interface
  • better detail output for enum (#6078)
  • detail output for class fields (deno doc deno.ns.d.ts Deno.Buffer.write)
  • parent interface information and inherited fields in interfaces (interface Bar extends Foo)
  • display all overloads in cli details view (#6186)
  • exports like these: https://gist.github.com/lucacasonato/1715418303c252e5290d96051d45e8b2
  • indexable types: x?: { [key: string]: { a: number; b: number } }

maybe

  • 2nd level and deeper reexports

Doc should be able to extract "module level" JSDoc

/** This module is intended to be 
 * used with latest deno runtime.
 * Lorem ipsum.
 **/


/** hello */
function foo() {
}

Doc generator should be able to extract first JSDoc and treat it as a "module documentation" - showing it at the top of terminal output or pass it to JSON structure.

CC @ry

Deno doc doesn't detect re-exports

I get dependency and type information correctly, but deno doc cli returns nothing and deno doc site gives "This module has no exports that are recognized by deno doc."

My mod.ts is just:

// @deno-types="./dist/subslate.esm.d.ts"
export * from './dist/subslate.esm.js';

My module: https://doc.deno.land/https/deno.land/x/[email protected]/mod.ts

deno info mod.ts results:

deno info mod.ts                                                                                                                                                                                                                          
local: C:\Users\user\subslate\mod.ts
type: TypeScript
deps: 2 unique (total 4.07KB)

file:///C:/Users/user/subslate/mod.ts (82B)
โ””โ”€โ”€ file:///C:/Users/user/subslate/dist/subslate.esm.js (3.99KB)

Things to fix

  • Remove dependency on deno_core
  • Setup CI (copy from deno_lint)
  • Remove DocFileLoader trait
  • Setup CLA
  • Setup Discord webhooks
  • Dedupe swc_util with deno and deno_lint
  • Unify method signatures on DocParser
  • Node definitions should move under src/nodes
  • Move printer back into deno/cli

Infer types variables and properties assigned functions

Currently, if you have:

class A {
  a = (a: string): void => {}
}
/* or */
const a = (a: string): void => {}

There is no type information available in the output. Inferring the type of the function should be fairly straight forward to infer.

`deno doc` doesn't infer types from object literal

Example

https://deno.land/x/[email protected]/protocol/reply.ts contains the following definition:

export const replyTypes = {
  Integer: "integer",
  SimpleString: "simple string",
  Array: "array",
  BulkString: "bulk string",
} as const;

deno doc generates the following output for the above file:

$ deno doc https://deno.land/x/[email protected]/protocol/reply.ts replyTypes

Defined in https://deno.land/x/[email protected]/protocol/reply.ts:12:0

const replyTypes

I think deno doc should output type of the replyTypes variable, but outputs nothing.

Environment

  • deno v1.8.2

Leading hard tabs (before the *) are not removed

I recently switched to using hard tabs (1: accessibility, 2: resizing while writing) and found that the generated JSON doesn't ignore tab characters before the *. This causes all lines following the first line to render as code on doc.deno.land.

$ cat tabs.ts
export interface Tabs {
	/**
	 * First line.
	 *
	 * Second line.
	 *
	 * Third line.
	 */
	method(): void;
}

export interface Spaces {
  /**
   * First line.
   *
   * Second line.
   *
   * Third line.
   */
  method(): void;
}  
$ deno doc tabs.ts
Defined in file:///Users/robert/Workspaces/github.com/SeparateRecords/deno_jamf_school/tabs.ts:12:0

interface Spaces

  method(): void
    First line.

    Second line.

    Third line.

Defined in file:///Users/robert/Workspaces/github.com/SeparateRecords/deno_jamf_school/tabs.ts:1:0

interface Tabs

  method(): void
    First line.

    	Second line.

    	Third line.
$ deno doc --json tabs.ts
[
  {
    "kind": "interface",
    "name": "Tabs",
    "location": {
      "filename": "file:///Users/robert/Workspaces/github.com/SeparateRecords/deno_jamf_school/tabs.ts",
      "line": 1,
      "col": 0
    },
    "jsDoc": null,
    "interfaceDef": {
      "extends": [],
      "methods": [
        {
          "name": "method",
          "location": {
            "filename": "file:///Users/robert/Workspaces/github.com/SeparateRecords/deno_jamf_school/tabs.ts",
            "line": 9,
            "col": 4
          },
          "jsDoc": "First line.\n\t\n\tSecond line.\n\t\n\tThird line.",
          "optional": false,
          "params": [],
          "returnType": {
            "repr": "void",
            "kind": "keyword",
            "keyword": "void"
          },
          "typeParams": []
        }
      ],
      "properties": [],
      "callSignatures": [],
      "indexSignatures": [],
      "typeParams": []
    }
  },
  {
    "kind": "interface",
    "name": "Spaces",
    "location": {
      "filename": "file:///Users/robert/Workspaces/github.com/SeparateRecords/deno_jamf_school/tabs.ts",
      "line": 12,
      "col": 0
    },
    "jsDoc": null,
    "interfaceDef": {
      "extends": [],
      "methods": [
        {
          "name": "method",
          "location": {
            "filename": "file:///Users/robert/Workspaces/github.com/SeparateRecords/deno_jamf_school/tabs.ts",
            "line": 20,
            "col": 2
          },
          "jsDoc": "First line.\n\nSecond line.\n\nThird line.",
          "optional": false,
          "params": [],
          "returnType": {
            "repr": "void",
            "kind": "keyword",
            "keyword": "void"
          },
          "typeParams": []
        }
      ],
      "properties": [],
      "callSignatures": [],
      "indexSignatures": [],
      "typeParams": []
    }
  }
]

The expected behaviour would be that tabs after a line break and before * are ignored, like spaces.

Doesn't support deep reexports

Example:

// foo.ts
export const foo = "foo";
// bar.ts
export * from "./foo.ts";
// baz.ts
export * from "./bar.ts";

ddoc baz.ts should output const foo: string, but outputs nothing.

This is already mentioned in #4, but I thought I should create a separate issue before I try and work on it.

Feature Request: add capability to suppress documentation

Example:
https://doc.deno.land/https/deno.land/x/playfab_sdk/support/runtime.ts#SecurityOptions

I have a type called SecurityOptions which is an OR of SecretKey | SessionTicket | EntityToken types. I'm attempting to create a "Oneof" pattern here, where the caller would set 1 of 3 possible keys, but no more than 1. The strategy to do this ends up defining extra fields that I'd like to exclude from my documentation to reduce confusion.

I'd propose some sort of suppression capability in deno_doc. There's prior art in JSDoc to support:
https://jsdoc.app/tags-ignore.html

Renamed export retains old name

Example:

declare function foo(): void;
export { foo as bar };

Expected:

function bar(): void

Actual:

function foo(): void

This is only the case with declarations. If foo() was actually implemented here, the output would be correct.

Type linking/referencing

Ref #111

@lucacasonato and I had a conversation and I did some thinking on this particular problem. Currently the output does not resolve the symbol for a type reference, and leaves it up to the consumer to do. This can be complicated and error prone. The documentation should provide information to "link" to that symbol in the most effective way:

We modify the TsTypeRefDef to be the following:

pub enum Scope {
  Global,
  Namespace(String),
  Local,
}

pub struct TsTypeSymbol {
  pub scope: Scope,
  pub location: Option<Location>,
  pub name: String,
}

pub struct TsTypeRefDef {
  pub type_params: Option<Vec<TsTypeDef>>,
  pub type_name: String,
  pub symbol: Option<TsTypeSymbol>,
}

We have already integrated deno_graph into deno_doc so the ability to resolved imported symbols should be possible, but the ability to express the global scope is needed to be able to supply this. I also think that if the type ref can't be resolved with the supplied information, we would just get a None in the reference.

Things might need to change a bit when getting into the implementation, but I think with this information, downstream consumers of the data would be able to easily provide "links" when printing the doc nodes.

support global augmentation

I'd like to be able to generate documentation for things added to existing types.

https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation

// observable.ts
export class Observable<T> {}
declare global {
  interface Array<T> {
    toObservable(): Observable<T>;
  }
}
Array.prototype.toObservable = function () {
  throw new Error("not implemented");
};

Currently deno doc observable.ts only prints information about class Observable<T> and not about Array<T>#toObservable().

I know that generally this isn't a good idea (prototype pollution) but 1) sometimes it is necessary (e.g. for polyfills for upcoming features) and 2) extending types using a Symbol can safely extend built-ins and other types as symbols avoid name conflicts.

Deno doc should pull JSDoc along with type definition

While dealing with type documentation I noticed this behavior.

//mod.js
// @deno-types="./mod.d.ts"
export function returnAsNumber(str) {
  return Number(str);
}
//mod.d.ts
/**
 * This function receives a string and returns its numeric value
 */
export function returnAsnumber(str: string): number;

Current behavior on running deno doc mod.js is:

function returnAsNumber(str)

Expected (hopeful :P) behavior on running deno doc mod.js should be something like:

function returnAsNumber(str: string): number
  This function receives a string and returns its numeric value

As referenced in #4 I would think this is in the mindset of the team as well?

Doc should infer simple TS types

no-inferrable-types lint rule tells to not use following types:

  • string
  • symbol
  • RegExp
  • number
  • boolean
  • bigint

But when using deno doc type is not specified.
unknown

Doc generator should be able to infer those types.

CC @SyrupThinker

Confusing output when the given file does not exist

Observed Behaviour

When running

$ deno doc typoinfilename

I receive the following output (actual paths ommitted for privacy):

The graph is missing a dependency.
    Specifier: file:///somepath/typoinfilename from file:///somepath/$deno$doc.ts

Expected Behaviour

I would have expected a message that tells me straight that typoinfilename could not be found, something like:

'typoinfilename' can not be found

Make sure to pass a path or URL pointing to an ES module

How to reproduce

Run

deno doc somemissingfile

with somemissingfile not being a file in the current folder.

Doesn't detect reexported imports

Example

// foo.ts
export const foo = "foo";
// mod.ts
import { foo } from "./foo.ts";

export { foo };

deno doc should show foo as an export of mod.ts, but doesn't.

JSDocs fail to be interpreted with decorators

@Decorator()
/**
 * JSDOC
 */
export class MyClass { 

}

Would succeed to add the JSDoc information to the output
but

/**
 * JSDOC
 */
@Decorator()
export class MyClass { 

}

will not succeed.

Both should be supported

Support `get` and `set` types from TypeScript 4.3

TypeScript 4.3 allows us to have different types for getting and setting a value.

This is currently working for classes already, but interfaces don't show this correctly.

Example docs: https://doc.deno.land/https/raw.githubusercontent.com%2Fgrammyjs%2FgrammY%2Fe7cb05658198c04fccb57aefb90d0282f3661ff2%2Fdeno%2Fsrc%2Fmod.ts

Scroll to Methods of class Bot to see working getters and setters.

Scroll to interface SessionFlavor to see how it does not work the same way on interfaces.

Class instance properties set in constructor are missed

For example, in Foo.js:

/** Description for class `Foo`. */
export class Foo {
  constructor() {
    /**
     * Description for instance property `a`.
     * @type {boolean}
     */
    this.a = true;
  }

  /**
   * Description for instance property `b`.
   * @type {boolean}
   */
  b = true;
}

Running deno doc Foo.js:

Defined in file:///[redacted]/Foo.js:2:0 

class Foo
  Description for class `Foo`.

  constructor()
  b
    Description for instance property `b`.
    @type {boolean}

The instance property a is missing.

Running deno doc --json Foo.js:

[
  {
    "kind": "class",
    "name": "Foo",
    "location": {
      "filename": "file:///[redacted]/Foo.js",
      "line": 2,
      "col": 0
    },
    "jsDoc": "Description for class `Foo`.",
    "classDef": {
      "isAbstract": false,
      "constructors": [
        {
          "jsDoc": null,
          "accessibility": null,
          "name": "constructor",
          "params": [],
          "location": {
            "filename": "file:///[redacted]/Foo.js",
            "line": 3,
            "col": 2
          }
        }
      ],
      "properties": [
        {
          "jsDoc": "Description for instance property `b`.\n@type {boolean}",
          "tsType": null,
          "readonly": false,
          "accessibility": null,
          "optional": false,
          "isAbstract": false,
          "isStatic": false,
          "name": "b",
          "location": {
            "filename": "file:///[redacted]/Foo.js",
            "line": 15,
            "col": 2
          }
        }
      ],
      "indexSignatures": [],
      "methods": [],
      "extends": null,
      "implements": [],
      "typeParams": [],
      "superTypeParams": []
    }
  }
]

Structure JSDoc better

Ref #111

I think we should introduce the following structure for js_doc which is current Option<String> in locations that support it:

/// This is incomplete, just illustrative...
pub enum JsDocTag {
  Param { name: String, type_ref: Option<String>, doc: Option<String> }
  Return { type_ref: Option<String>, doc: Option<String> }
  TypeRef { type_ref: Option<String>, doc: Option<String> }
  Deprecated { doc: Option<String> }
}

pub struct JsDoc {
  doc: Option<String>,
  tags: Vec<JsDocTag>,
}

Symbol cannot be exported twice

Example:

export function foo() {}
export { foo as bar };

deno doc should show two exports, function foo() and function bar(). However, this currently only shows foo().

I think this is part of the issue in #57.

object doc comments

typescript types can document fields like so:

/** this is my object */
export interface MyObject {
  /** this is my field */
  my_field: string
}

and deno will generate the following:

interface MyObject
  this is my object

  my_field: string
    this is my field

however, defining a javascript object like so:

/** this is my object */
export const MY_OBJECT = {
  /** this is my field */
  my_field: string
}

only documents the variable declaration:

const MY_OBJECT
  this is my object

is it possible to support object field doc comments? There are lots of use cases for static objects defined in modules. Ultimately my personal use case is to take advantage of the zod validation library while still relying on handy deno doc generation colinhacks/zod#457

E.g. supporting deno doc zod-validators.ts which look like this:

import { z } from 'https://deno.land/x/[email protected]/mod.ts'

/** this is my object */
const MyObject = z.object({
  /** this is my field */
  my_field: z.string()
})
export type z.infer<typeof MyObject>

currently this just prints

type MyObjectType = z.infer<typeof MyObject>

Doesn't respect compiler hints

At the moment, deno doc doesn't respect /// <reference types="..." /> nor X-TypeScript-Types.

Example:

foo.js

/// <reference types="./foo.d.ts" />
export const foo = "foo";

foo.d.ts

export const foo: string;

Expected output of deno doc foo.js:

const foo: string

Actual:

const foo

Support mapped types

The following:

export type Partial<T> = {
  [P in keyof T]?: T[P];
};

Results in the type side being set to { repr: "<UNIMPLEMENTED>", kind: null }.

(Deno doc) jsDoc is not being included for declared functions

Deno doc is not including jsDoc in it's output for declared functions. This is most obvious with the lack of any jsdoc showing for the functions at the top of https://doc.deno.land/https/github.com/denoland/deno/releases/latest/download/lib.deno.d.ts.

To take one specific example, in lib.deno.shared_global.ts, setTimeout is declared as:

/** Sets a timer which executes a function once after the timer expires. Returns
 * an id which may be used to cancel the timeout.
 *
 *     setTimeout(() => { console.log('hello'); }, 500);
 */
declare function setTimeout(...)

but the output of deno doc --json cli/js/lib.deno.ns.d.ts has null jsDoc:

  {
    "kind": "function",
    "name": "setTimeout",
    "location": {
      "filename": "file:///home/chris/dev/deno/cli/js/lib.deno.shared_globals.d.ts",
      "line": 182,
      "col": 8
    },
    "jsDoc": null,
    ...

How to tell in JSON if the same thing is exported multiple ways

Sometimes, a module exports the same thing as both a named and default export, e.g in Foo.js:

export class Foo {}

export default Foo;

Run deno doc --json Foo.js and the output is:

[
  {
    "kind": "class",
    "name": "Foo",
    "location": {
      "filename": "file:///Users/jaydenseric/Sites/ruck/Foo.js",
      "line": 1,
      "col": 0
    },
    "jsDoc": null,
    "classDef": {
      "isAbstract": false,
      "constructors": [],
      "properties": [],
      "indexSignatures": [],
      "methods": [],
      "extends": null,
      "implements": [],
      "typeParams": [],
      "superTypeParams": []
    }
  },
  {
    "kind": "class",
    "name": "default",
    "location": {
      "filename": "file:///Users/jaydenseric/Sites/ruck/Foo.js",
      "line": 1,
      "col": 0
    },
    "jsDoc": null,
    "classDef": {
      "isAbstract": false,
      "constructors": [],
      "properties": [],
      "indexSignatures": [],
      "methods": [],
      "extends": null,
      "implements": [],
      "typeParams": [],
      "superTypeParams": []
    }
  }
]

Note the documentation data for the same class is repeated twice.

Ideally generated docs for this data would not repeat all of the documentation for the same class twice, but it would either have one entry that explains the two ways it can be imported, or a second entry for either the named or default export would link to the main docs for the class.

Can this be achieved using the current JSON data? It looks like the location is the same for both the named and default exports, is this a bug? It's not clear if the location should refer to the line of the export declaration or the source of an exported reference. Can location be relied upon to detect the same member exported twice? Although dumb, theoretically the same member could also be exported multiple times under multiple named exports (a common use case is aliases for the same thing).

What if the JSON data structure were to be this instead:

  [
    {
+     "exports": ["Foo", "default"],
      "kind": "class",
      "name": "Foo",
      "location": {
        "filename": "file:///Users/jaydenseric/Sites/ruck/Foo.js",
        "line": 1,
        "col": 0
      },
      "jsDoc": null,
      "classDef": {
        "isAbstract": false,
        "constructors": [],
        "properties": [],
        "indexSignatures": [],
        "methods": [],
        "extends": null,
        "implements": [],
        "typeParams": [],
        "superTypeParams": []
      }
    },
-   {
-     "kind": "class",
-     "name": "default",
-     "location": {
-       "filename": "file:///Users/jaydenseric/Sites/ruck/Foo.js",
-       "line": 1,
-       "col": 0
-     },
-     "jsDoc": null,
-     "classDef": {
-       "isAbstract": false,
-       "constructors": [],
-       "properties": [],
-       "indexSignatures": [],
-       "methods": [],
-       "extends": null,
-       "implements": [],
-       "typeParams": [],
-       "superTypeParams": []
-     }
    }
  ]

Add API to generate docs for AST instead of source code

For the purpose of denoland/deno#8641 we should have additional APIs on DocParser struct that allows to pass already parsed AST instead of source code.

Current API:

deno_doc/src/parser.rs

Lines 81 to 101 in c2f34ca

pub fn parse_module(
&self,
file_name: &str,
syntax: Syntax,
source_code: &str,
) -> Result<ModuleDoc, DocError> {
let parse_result =
self.ast_parser.parse_module(file_name, syntax, source_code);
let module = parse_result?;
let mut doc_entries =
self.get_doc_nodes_for_module_body(module.body.clone());
let import_doc_entries =
self.get_doc_nodes_for_module_imports(module.body.clone(), file_name)?;
doc_entries.extend(import_doc_entries);
let reexports = self.get_reexports_for_module_body(module.body);
let module_doc = ModuleDoc {
definitions: doc_entries,
reexports,
};
Ok(module_doc)
}

Proposed API:

  pub fn parse_ast(
    &self,
    file_name: &str,
    ast: &swc_ecmascript::ast::Module,
  ) -> Result<ModuleDoc, DocError>

Reflecting on the last year of deno_doc

It is time to reflect on the last year of deno_doc: what is good, what is bad, and what needs improvements. The main pain point I currently see is this: the doc.deno.land website needs to do a lot of post processing on the deno doc --json output to get all the features it wants. I have written down all the features I want in deno doc directly as concrete goals below:

Goals

The high level goal of deno_doc is to take a JS / JS+tsdoc / TS source file, and extract all information from this file that is relevant for documentation of the module, and output it in a structured and easy to consume format. Specifically:

  • The input should have to be no more than the root module, and all of it's (transitive) dependencies. All inputted modules consist of source code, a media type, and a fully resolved specifier.
  • The output should be structured data that describes the signatures of all functions / types / interfaces declared / exported in that file.
    • Each component in this structured data should contain a reference to the module it is defined it, so a user can be deep linked there.
    • The structured data should not encode the actual implementation of code in a module.
    • The structured data should expose doc comments on declarations of fields of those as raw markdown, but without the jsdoc / tsdoc parameters (they should be exposed as structured data).
    • The structured data should be flat. There should be no hierarchical structure for individual modules or TypeScript namespaces. Nesting is fine for things like fields of classes / interfaces.
  • The output of the structured data should be deterministic for a given input.
  • The output format should require no extra computation to be processed into HTML with signature syntax highlighting, node deep linking (also across modules), or cleaning of documentation comments.
  • The output format must be JSON serializable.
  • deno_doc should support compilation to arm64 and x64 on Windows, macOS and Linux, and compilation to WASM.
  • Module loading should be pluggable.
  • Partial module graphs should be supported (ie let me generate an output for a module, even if some of its dependencies are unavailable).

deno doc regression: unable to fetch files from GitHub releases

$ deno --version
deno 1.7.5 (release, x86_64-unknown-linux-gnu)
v8 9.0.123
typescript 4.1.4

$ deno doc https://github.com/denoland/deno/releases/latest/download/lib.deno.d.ts

(Output normally, omitted due to length)

$ deno --version
deno 1.8.1 (release, x86_64-unknown-linux-gnu)
v8 9.0.257.3
typescript 4.2.2

$ deno doc https://github.com/denoland/deno/releases/latest/download/lib.deno.d.ts
error: An unsupported media type was attempted to be imported as a module.
  Specifier: https://github-releases.githubusercontent.com/133442384/87f6cd80-811f-11eb-971d-592b7d186134?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20210311%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20210311T144531Z&X-Amz-Expires=300&X-Amz-Signature=4842754d7756c55649806f27575ded5d42dc2e8a3d482a6dced38be6e6e8290a&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=133442384&response-content-disposition=attachment%3B%20filename%3Dlib.deno.d.ts&response-content-type=application%2Foctet-stream
  MediaType: Unknown

TsType of properties should be intelligent

Right now, if a property doesn't explicitly specify a type ex: ```const var: Type = ..., deno_doc` doesn't populate the `tsType` field for it.

Sometimes, type is not needed as it can be guessed by the IDE and the typescript compiler as well

const type = "it's a string";

in that scenario, it's known that the default type of that variable is string, thus tsType should use such.

Fix location line and column

It seems the line and column on Location is display oriented. There are two issues though:

  1. We're using a tab indent width of 4. Shouldn't it be 2 since we use 2 spaced indents in deno fmt?
  2. Currently the line is 1-indexed, but the column is 0-indexed.

All that said, should this even be "display" oriented?

Show typedef-defined types in JS files

Types defined with @typedef are not displayed in console output under deno doc with the following deno version:

$ deno --version

deno 1.13.2 (release, x86_64-apple-darwin)
v8 9.3.345.11
typescript 4.3.5

For example,

// identity.js

/**
 * @template T
 * @typedef {Object} Identity
 * @property {<U>(f: (value: T) => U) => Identity<U>} map
 */

/**
 * @template T
 * @param {T} value
 * @return {Identity<T>}
 */
export function of(value) {
  return {
    map(f) {
      return of(f(value));
    }
  };
}
$ deno doc identity.js

function of(value)
  @template T
  @param {T} value
  @return {Identity<T>}

Importing the Identity type from a .ts file however shows that the type is indeed exported by the .js file.

// example.ts

import type { Identity } from './identity.js'; // works fine

It does not show up in deno doc identity.js though. If the type or interface were defined in a .ts file, it would appear in the output as:

// identity.ts

export interface Identity<T> {
  map<U>(f: (value: T) => U): Identity<U>
}
$ deno doc identity.ts

interface Identity<T>

  map(f: (value: T) => U): Identity<U>

Can types defined with JSDoc's @typedef be exposed by deno doc?

Documentation should take class extensions into consideration

As of right now, deno doc does not respect extensions. This means

export class B { 
   public id: number;
}
export class A extends B { 
  public userName: string;
}

if I run deno doc for class A, it will only document the property userName but will not for id part of the class extension.

deno doc should be able to read this, and respect the extensions of extensions (example, B extends C)

Support template literal types

The following:

export type World = "world";
 
export type Greeting = `hello ${World}`;

Greeting ends up being just "hello " and is missing the template literal type.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.