Skip to content

Commit

Permalink
fix(docs): Allow @ char in jsdoc comments to be escaped
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelbromley committed Jun 7, 2019
1 parent 6564d3f commit bdc0d1f
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 21 deletions.
6 changes: 3 additions & 3 deletions packages/admin-ui-plugin/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,15 @@ export interface AdminUiOptions {
*
* ## Installation
*
* `yarn add @vendure/admin-ui-plugin`
* `yarn add \@vendure/admin-ui-plugin`
*
* or
*
* `npm install @vendure/admin-ui-plugin`
* `npm install \@vendure/admin-ui-plugin`
*
* @example
* ```ts
* import { AdminUiPlugin } from '@vendure/admin-ui-plugin';
* import { AdminUiPlugin } from '\@vendure/admin-ui-plugin';
*
* const config: VendureConfig = {
* // Add an instance of the plugin to the plugins array
Expand Down
6 changes: 3 additions & 3 deletions packages/asset-server-plugin/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,15 +104,15 @@ export interface AssetServerOptions {
*
* ## Installation
*
* `yarn add @vendure/asset-server-plugin`
* `yarn add \@vendure/asset-server-plugin`
*
* or
*
* `npm install @vendure/asset-server-plugin`
* `npm install \@vendure/asset-server-plugin`
*
* @example
* ```ts
* import { AssetServerPlugin } from '@vendure/asset-server-plugin';
* import { AssetServerPlugin } from '\@vendure/asset-server-plugin';
*
* const config: VendureConfig = {
* // Add an instance of the plugin to the plugins array
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,19 @@ export interface DefaultSearchPluginOptions {
* The DefaultSearchPlugin provides a full-text Product search based on the full-text searching capabilities of the
* underlying database.
*
* The DefaultSearchPlugin is bundled with the `@vendure/core` package. If you are not using an alternative search
* plugin, then make sure this one is used, otherwise you will not be able to search products via the [`search` query](/docs/graphql-api/shop/queries#search).
* The DefaultSearchPlugin is bundled with the `\@vendure/core` package. If you are not using an alternative search
* plugin, then make sure this one is used, otherwise you will not be able to search products via the
* [`search` query](/docs/graphql-api/shop/queries#search).
*
* {{% alert "warning" %}}
* Note that the quality of the fulltext search capabilities varies depending on the underlying database being used. For example,
* the MySQL & Postgres implementations will typically yield better results than the SQLite implementation.
* {{% /alert %}}
*
*
* @example
* ```ts
* import { DefaultSearchPlugin } from '@vendure/core';
* import { DefaultSearchPlugin } from '\@vendure/core';
*
* const config: VendureConfig = {
* // Add an instance of the plugin to the plugins array
Expand All @@ -63,10 +70,6 @@ export interface DefaultSearchPluginOptions {
* };
* ```
*
* {{% alert "warning" %}}
* Note that the quality of the fulltext search capabilities varies depending on the underlying database being used. For example, the MySQL & Postgres implementations will typically yield better results than the SQLite implementation.
* {{% /alert %}}
*
* @docsCategory DefaultSearchPlugin
*/
export class DefaultSearchPlugin implements VendurePlugin {
Expand Down
10 changes: 5 additions & 5 deletions packages/email-plugin/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ import { EmailPluginDevModeOptions, EmailPluginOptions, EmailTransportOptions, E
*
* ## Installation
*
* `yarn add @vendure/email-plugin`
* `yarn add \@vendure/email-plugin`
*
* or
*
* `npm install @vendure/email-plugin`
* `npm install \@vendure/email-plugin`
*
* @example
* ```ts
* import { defaultEmailHandlers, EmailPlugin } from '@vendure/email-plugin';
* import { defaultEmailHandlers, EmailPlugin } from '\@vendure/email-plugin';
*
* const config: VendureConfig = {
* // Add an instance of the plugin to the plugins array
Expand All @@ -48,11 +48,11 @@ import { EmailPluginDevModeOptions, EmailPluginOptions, EmailTransportOptions, E
* ## Email templates
*
* In the example above, the plugin has been configured to look in `<app-root>/vendure/email/templates`
* for the email template files. If you used `@vendure/create` to create your application, the templates will have
* for the email template files. If you used `\@vendure/create` to create your application, the templates will have
* been copied to that location during setup.
*
* If you are installing the EmailPlugin separately, then you'll need to copy the templates manually from
* `node_modules/@vendure/email-plugin/templates` to a location of your choice, and then point the `templatePath` config
* `node_modules/\@vendure/email-plugin/templates` to a location of your choice, and then point the `templatePath` config
* property at that directory.
*
* ## Customizing templates
Expand Down
26 changes: 23 additions & 3 deletions scripts/docs/typescript-docs-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import {
*/
export class TypescriptDocsParser {

private readonly atTokenPlaceholder = '__EscapedAtToken__';

/**
* Parses the TypeScript files given by the filePaths array and returns the
* parsed data structures ready for rendering.
Expand All @@ -30,7 +32,7 @@ export class TypescriptDocsParser {
const sourceFiles = filePaths.map(filePath => {
return ts.createSourceFile(
filePath,
fs.readFileSync(filePath).toString(),
this.replaceEscapedAtTokens(fs.readFileSync(filePath).toString()),
ts.ScriptTarget.ES2015,
true,
);
Expand Down Expand Up @@ -237,7 +239,7 @@ export class TypescriptDocsParser {
const memberInfo: MemberInfo = {
fullText,
name,
description,
description: this.restoreAtTokens(description),
type,
modifiers,
};
Expand Down Expand Up @@ -290,7 +292,7 @@ export class TypescriptDocsParser {
description: tag => (description += tag.comment),
example: tag => (description += this.formatExampleCode(tag.comment)),
});
return description;
return this.restoreAtTokens(description);
}

/**
Expand Down Expand Up @@ -348,4 +350,22 @@ export class TypescriptDocsParser {
return input.replace(/([a-z])([A-Z])/g, '$1-$2').replace(/\s+/g, '-').toLowerCase() as T;
}

/**
* TypeScript from v3.5.1 interprets all '@' tokens in a tag comment as a new tag. This is a problem e.g.
* when a plugin includes in it's description some text like "install the @vendure/some-plugin package". Here,
* TypeScript will interpret "@vendure" as a JSDoc tag and remove it and all remaining text from the comment.
*
* The solution is to replace all escaped @ tokens ("\@") with a replacer string so that TypeScript treats them
* as regular comment text, and then once it has parsed the statement, we replace them with the "@" character.
*/
private replaceEscapedAtTokens(content: string): string {
return content.replace(/\\@/g, this.atTokenPlaceholder);
}

/**
* Restores "@" tokens which were replaced by the replaceEscapedAtTokens() method.
*/
private restoreAtTokens(content: string): string {
return content.replace(new RegExp(this.atTokenPlaceholder, 'g'), '@');
}
}

0 comments on commit bdc0d1f

Please sign in to comment.