diff --git a/packages/cli/generators/controller/index.js b/packages/cli/generators/controller/index.js index e303381414c2..eebc70f638b3 100644 --- a/packages/cli/generators/controller/index.js +++ b/packages/cli/generators/controller/index.js @@ -236,13 +236,7 @@ module.exports = class ControllerGenerator extends ArtifactGenerator { debug(`artifactInfo: ${inspect(this.artifactInfo)}`); debug(`Copying artifact to: ${dest}`); } - this.fs.copyTpl( - source, - dest, - this.artifactInfo, - {}, - {globOptions: {dot: true}}, - ); + this.copyTemplatedFiles(source, dest, this.artifactInfo); return; } diff --git a/packages/cli/generators/datasource/index.js b/packages/cli/generators/datasource/index.js index 0d8509dead5b..141894401a7c 100644 --- a/packages/cli/generators/datasource/index.js +++ b/packages/cli/generators/datasource/index.js @@ -286,7 +286,7 @@ module.exports = class DataSourceGenerator extends ArtifactGenerator { // Copy Templates this.fs.writeJSON(jsonPath, ds); - this.fs.copyTpl(classTemplatePath, tsPath, this.artifactInfo); + this.copyTemplatedFiles(classTemplatePath, tsPath, this.artifactInfo); } install() { diff --git a/packages/cli/generators/model/index.js b/packages/cli/generators/model/index.js index f06a85cbd637..1704bb1e6aaa 100644 --- a/packages/cli/generators/model/index.js +++ b/packages/cli/generators/model/index.js @@ -345,7 +345,7 @@ module.exports = class ModelGenerator extends ArtifactGenerator { } }); - this.fs.copyTpl( + this.copyTemplatedFiles( this.templatePath(MODEL_TEMPLATE_PATH), tsPath, this.artifactInfo, diff --git a/packages/cli/generators/openapi/index.js b/packages/cli/generators/openapi/index.js index 3a1087a449ae..d48e34502aa7 100644 --- a/packages/cli/generators/openapi/index.js +++ b/packages/cli/generators/openapi/index.js @@ -126,7 +126,7 @@ module.exports = class OpenApiGenerator extends BaseGenerator { if (debug.enabled) { debug('Copying artifact to: %s', dest); } - this.fs.copyTpl(source, dest, c, {}, {globOptions: {dot: true}}); + this.copyTemplatedFiles(source, dest, c); } } @@ -144,7 +144,7 @@ module.exports = class OpenApiGenerator extends BaseGenerator { debug('Copying artifact to: %s', dest); } const source = m.kind === 'class' ? modelSource : typeSource; - this.fs.copyTpl(source, dest, m, {}, {globOptions: {dot: true}}); + this.copyTemplatedFiles(source, dest, m); } } diff --git a/packages/cli/generators/repository/index.js b/packages/cli/generators/repository/index.js index bd96fc4e8230..429cf9c67643 100644 --- a/packages/cli/generators/repository/index.js +++ b/packages/cli/generators/repository/index.js @@ -401,13 +401,7 @@ module.exports = class RepositoryGenerator extends ArtifactGenerator { debug(`artifactInfo: ${inspect(this.artifactInfo)}`); debug(`Copying artifact to: ${dest}`); } - this.fs.copyTpl( - source, - dest, - this.artifactInfo, - {}, - {globOptions: {dot: true}}, - ); + this.copyTemplatedFiles(source, dest, this.artifactInfo); return; } diff --git a/packages/cli/generators/service/index.js b/packages/cli/generators/service/index.js index bcb758032276..8a67f87c2ca7 100644 --- a/packages/cli/generators/service/index.js +++ b/packages/cli/generators/service/index.js @@ -233,13 +233,7 @@ module.exports = class ServiceGenerator extends ArtifactGenerator { debug(`artifactInfo: ${inspect(this.artifactInfo)}`); debug(`Copying artifact to: ${dest}`); - this.fs.copyTpl( - source, - dest, - this.artifactInfo, - {}, - {globOptions: {dot: true}}, - ); + this.copyTemplatedFiles(source, dest, this.artifactInfo); return; } diff --git a/packages/cli/lib/artifact-generator.js b/packages/cli/lib/artifact-generator.js index f843660f73be..8e7af1b839ee 100644 --- a/packages/cli/lib/artifact-generator.js +++ b/packages/cli/lib/artifact-generator.js @@ -71,12 +71,10 @@ module.exports = class ArtifactGenerator extends BaseGenerator { // Copy template files from ./templates // Renaming of the files should be done in the generator inheriting from this one - this.fs.copyTpl( + this.copyTemplatedFiles( this.templatePath('**/*'), this.destinationPath(), this.artifactInfo, - {}, - {globOptions: {dot: true}}, ); } diff --git a/packages/cli/lib/base-generator.js b/packages/cli/lib/base-generator.js index 05cbe10cecff..4c300ad06c9d 100644 --- a/packages/cli/lib/base-generator.js +++ b/packages/cli/lib/base-generator.js @@ -267,6 +267,42 @@ module.exports = class BaseGenerator extends Generator { this.npmInstall(null, opts, spawnOpts); } + /** + * Wrapper for mem-fs-editor.copyTpl() to ensure consistent options + * + * See https://github.com/SBoudrias/mem-fs-editor/blob/master/lib/actions/copy-tpl.js + * + * @param {string} from + * @param {string} to + * @param {object} context + * @param {object} templateOptions + * @param {object} copyOptions + */ + copyTemplatedFiles( + from, + to, + context, + templateOptions = {}, + copyOptions = { + // See https://github.com/mrmlnc/fast-glob#options-1 + globOptions: { + // Allow patterns to match filenames starting with a period (files & + // directories), even if the pattern does not explicitly have a period + // in that spot. + dot: true, + // Disable expansion of brace patterns ({a,b}, {1..3}). + nobrace: true, + // Disable extglob support (patterns like +(a|b)), so that extglobs + // are regarded as literal characters. This flag allows us to support + // Windows paths such as + // `D:\Users\BKU\oliverkarst\AppData(Roaming)\npm\node_modules\@loopback\cli` + noext: true, + }, + }, + ) { + return this.fs.copyTpl(from, to, context, templateOptions, copyOptions); + } + /** * Checks if current directory is a LoopBack project by checking for * keyword 'loopback' under 'keywords' attribute in package.json. diff --git a/packages/cli/lib/project-generator.js b/packages/cli/lib/project-generator.js index 3c5cf7024e32..bb640e756438 100644 --- a/packages/cli/lib/project-generator.js +++ b/packages/cli/lib/project-generator.js @@ -192,14 +192,12 @@ module.exports = class ProjectGenerator extends BaseGenerator { if (this.shouldExit()) return false; // First copy common files from ../../project/templates - this.fs.copyTpl( + this.copyTemplatedFiles( this.templatePath('../../project/templates/**/*'), this.destinationPath(''), { project: this.projectInfo, }, - {}, - {globOptions: {dot: true}}, ); // Rename `_.gitignore` back to `.gitignore`. @@ -211,14 +209,12 @@ module.exports = class ProjectGenerator extends BaseGenerator { ); // Copy project type specific files from ./templates - this.fs.copyTpl( + this.copyTemplatedFiles( this.templatePath('**/*'), this.destinationPath(''), { project: this.projectInfo, }, - {}, - {globOptions: {dot: true}}, ); if (!this.projectInfo.tslint) {