Browse Source

fix(docs): Allow @ char in jsdoc comments to be escaped

Michael Bromley 6 years ago
parent
commit
bdc0d1f29e

+ 3 - 3
packages/admin-ui-plugin/src/plugin.ts

@@ -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

+ 3 - 3
packages/asset-server-plugin/src/plugin.ts

@@ -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

+ 10 - 7
packages/core/src/plugin/default-search-plugin/default-search-plugin.ts

@@ -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
@@ -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 {

+ 5 - 5
packages/email-plugin/src/plugin.ts

@@ -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
@@ -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

+ 23 - 3
scripts/docs/typescript-docs-parser.ts

@@ -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.
@@ -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,
             );
@@ -237,7 +239,7 @@ export class TypescriptDocsParser {
                 const memberInfo: MemberInfo = {
                     fullText,
                     name,
-                    description,
+                    description: this.restoreAtTokens(description),
                     type,
                     modifiers,
                 };
@@ -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);
     }
 
     /**
@@ -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'), '@');
+    }
 }