Skip to content

Commit

Permalink
feat: transliterate user defined content (#359)
Browse files Browse the repository at this point in the history
Use `jsii-rosetta` to transliterate assemblies before constructing the reflect TypeSystem.

This makes it so README code snippets as well as `@example` code blocks for inline documentation are also transliterated, providing a full language specific page. 

> Currently still in draft because it uses an unpublished version of `@jsii/spec` and `jsii-rosetta` pending a jsii release.

### Implementation Notes

Previously, the `Documentation` class accepted a **required** `reflect.Assembly` property. This meant that the creation of the type-system was the responsibility of the caller. This API is somewhat cumbersome,  and now that the assemblies need to be transliterated beforehand, this is even more so. 

The PR changes the input to the `Documentation` class, so that it only requires local paths that contain assembly files, it then proceeds to transliterate those assemblies and create the type-system on its own. 

Since the creation of the type-system is an `async` process, the `Documentation` class offers a `static async` function that needs to be awaited on, instead of directly using the constructor, which is now private. 

So the usage now becomes:

```ts
const docs = await Documentation.forLocalPackage(rootPath, assembliesPath);
const page = docs.render().render();
```

In addition, a new functionality of generating documentation for remote packages was added:

```ts
const docs = await Documentation.forRemotePackage('@aws-cdk/aws-ecr', '1.110.1');
const page = docs.render().render();
```

BREAKING CHANGE: The `Documentation` class can no longer be directly instantiated, use static factory methods instead.
  • Loading branch information
iliapolo authored Jul 12, 2021
1 parent f271ab5 commit 05c2d7e
Show file tree
Hide file tree
Showing 33 changed files with 10,382 additions and 5,414 deletions.
1 change: 1 addition & 0 deletions .gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 8 additions & 8 deletions .projen/deps.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions .projenrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ const project = new TypeScriptProject({
},
devDeps: [
'@types/fs-extra@^8', // >8 needs a newer node version
'glob-promise',
'glob',
],
deps: [
'yargs',
'fs-extra',
'case',
'glob-promise',
'glob',
'jsii-reflect',
'jsii-rosetta',
'@jsii/spec',
],
compileBeforeTest: true, // we need this for the CLI test
Expand All @@ -42,4 +42,6 @@ for (const library of libraryFixtures) {
project.compileTask.exec('npm run compile', { cwd: `./test/__fixtures__/libraries/${library}` });
}

// artifacts created by transpilation in tests
project.gitignore.exclude('test/**/.jsii.*');
project.synth();
11 changes: 1 addition & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,8 @@ As a library:

```ts
import { Documentation } from 'jsii-docgen';
import * as reflect from 'jsii-reflect';

const ts = new reflect.TypeSystem();
await ts.loadFile('my/project/.jsii');

const docs = new Documentation({
assembly: ts.findAssembly('my-project-name'),
language: 'ts',
readme: false,
});

const docs = await Documentation.forLocalPackage('.', { language: 'ts' });
const markdown = docs.render().render(); // returns a markdown string
```

Expand Down
4 changes: 2 additions & 2 deletions package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 3 additions & 37 deletions src/cli.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import * as fs from 'fs';
import * as path from 'path';
import * as glob from 'glob';
import * as reflect from 'jsii-reflect';
import * as yargs from 'yargs';
import { Documentation } from './index';

Expand All @@ -12,41 +9,10 @@ export async function main() {
.example('$0', 'Generate documentation for the current module as a single file (auto-resolves node depedencies)')
.argv;

const assembly = await createAssembly();

const docs = new Documentation({
assembly,
language: 'ts',
readme: false,
});

const docs = await Documentation.forProject(process.cwd());
const output = args.output ?? 'API.md';

const markdown = docs.render().render();
fs.writeFileSync(output, markdown);
}

async function createAssembly(): Promise<reflect.Assembly> {

const ts = new reflect.TypeSystem();
const root = path.join(process.cwd(), '.jsii');

if (!fs.existsSync(root)) {
throw new Error(`Unable to locate jsii assembly at: ${root}. Make sure to run this command `
+ 'from the root directory of your package after the jsii assembly has been created.');
}

await ts.loadFile('.jsii', { isRoot: true });

// using 'glob' here is arguably a little wasteful, but better
// then maintaining code trying to accurately deduce where each
// required assembly is located.
for (let dependency of glob.sync('./node_modules/**/.jsii')) {
await ts.load(dependency);
}

return ts.roots[0];

const markdown = docs.render({ readme: false });
fs.writeFileSync(output, markdown.render());
}

main().catch(e => {
Expand Down
1 change: 0 additions & 1 deletion src/docgen/render/markdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,6 @@ export class Markdown {
// This will be gone soon.
// Note though that cross links (i.e links dependencies will not work yet regardless)
const headerSpan = !!process.env.HEADER_SPAN;
console.log(`Header span: ${headerSpan}`);
if (headerSpan) {
content.push(
`${heading} <span data-heading-title="${this.header}" data-heading-id="${anchor}"></span>`,
Expand Down
2 changes: 1 addition & 1 deletion src/docgen/transpile/python.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ const propertyToParameter = (
*/
export class PythonTranspile extends transpile.TranspileBase {
constructor() {
super('python');
super(transpile.Language.PYTHON);
}

public readme(readme: string): string {
Expand Down
49 changes: 46 additions & 3 deletions src/docgen/transpile/transpile.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,48 @@
import * as reflect from 'jsii-reflect';

/**
* Supported languages to generate documentation in.
*/
export class Language {
/**
* TypeScript.
*/
public static readonly TYPESCRIPT = new Language('typescript');

/**
* Python.
*/
public static readonly PYTHON = new Language('python');

/**
* Transform a literal string to the `Language` object.
*
* Throws an `UnsupportedLanguageError` if the language is not supported.
*/
public static fromString(lang: string) {
switch (lang) {
case Language.TYPESCRIPT.toString():
return Language.TYPESCRIPT;
case Language.PYTHON.toString():
return Language.PYTHON;
default:
throw new UnsupportedLanguageError(lang, [Language.TYPESCRIPT, Language.PYTHON]);
}
}

private constructor(private readonly lang: string) {}

public toString() {
return this.lang;
}
}

export class UnsupportedLanguageError extends Error {
constructor(lang: string, supported: Language[]) {
super(`Unsupported language: ${lang}. Supported languages are: [${supported}]`);
}
}

/**
* Outcome of transpiling a jsii struct.
*/
Expand Down Expand Up @@ -374,9 +417,9 @@ export interface TranspiledModuleLike {
*/
export interface Transpile {
/**
* The language of the tranpiler.
* The language of the transpiler.
*/
language: string;
readonly language: Language;

/**
* Transpile a module like object (Assembly | Submodule)
Expand Down Expand Up @@ -492,7 +535,7 @@ export interface TranspileBase extends Transpile {}
* Common functionality between different transpilers.
*/
export abstract class TranspileBase implements Transpile {
constructor(public readonly language: string) {}
constructor(public readonly language: Language) {}

public type(type: reflect.Type): TranspiledType {
const submodule = this.findSubmodule(type);
Expand Down
2 changes: 1 addition & 1 deletion src/docgen/transpile/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const formatSignature = (name: string, inputs: string[]) => {
*/
export class TypeScriptTranspile extends transpile.TranspileBase {
constructor() {
super('typescript');
super(transpile.Language.TYPESCRIPT);
}

public readme(readme: string): string {
Expand Down
Loading

0 comments on commit 05c2d7e

Please sign in to comment.