From dd6eee3504a12e15ed48e69358ea0266e487badf Mon Sep 17 00:00:00 2001 From: Vinicius Rosa Date: Tue, 31 Jan 2023 18:45:42 +1100 Subject: [PATCH] feat(ui-devkit): Add "exclude" option to UI extensions (#2009) --- packages/ui-devkit/src/compiler/scaffold.ts | 13 +++++++++++- packages/ui-devkit/src/compiler/types.ts | 12 +++++++++++ scripts/docs/typescript-docs-parser.ts | 22 ++++++++++++--------- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/packages/ui-devkit/src/compiler/scaffold.ts b/packages/ui-devkit/src/compiler/scaffold.ts index e74c5a2f58..6657a676bb 100644 --- a/packages/ui-devkit/src/compiler/scaffold.ts +++ b/packages/ui-devkit/src/compiler/scaffold.ts @@ -1,6 +1,7 @@ /* tslint:disable:no-console */ import { spawn } from 'child_process'; import * as fs from 'fs-extra'; +import glob from 'glob'; import * as path from 'path'; import { @@ -103,7 +104,17 @@ async function copyExtensionModules(outputPath: string, extensions: Array glob.sync(path.join(extension.extensionPath, e))) + .flatMap(e => e); + fs.copySync(extension.extensionPath, dest, { + filter: name => name === extension.extensionPath || exclude.every(e => e !== name), + }); } } diff --git a/packages/ui-devkit/src/compiler/types.ts b/packages/ui-devkit/src/compiler/types.ts index 95fa359ca5..d52abda3a5 100644 --- a/packages/ui-devkit/src/compiler/types.ts +++ b/packages/ui-devkit/src/compiler/types.ts @@ -206,6 +206,18 @@ export interface AdminUiExtension * ``` */ pathAlias?: string; + + /** + * @description + * Optional array specifying filenames or [glob](https://github.com/isaacs/node-glob) patterns that should + * be skipped when copying the directory defined by `extensionPath`. + * + * @example + * ```ts + * exclude: ['**\/*.spec.ts'] + * ``` + */ + exclude?: string[]; } /** diff --git a/scripts/docs/typescript-docs-parser.ts b/scripts/docs/typescript-docs-parser.ts index 25a9c56498..a697b7a91e 100644 --- a/scripts/docs/typescript-docs-parser.ts +++ b/scripts/docs/typescript-docs-parser.ts @@ -20,6 +20,7 @@ import { */ export class TypescriptDocsParser { private readonly atTokenPlaceholder = '__EscapedAtToken__'; + private readonly commentBlockEndTokenPlaceholder = '__EscapedCommentBlockEndToken__' /** * Parses the TypeScript files given by the filePaths array and returns the @@ -29,7 +30,7 @@ export class TypescriptDocsParser { const sourceFiles = filePaths.map(filePath => { return ts.createSourceFile( filePath, - this.replaceEscapedAtTokens(fs.readFileSync(filePath).toString()), + this.replaceEscapedTokens(fs.readFileSync(filePath).toString()), ts.ScriptTarget.ES2015, true, ); @@ -288,7 +289,7 @@ export class TypescriptDocsParser { const memberInfo: MemberInfo = { fullText, name, - description: this.restoreAtTokens(description), + description: this.restoreTokens(description), type, modifiers, since, @@ -383,7 +384,7 @@ export class TypescriptDocsParser { description: comment => (description += comment), example: comment => (description += this.formatExampleCode(comment)), }); - return this.restoreAtTokens(description); + return this.restoreTokens(description); } /** @@ -446,20 +447,23 @@ export class TypescriptDocsParser { /** * 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, + * when a plugin includes in its 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. + * + * Similarly, '/*' is interpreted as end of a comment block. However, it can be useful to specify a globstar + * pattern in descriptions and therefore it is supported as long as the leading '/' is escaped ("\/"). */ - private replaceEscapedAtTokens(content: string): string { - return content.replace(/\\@/g, this.atTokenPlaceholder); + private replaceEscapedTokens(content: string): string { + return content.replace(/\\@/g, this.atTokenPlaceholder).replace(/\\\/\*/g, this.commentBlockEndTokenPlaceholder); } /** - * Restores "@" tokens which were replaced by the replaceEscapedAtTokens() method. + * Restores "@" and "/*" tokens which were replaced by the replaceEscapedTokens() method. */ - private restoreAtTokens(content: string): string { - return content.replace(new RegExp(this.atTokenPlaceholder, 'g'), '@'); + private restoreTokens(content: string): string { + return content.replace(new RegExp(this.atTokenPlaceholder, 'g'), '@').replace(new RegExp(this.commentBlockEndTokenPlaceholder, 'g'), '/*'); } }