From 855dcbbb4b61fc64f5905f7a9124e56e0b55d50e Mon Sep 17 00:00:00 2001 From: David Yusta Date: Mon, 27 Nov 2023 10:50:15 +0100 Subject: [PATCH] refactor: lint and format files --- .../@guidesmiths/cuckoojs-cli/src/cli.spec.ts | 6 +- packages/@guidesmiths/cuckoojs-cli/src/cli.ts | 107 ++++---- .../src/commands/abstract.command.ts | 19 +- .../src/commands/generate.command.ts | 50 ++-- .../cuckoojs-cli/src/commands/index.ts | 4 +- .../src/commands/lambda-new.command.ts | 257 ++++++++++-------- .../cuckoojs-cli/src/commands/new.command.ts | 94 ++++--- .../cuckoojs-cli/src/lib/printer/printer.ts | 157 ++++++----- .../src/lib/runners/bash.runner.husky.ts | 39 +-- .../src/lib/runners/generic.runner.ts | 12 +- .../src/lib/runners/git.runner.ts | 31 ++- .../src/lib/runners/nest.runner.ts | 27 +- .../src/lib/runners/npm.runner.ts | 128 +++++---- .../src/lib/runners/schematic.runner.ts | 93 ++++--- .../cuckoojs-cli/src/lib/ui/ui.ts | 4 +- .../utils/PackageManager/PackageManager.ts | 17 +- .../src/lib/utils/Prompter/Prompter.ts | 23 +- .../src/lib/utils/sortObjectByKeys.ts | 13 +- .../cuckoojs-cli/src/lib/utils/spawnAsync.ts | 28 +- .../basic-tooling/basic-tooling.factory.ts | 44 +-- .../src/ci/ci.factory.spec.ts | 48 ++-- .../cuckoojs-schematics/src/ci/ci.factory.ts | 40 +-- .../src/commitlint/commitlint.factory.ts | 66 +++-- .../src/dockerfile/dockerfile.factory.spec.ts | 42 +-- .../src/dockerfile/dockerfile.factory.ts | 84 +++--- .../src/eslint/eslint.factory.spec.ts | 48 ++-- .../src/eslint/eslint.factory.ts | 88 +++--- .../src/gitignore/gitignore.factory.spec.ts | 18 +- .../src/gitignore/gitignore.factory.ts | 49 ++-- .../helm-strategies/helm.strategy.factory.ts | 4 +- .../src/helm/helm-strategies/helm.strategy.ts | 30 +- .../generic.Ingress.strategy.ts | 10 +- .../ingress-controller/ingress.strategy.ts | 17 +- .../tls-cert/tlsCert.strategy.ts | 22 +- .../src/helm/helm.factory.spec.ts | 30 +- .../src/helm/rule-builder/rule.builder.ts | 137 ++++++---- .../src/husky/husky.factory.ts | 93 ++++--- .../lambda-quickstart.factory.spec.ts | 63 +++-- .../lambda-quickstart.factory.ts | 66 +++-- .../nestjs-config.factory.spec.ts | 16 +- .../nestjs-config/nestjs-config.factory.ts | 33 ++- .../utils/add-config-to-module-change.ts | 122 +++++---- .../utils/add-config-to-module-rule.ts | 46 ++-- .../utils/add-imports-to-file-change.ts | 26 +- .../src/nvmrc/nvmrc.factory.ts | 63 ++--- .../pr-template/pr-template.factory.spec.ts | 42 +-- .../src/pr-template/pr-template.factory.ts | 40 ++- .../src/utils/ast-utils.ts | 168 +++++++++--- .../cuckoojs-schematics/src/utils/change.ts | 31 ++- .../src/utils/package-json.utils.ts | 179 ++++++------ 50 files changed, 1589 insertions(+), 1285 deletions(-) diff --git a/packages/@guidesmiths/cuckoojs-cli/src/cli.spec.ts b/packages/@guidesmiths/cuckoojs-cli/src/cli.spec.ts index 7bf02eac..583cf874 100644 --- a/packages/@guidesmiths/cuckoojs-cli/src/cli.spec.ts +++ b/packages/@guidesmiths/cuckoojs-cli/src/cli.spec.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from '@jest/globals'; describe('pr-template', () => { - it('hello world', () => { - expect('hello world').toBe('hello world'); - }); + it('hello world', () => { + expect('hello world').toBe('hello world'); + }); }); diff --git a/packages/@guidesmiths/cuckoojs-cli/src/cli.ts b/packages/@guidesmiths/cuckoojs-cli/src/cli.ts index a8ff35c9..71b2edec 100755 --- a/packages/@guidesmiths/cuckoojs-cli/src/cli.ts +++ b/packages/@guidesmiths/cuckoojs-cli/src/cli.ts @@ -1,65 +1,70 @@ #!/usr/bin/env node -import {Option, Command} from 'commander'; -import {version} from '../package.json'; -import {NewCommand, GenerateCommand} from './commands'; -import {LambdaNewCommand} from "./commands/lambda-new.command"; +import { Option, Command } from 'commander'; +import { version } from '../package.json'; +import { NewCommand, GenerateCommand } from './commands'; +import { LambdaNewCommand } from './commands/lambda-new.command'; const init = (): void => { - const cuckoo = new Command('cuckoo'); + const cuckoo = new Command('cuckoo'); - cuckoo - .version( - version, - '-v, --version', - 'Output the current version.', - ); + cuckoo.version(version, '-v, --version', 'Output the current version.'); - cuckoo - .helpOption('-h, --help', 'Output usage information.') - .showHelpAfterError() - .usage(' [options]'); + cuckoo + .helpOption('-h, --help', 'Output usage information.') + .showHelpAfterError() + .usage(' [options]'); - const nest = cuckoo - .command('nest') - .description('Generate nest template') + const nest = cuckoo.command('nest').description('Generate nest template'); - nest - .command('new [options...]') - .alias('n') - .description('Generate Nest application with basic tooling.') - .action(async (name: string) => { - await new NewCommand(name).execute(); - }); + nest + .command('new [options...]') + .alias('n') + .description('Generate Nest application with basic tooling.') + .action(async (name: string) => { + await new NewCommand(name).execute(); + }); - nest - .command('generate [options...]') - .alias('g') - .description('Generate a Nest element.') - .action(async (schematic: string, name: string, options: string[]) => { - await new GenerateCommand(schematic, name, options).execute(); - }); + nest + .command('generate [options...]') + .alias('g') + .description('Generate a Nest element.') + .action(async (schematic: string, name: string, options: string[]) => { + await new GenerateCommand(schematic, name, options).execute(); + }); - const lambda = cuckoo - .command('lambda') - .description('Generate lambda template') + const lambda = cuckoo + .command('lambda') + .description('Generate lambda template'); - lambda - .command('new ') - .alias('n') - .description('Generate an AWS Lambda Quickstart') - .addOption( - new Option('-g, --git-provider ', 'Git provider to host the repo') - .choices(['github', 'azuredevops']) - .default('github')) - .addOption( - new Option('--skip-git-init', 'Skip git repository initialization') - ) - .action(async (name: string, options: { gitProvider: string, skipGitInit: string}) => { - await new LambdaNewCommand(name, options.gitProvider, !!options.skipGitInit).execute(); - }); + lambda + .command('new ') + .alias('n') + .description('Generate an AWS Lambda Quickstart') + .addOption( + new Option( + '-g, --git-provider ', + 'Git provider to host the repo', + ) + .choices(['github', 'azuredevops']) + .default('github'), + ) + .addOption( + new Option('--skip-git-init', 'Skip git repository initialization'), + ) + .action( + async ( + name: string, + options: { gitProvider: string; skipGitInit: string }, + ) => { + await new LambdaNewCommand( + name, + options.gitProvider, + !!options.skipGitInit, + ).execute(); + }, + ); - cuckoo - .parse(process.argv); + cuckoo.parse(process.argv); }; init(); diff --git a/packages/@guidesmiths/cuckoojs-cli/src/commands/abstract.command.ts b/packages/@guidesmiths/cuckoojs-cli/src/commands/abstract.command.ts index 5c0f4a95..f4c8eb3d 100644 --- a/packages/@guidesmiths/cuckoojs-cli/src/commands/abstract.command.ts +++ b/packages/@guidesmiths/cuckoojs-cli/src/commands/abstract.command.ts @@ -1,12 +1,17 @@ import Printer from '../lib/printer/printer'; export class AbstractCommand { - protected static endProcess(status: number) { - process.exit(status); - } + protected static endProcess(status: number) { + process.exit(status); + } - protected printSuccess = Printer.format({fontColor: 'green', decoration: 'bold'}); - protected printError = Printer.format({fontColor: 'red', decoration: 'bold'}); - protected printNeutral = Printer.format({decoration: 'bold'}); + protected printSuccess = Printer.format({ + fontColor: 'green', + decoration: 'bold', + }); + protected printError = Printer.format({ + fontColor: 'red', + decoration: 'bold', + }); + protected printNeutral = Printer.format({ decoration: 'bold' }); } - diff --git a/packages/@guidesmiths/cuckoojs-cli/src/commands/generate.command.ts b/packages/@guidesmiths/cuckoojs-cli/src/commands/generate.command.ts index 529f1b62..8949ae89 100644 --- a/packages/@guidesmiths/cuckoojs-cli/src/commands/generate.command.ts +++ b/packages/@guidesmiths/cuckoojs-cli/src/commands/generate.command.ts @@ -1,28 +1,34 @@ -import {messages} from '../lib/ui/ui'; -import {AbstractCommand} from './abstract.command'; -import {NestRunner} from '../lib/runners/nest.runner'; +import { messages } from '../lib/ui/ui'; +import { AbstractCommand } from './abstract.command'; +import { NestRunner } from '../lib/runners/nest.runner'; export class GenerateCommand extends AbstractCommand { - private readonly schematicRunner: NestRunner = new NestRunner(); + private readonly schematicRunner: NestRunner = new NestRunner(); - constructor( - private readonly schematic: string, - private readonly name: string, - private readonly options: string[], - ) { - super(); - } + constructor( + private readonly schematic: string, + private readonly name: string, + private readonly options: string[], + ) { + super(); + } - public async execute() { - this.printSuccess(messages.banner); + public async execute() { + this.printSuccess(messages.banner); - try { - this.printNeutral(`Generating Nest ${this.schematic}.`); - await this.schematicRunner.generateNestElement(this.schematic, this.name, this.options); - this.printSuccess(`Nest ${this.schematic} generated.`); - } catch (error: unknown) { - this.printError(`Error generating Nest ${this.schematic}: ${(error as Error).message}`); - GenerateCommand.endProcess(1); - } - } + try { + this.printNeutral(`Generating Nest ${this.schematic}.`); + await this.schematicRunner.generateNestElement( + this.schematic, + this.name, + this.options, + ); + this.printSuccess(`Nest ${this.schematic} generated.`); + } catch (error: unknown) { + this.printError( + `Error generating Nest ${this.schematic}: ${(error as Error).message}`, + ); + GenerateCommand.endProcess(1); + } + } } diff --git a/packages/@guidesmiths/cuckoojs-cli/src/commands/index.ts b/packages/@guidesmiths/cuckoojs-cli/src/commands/index.ts index f7ed9e33..51b60a4b 100644 --- a/packages/@guidesmiths/cuckoojs-cli/src/commands/index.ts +++ b/packages/@guidesmiths/cuckoojs-cli/src/commands/index.ts @@ -1,2 +1,2 @@ -export {NewCommand} from './new.command'; -export {GenerateCommand} from './generate.command'; +export { NewCommand } from './new.command'; +export { GenerateCommand } from './generate.command'; diff --git a/packages/@guidesmiths/cuckoojs-cli/src/commands/lambda-new.command.ts b/packages/@guidesmiths/cuckoojs-cli/src/commands/lambda-new.command.ts index 60f78d1e..37877371 100644 --- a/packages/@guidesmiths/cuckoojs-cli/src/commands/lambda-new.command.ts +++ b/packages/@guidesmiths/cuckoojs-cli/src/commands/lambda-new.command.ts @@ -1,126 +1,143 @@ -import {SchematicRunner} from '../lib/runners/schematic.runner'; -import type {PackageEntry, ScriptEntry} from '../lib/runners/npm.runner'; -import {NpmRunner} from '../lib/runners/npm.runner'; -import {messages} from '../lib/ui/ui'; +import { SchematicRunner } from '../lib/runners/schematic.runner'; +import type { PackageEntry, ScriptEntry } from '../lib/runners/npm.runner'; +import { NpmRunner } from '../lib/runners/npm.runner'; +import { messages } from '../lib/ui/ui'; import * as fs from 'fs'; -import {join} from 'path'; -import {BashRunnerHusky} from '../lib/runners/bash.runner.husky'; -import {AbstractCommand} from './abstract.command'; +import { join } from 'path'; +import { BashRunnerHusky } from '../lib/runners/bash.runner.husky'; +import { AbstractCommand } from './abstract.command'; import Printer from '../lib/printer/printer'; -import {GitRunner} from "../lib/runners/git.runner"; +import { GitRunner } from '../lib/runners/git.runner'; export class LambdaNewCommand extends AbstractCommand { - private readonly schematicRunner: SchematicRunner = new SchematicRunner(); - private readonly gitRunner: GitRunner = new GitRunner(); - private readonly npmRunner: NpmRunner = new NpmRunner(); - private readonly bashRunnerHusky: BashRunnerHusky = new BashRunnerHusky(); - - private readonly initialPackages: PackageEntry[] = [ - {name: 'husky', version: '^8.0.1', section: 'devDependencies'}, - ]; - - private readonly initialScripts: ScriptEntry[] = [ - {name: 'prepare', value: 'husky install'}, - {name: 'postinstall', value: 'npx @guidesmiths/license-checker --outputFileName license-report --failOn /GPL/'}, - ]; - - constructor( - private readonly name: string, - private readonly gitProvider: string, - private readonly skipGitInit: boolean - ) { - super(); - } - - public async execute() { - const printer = new Printer(); - this.printSuccess(messages.banner); - - if (this.checkFileExists()) { - if(this.skipGitInit){ - this.printNeutral(`Folder ${this.name} already exists but git won't be initialized there`); - }else{ - this.printError(`Error generating new project: Folder ${this.name} already exists`); - LambdaNewCommand.endProcess(1); - } - } else { - if(this.skipGitInit) { - this.printNeutral(`Folder ${this.name} does not exist and git won't be initialized there`); - } - } - - try { - this.checkFileExists(); - - printer.startStep('Generating AWS Lambda scaffolding'); - await this.schematicRunner.addLambdaQuickstart(this.name); - printer.endStep(); - - printer.startStep('Initializing Git repository'); - if (this.skipGitInit) { - printer.updateStep('[Skipped] Initializing Git repository'); - } else { - await this.gitRunner.init(this.name); - await this.gitRunner.createBranch({folderName: this.name}); - } - printer.endStep(); - - printer.startStep('Adding additional packages'); - await this.npmRunner.addPackages(this.name, this.initialPackages); - printer.endStep(); - - printer.startStep('Adding additional npm scripts'); - await this.npmRunner.addScripts(this.name, this.initialScripts); - printer.endStep(); - - printer.startStep('Adding commitlint config file'); - await this.schematicRunner.addCommitlint(this.name); - printer.endStep(); - - printer.startStep('Adding .gitignore file'); - await this.schematicRunner.addGitignoreFile(this.name); - printer.endStep(); - - printer.startStep('Setting ESlint config'); - await this.schematicRunner.addESlint(this.name); - printer.endStep(); - - printer.startStep('Adding Pull Request template file'); - await this.schematicRunner.addPullRequestTemplate(this.name, this.gitProvider); - printer.endStep(); - - printer.startStep('Installing dependencies'); - await this.npmRunner.install(this.name); - printer.endStep(); - - printer.startStep('Applying ESlist config'); - await this.npmRunner.runScript(this.name, 'lint:fix'); - printer.endStep(); - - printer.startStep('Creating husky files'); - await this.npmRunner.runScript(this.name, 'prepare'); - await this.bashRunnerHusky.addHuskyCommitMsg(this.name); - await this.bashRunnerHusky.addHuskyPrePush(this.name); - printer.endStep(); - - this.printSuccess(`\n 🐦 Your CuckooJS Lambda "${this.name}" is generated and ready to use 🐦`); - } catch (error: unknown) { - printer.load.fail(`Error generating new project: ${(error as Error).message}`); - this.removeFolder(); + private readonly schematicRunner: SchematicRunner = new SchematicRunner(); + private readonly gitRunner: GitRunner = new GitRunner(); + private readonly npmRunner: NpmRunner = new NpmRunner(); + private readonly bashRunnerHusky: BashRunnerHusky = new BashRunnerHusky(); + + private readonly initialPackages: PackageEntry[] = [ + { name: 'husky', version: '^8.0.1', section: 'devDependencies' }, + ]; + + private readonly initialScripts: ScriptEntry[] = [ + { name: 'prepare', value: 'husky install' }, + { + name: 'postinstall', + value: + 'npx @guidesmiths/license-checker --outputFileName license-report --failOn /GPL/', + }, + ]; + + constructor( + private readonly name: string, + private readonly gitProvider: string, + private readonly skipGitInit: boolean, + ) { + super(); + } + + public async execute() { + const printer = new Printer(); + this.printSuccess(messages.banner); + + if (this.checkFileExists()) { + if (this.skipGitInit) { + this.printNeutral( + `Folder ${this.name} already exists but git won't be initialized there`, + ); + } else { + this.printError( + `Error generating new project: Folder ${this.name} already exists`, + ); + LambdaNewCommand.endProcess(1); + } + } else { + if (this.skipGitInit) { + this.printNeutral( + `Folder ${this.name} does not exist and git won't be initialized there`, + ); + } + } + + try { + this.checkFileExists(); + + printer.startStep('Generating AWS Lambda scaffolding'); + await this.schematicRunner.addLambdaQuickstart(this.name); + printer.endStep(); + + printer.startStep('Initializing Git repository'); + if (this.skipGitInit) { + printer.updateStep('[Skipped] Initializing Git repository'); + } else { + await this.gitRunner.init(this.name); + await this.gitRunner.createBranch({ folderName: this.name }); + } + printer.endStep(); + + printer.startStep('Adding additional packages'); + await this.npmRunner.addPackages(this.name, this.initialPackages); + printer.endStep(); + + printer.startStep('Adding additional npm scripts'); + await this.npmRunner.addScripts(this.name, this.initialScripts); + printer.endStep(); + + printer.startStep('Adding commitlint config file'); + await this.schematicRunner.addCommitlint(this.name); + printer.endStep(); + + printer.startStep('Adding .gitignore file'); + await this.schematicRunner.addGitignoreFile(this.name); + printer.endStep(); + + printer.startStep('Setting ESlint config'); + await this.schematicRunner.addESlint(this.name); + printer.endStep(); + + printer.startStep('Adding Pull Request template file'); + await this.schematicRunner.addPullRequestTemplate( + this.name, + this.gitProvider, + ); + printer.endStep(); + + printer.startStep('Installing dependencies'); + await this.npmRunner.install(this.name); + printer.endStep(); + + printer.startStep('Applying ESlist config'); + await this.npmRunner.runScript(this.name, 'lint:fix'); + printer.endStep(); + + printer.startStep('Creating husky files'); + await this.npmRunner.runScript(this.name, 'prepare'); + await this.bashRunnerHusky.addHuskyCommitMsg(this.name); + await this.bashRunnerHusky.addHuskyPrePush(this.name); + printer.endStep(); + + this.printSuccess( + `\n 🐦 Your CuckooJS Lambda "${this.name}" is generated and ready to use 🐦`, + ); + } catch (error: unknown) { + printer.load.fail( + `Error generating new project: ${(error as Error).message}`, + ); + this.removeFolder(); LambdaNewCommand.endProcess(1); - } - } - - private removeFolder() { - try { - fs.rmdirSync(join(process.cwd(), this.name), {recursive: true}); - } catch (e: unknown) { - // ignore - } - } - - private checkFileExists() { - const path = join(process.cwd(), this.name); - return fs.existsSync(path); - } + } + } + + private removeFolder() { + try { + fs.rmdirSync(join(process.cwd(), this.name), { recursive: true }); + } catch (e: unknown) { + // ignore + } + } + + private checkFileExists() { + const path = join(process.cwd(), this.name); + return fs.existsSync(path); + } } diff --git a/packages/@guidesmiths/cuckoojs-cli/src/commands/new.command.ts b/packages/@guidesmiths/cuckoojs-cli/src/commands/new.command.ts index c4f6590e..a6cfbcef 100644 --- a/packages/@guidesmiths/cuckoojs-cli/src/commands/new.command.ts +++ b/packages/@guidesmiths/cuckoojs-cli/src/commands/new.command.ts @@ -1,67 +1,71 @@ -import {SchematicRunner} from '../lib/runners/schematic.runner'; -import {GitRunner} from '../lib/runners/git.runner'; -import {messages} from '../lib/ui/ui'; +import { SchematicRunner } from '../lib/runners/schematic.runner'; +import { GitRunner } from '../lib/runners/git.runner'; +import { messages } from '../lib/ui/ui'; import * as fs from 'fs'; -import {join} from 'path'; -import {AbstractCommand} from './abstract.command'; -import {NestRunner} from '../lib/runners/nest.runner'; +import { join } from 'path'; +import { AbstractCommand } from './abstract.command'; +import { NestRunner } from '../lib/runners/nest.runner'; import Printer from '../lib/printer/printer'; -import {Prompter} from '../lib/utils/Prompter/Prompter'; -import {PackageManager} from '../lib/utils/PackageManager/PackageManager'; +import { Prompter } from '../lib/utils/Prompter/Prompter'; +import { PackageManager } from '../lib/utils/PackageManager/PackageManager'; export class NewCommand extends AbstractCommand { - private readonly schematicRunner: SchematicRunner = new SchematicRunner(); - private readonly gitRunner: GitRunner = new GitRunner(); - private readonly nestRunner: NestRunner = new NestRunner(); + private readonly schematicRunner: SchematicRunner = new SchematicRunner(); + private readonly gitRunner: GitRunner = new GitRunner(); + private readonly nestRunner: NestRunner = new NestRunner(); - constructor( - private readonly name: string, - ) { - super(); - } + constructor(private readonly name: string) { + super(); + } - public async execute() { + public async execute() { const printer = new Printer(); - this.printSuccess(messages.banner); + this.printSuccess(messages.banner); - if (this.checkFileExists()) { - this.printError(`Error generating new project: Folder ${this.name} already exists`); - NewCommand.endProcess(1); - } + if (this.checkFileExists()) { + this.printError( + `Error generating new project: Folder ${this.name} already exists`, + ); + NewCommand.endProcess(1); + } - try { + try { const packageManager = await Prompter.promptPackageManager(); - await this.nestRunner.generateNestApplication(this.name, packageManager); + await this.nestRunner.generateNestApplication(this.name, packageManager); - await this.gitRunner.createBranch({folderName: this.name}); + await this.gitRunner.createBranch({ folderName: this.name }); - await this.schematicRunner.addBasicTooling(this.name); + await this.schematicRunner.addBasicTooling(this.name); await this.schematicRunner.addNestJsConfigModule(this.name); printer.startStep('Installing dependencies'); - await new PackageManager(this.name).install(packageManager); + await new PackageManager(this.name).install(packageManager); printer.endStep(); - this.printSuccess(`\n🐦 Your CuckooJS Nest "${this.name}" project is generated and ready to use 🐦`); - } catch (error: unknown) { - printer.load.fail(`Error generating new project: ${(error as Error).message}`); - this.removeFolder(); - NewCommand.endProcess(1); - } - } + this.printSuccess( + `\n🐦 Your CuckooJS Nest "${this.name}" project is generated and ready to use 🐦`, + ); + } catch (error: unknown) { + printer.load.fail( + `Error generating new project: ${(error as Error).message}`, + ); + this.removeFolder(); + NewCommand.endProcess(1); + } + } - private removeFolder() { - try { - fs.rmdirSync(join(process.cwd(), this.name), {recursive: true}); - } catch (e: unknown) { - // ignore - } - } + private removeFolder() { + try { + fs.rmdirSync(join(process.cwd(), this.name), { recursive: true }); + } catch (e: unknown) { + // ignore + } + } - private checkFileExists() { - const path = join(process.cwd(), this.name); - return fs.existsSync(path); - } + private checkFileExists() { + const path = join(process.cwd(), this.name); + return fs.existsSync(path); + } } diff --git a/packages/@guidesmiths/cuckoojs-cli/src/lib/printer/printer.ts b/packages/@guidesmiths/cuckoojs-cli/src/lib/printer/printer.ts index 3b84b492..3a8919d1 100644 --- a/packages/@guidesmiths/cuckoojs-cli/src/lib/printer/printer.ts +++ b/packages/@guidesmiths/cuckoojs-cli/src/lib/printer/printer.ts @@ -1,9 +1,27 @@ /* eslint-disable @typescript-eslint/no-require-imports */ import loading = require('loading-cli'); -type FontColor = 'black' | 'red' | 'green' | 'yellow' | 'blue' | 'magenta' | 'cyan' | 'white' | 'none'; - -type BackgroundColor = 'black' | 'red' | 'green' | 'yellow' | 'blue' | 'magenta' | 'cyan' | 'white' | 'none'; +type FontColor = + | 'black' + | 'red' + | 'green' + | 'yellow' + | 'blue' + | 'magenta' + | 'cyan' + | 'white' + | 'none'; + +type BackgroundColor = + | 'black' + | 'red' + | 'green' + | 'yellow' + | 'blue' + | 'magenta' + | 'cyan' + | 'white' + | 'none'; type Alignment = 'left' | 'center'; @@ -13,89 +31,90 @@ const reset = '\u001b[0m'; const none = ''; const fontColorMap: Record = { - black: '\u001b[30m', - red: '\u001b[31m', - green: '\u001b[32m', - yellow: '\u001b[33m', - blue: '\u001b[34m', - magenta: '\u001b[35m', - cyan: '\u001b[35m', - white: '\u001b[37m', - none, + black: '\u001b[30m', + red: '\u001b[31m', + green: '\u001b[32m', + yellow: '\u001b[33m', + blue: '\u001b[34m', + magenta: '\u001b[35m', + cyan: '\u001b[35m', + white: '\u001b[37m', + none, }; const backgroundColorMap: Record = { - black: '\u001b[40m', - red: '\u001b[41m', - green: '\u001b[42m', - yellow: '\u001b[43m', - blue: '\u001b[44m', - magenta: '\u001b[45m', - cyan: '\u001b[46m', - white: '\u001b[47m', - none, + black: '\u001b[40m', + red: '\u001b[41m', + green: '\u001b[42m', + yellow: '\u001b[43m', + blue: '\u001b[44m', + magenta: '\u001b[45m', + cyan: '\u001b[46m', + white: '\u001b[47m', + none, }; const decorationMap: Record = { - bold: '\u001b[1m', - underline: '\u001b[4m', - reversed: '\u001b[7m', - none, + bold: '\u001b[1m', + underline: '\u001b[4m', + reversed: '\u001b[7m', + none, }; interface Style { - fontColor?: FontColor; - backgroundColor?: BackgroundColor; - alignment?: Alignment; - decoration?: Decoration; + fontColor?: FontColor; + backgroundColor?: BackgroundColor; + alignment?: Alignment; + decoration?: Decoration; } export default class Printer { - public static format({ - backgroundColor = 'none', - fontColor = 'none', - alignment = 'left', - decoration = 'none', - }: Style) { - const backgroundCode = backgroundColorMap[backgroundColor]; - const fontCode = fontColorMap[fontColor]; - const decorationCode = decorationMap[decoration]; - return function (text: string) { - const formattedText = `${backgroundCode}${fontCode}${decorationCode}${text}${reset}`; - let leftPaddingAmount = 0; - if (alignment === 'center') { - leftPaddingAmount = Printer.calculateLeftPadding(text); - } - - process.stdout.write(`${' '.repeat(leftPaddingAmount)}${formattedText}\n`); - }; - } - - private static calculateLeftPadding(text: string) { - const columns = process.stdout.columns || 80; - return Math.floor((columns - text.length) / 2); - } - - - load: loading.Loading; - constructor() { - this.load = loading({ + public static format({ + backgroundColor = 'none', + fontColor = 'none', + alignment = 'left', + decoration = 'none', + }: Style) { + const backgroundCode = backgroundColorMap[backgroundColor]; + const fontCode = fontColorMap[fontColor]; + const decorationCode = decorationMap[decoration]; + return function (text: string) { + const formattedText = `${backgroundCode}${fontCode}${decorationCode}${text}${reset}`; + let leftPaddingAmount = 0; + if (alignment === 'center') { + leftPaddingAmount = Printer.calculateLeftPadding(text); + } + + process.stdout.write( + `${' '.repeat(leftPaddingAmount)}${formattedText}\n`, + ); + }; + } + + private static calculateLeftPadding(text: string) { + const columns = process.stdout.columns || 80; + return Math.floor((columns - text.length) / 2); + } + + load: loading.Loading; + constructor() { + this.load = loading({ color: 'green', interval: 100, stream: process.stdout, frames: ['◐', 'ā—“', 'ā—‘', 'ā—’'], }); - } + } - public startStep(text: string): void { - this.load.text = text; - this.load.start(); - } + public startStep(text: string): void { + this.load.text = text; + this.load.start(); + } - public updateStep(text: string): void { - this.load.text = text; - } + public updateStep(text: string): void { + this.load.text = text; + } - public endStep(): void { - this.load.succeed(this.load.text); - } + public endStep(): void { + this.load.succeed(this.load.text); + } } diff --git a/packages/@guidesmiths/cuckoojs-cli/src/lib/runners/bash.runner.husky.ts b/packages/@guidesmiths/cuckoojs-cli/src/lib/runners/bash.runner.husky.ts index f3b8bb74..50a75e8a 100644 --- a/packages/@guidesmiths/cuckoojs-cli/src/lib/runners/bash.runner.husky.ts +++ b/packages/@guidesmiths/cuckoojs-cli/src/lib/runners/bash.runner.husky.ts @@ -1,27 +1,28 @@ - -import {GenericRunner} from './generic.runner'; -import {join} from 'path'; +import { GenericRunner } from './generic.runner'; +import { join } from 'path'; export class BashRunnerHusky extends GenericRunner { - private static getHuskyHookFile(name: string, hook: string): string { - return join(process.cwd(), name, '.husky', hook); - } + private static getHuskyHookFile(name: string, hook: string): string { + return join(process.cwd(), name, '.husky', hook); + } - constructor() { - super('npx'); - } + constructor() { + super('npx'); + } - public async addHuskyCommitMsg(folderName: string) { - const fullPath = BashRunnerHusky.getHuskyHookFile(folderName, 'commit-msg'); + public async addHuskyCommitMsg(folderName: string) { + const fullPath = BashRunnerHusky.getHuskyHookFile(folderName, 'commit-msg'); - const args = ['husky add ' + fullPath + ' \'npx --no -- commitlint --edit "$1"\'']; - await super.run({command: '', args}); - } + const args = [ + 'husky add ' + fullPath + ' \'npx --no -- commitlint --edit "$1"\'', + ]; + await super.run({ command: '', args }); + } - public async addHuskyPrePush(folderName: string) { - const fullPath = BashRunnerHusky.getHuskyHookFile(folderName, 'pre-push'); + public async addHuskyPrePush(folderName: string) { + const fullPath = BashRunnerHusky.getHuskyHookFile(folderName, 'pre-push'); - const args = ['husky add ' + fullPath + ' \'npm run test\'']; - await super.run({command: '', args}); - } + const args = ['husky add ' + fullPath + " 'npm run test'"]; + await super.run({ command: '', args }); + } } diff --git a/packages/@guidesmiths/cuckoojs-cli/src/lib/runners/generic.runner.ts b/packages/@guidesmiths/cuckoojs-cli/src/lib/runners/generic.runner.ts index 698b8c61..139e7178 100644 --- a/packages/@guidesmiths/cuckoojs-cli/src/lib/runners/generic.runner.ts +++ b/packages/@guidesmiths/cuckoojs-cli/src/lib/runners/generic.runner.ts @@ -1,8 +1,7 @@ -import spawnAsync, {RunObject} from '../utils/spawnAsync'; +import spawnAsync, { RunObject } from '../utils/spawnAsync'; export class GenericRunner { - constructor(protected binary: string) { - } + constructor(protected binary: string) {} protected run({ command, @@ -10,6 +9,11 @@ export class GenericRunner { cwd = process.cwd(), stdio = 'inherit', }: RunObject) { - return spawnAsync({command: this.binary, args: [command, ...args], stdio, cwd}); + return spawnAsync({ + command: this.binary, + args: [command, ...args], + stdio, + cwd, + }); } } diff --git a/packages/@guidesmiths/cuckoojs-cli/src/lib/runners/git.runner.ts b/packages/@guidesmiths/cuckoojs-cli/src/lib/runners/git.runner.ts index 807b4039..69294396 100644 --- a/packages/@guidesmiths/cuckoojs-cli/src/lib/runners/git.runner.ts +++ b/packages/@guidesmiths/cuckoojs-cli/src/lib/runners/git.runner.ts @@ -1,20 +1,27 @@ -import {GenericRunner} from './generic.runner'; +import { GenericRunner } from './generic.runner'; interface CreateBranchOptions { - initialBranch?: string; - folderName: string; + initialBranch?: string; + folderName: string; } export class GitRunner extends GenericRunner { - constructor() { - super('git'); - } + constructor() { + super('git'); + } - public async init(folderName: string) { - await super.run({command: 'init', args: [folderName]}); - } + public async init(folderName: string) { + await super.run({ command: 'init', args: [folderName] }); + } - public async createBranch({folderName, initialBranch = 'main'}: CreateBranchOptions) { - await super.run({command: `-C ${folderName} checkout`, args: ['-b', initialBranch], stdio: 'pipe'}); - } + public async createBranch({ + folderName, + initialBranch = 'main', + }: CreateBranchOptions) { + await super.run({ + command: `-C ${folderName} checkout`, + args: ['-b', initialBranch], + stdio: 'pipe', + }); + } } diff --git a/packages/@guidesmiths/cuckoojs-cli/src/lib/runners/nest.runner.ts b/packages/@guidesmiths/cuckoojs-cli/src/lib/runners/nest.runner.ts index 0beec937..f29a7964 100644 --- a/packages/@guidesmiths/cuckoojs-cli/src/lib/runners/nest.runner.ts +++ b/packages/@guidesmiths/cuckoojs-cli/src/lib/runners/nest.runner.ts @@ -1,28 +1,37 @@ -import {GenericRunner} from './generic.runner'; +import { GenericRunner } from './generic.runner'; export class NestRunner extends GenericRunner { private static getCliPath(): string { - return require.resolve( - '@nestjs/cli/bin/nest.js', - {paths: module.paths}, - ); + return require.resolve('@nestjs/cli/bin/nest.js', { paths: module.paths }); } constructor() { super('node'); } - public async generateNestApplication(name: string, packageManager: string): Promise { - const args = ['new', name, `--package-manager ${packageManager}`, '--skip-install']; + public async generateNestApplication( + name: string, + packageManager: string, + ): Promise { + const args = [ + 'new', + name, + `--package-manager ${packageManager}`, + '--skip-install', + ]; await this.runNestCli(args); } - public async generateNestElement(schematic: string, name: string, options: string[]) { + public async generateNestElement( + schematic: string, + name: string, + options: string[], + ) { const args = ['generate', schematic, name, ...options]; await this.runNestCli(args); } private async runNestCli(args: string[]) { - await super.run({command: NestRunner.getCliPath(), args}); + await super.run({ command: NestRunner.getCliPath(), args }); } } diff --git a/packages/@guidesmiths/cuckoojs-cli/src/lib/runners/npm.runner.ts b/packages/@guidesmiths/cuckoojs-cli/src/lib/runners/npm.runner.ts index 7ef4560f..c9d03c0f 100644 --- a/packages/@guidesmiths/cuckoojs-cli/src/lib/runners/npm.runner.ts +++ b/packages/@guidesmiths/cuckoojs-cli/src/lib/runners/npm.runner.ts @@ -1,17 +1,17 @@ -import {GenericRunner} from './generic.runner'; -import {join} from 'path'; -import {promises as fs} from 'fs'; +import { GenericRunner } from './generic.runner'; +import { join } from 'path'; +import { promises as fs } from 'fs'; import sortObjectKeys from '../utils/sortObjectByKeys'; export interface PackageEntry { - name: string; - version: string; - section: PackageDependencySection; + name: string; + version: string; + section: PackageDependencySection; } export interface ScriptEntry { - name: string; - value: string; + name: string; + value: string; } type PackageDependencySection = 'dependencies' | 'devDependencies'; @@ -21,56 +21,64 @@ type PackageSection = 'scripts' | PackageDependencySection; type PackageJson = Record>; export class NpmRunner extends GenericRunner { - private static ensurePackageSection(packageJson: PackageJson, section: PackageSection) { - if (!packageJson[section]) { - packageJson[section] = {}; - } - } - - private static buildPackageJsonPath(name: string) { - return join(process.cwd(), name, 'package.json'); - } - - private static async loadPackageJson(path: string) { - return JSON.parse(await fs.readFile(path, {encoding: 'utf-8'})) as PackageJson; - } - - constructor() { - super('npm'); - } - - public async install(name: string) { - const args = [`--prefix ${name}`]; - await super.run({command: 'install', args, stdio: 'pipe'}); - } - - public async runScript(name: string, script: string) { - const args = [`--prefix ${name} ${script}`]; - await super.run({command: 'run', args}); - } - - public async addPackages(name: string, packageEntries: PackageEntry[]) { - const packagePath = NpmRunner.buildPackageJsonPath(name); - const packageJson = await NpmRunner.loadPackageJson(packagePath); - - for (const packageEntry of packageEntries) { - NpmRunner.ensurePackageSection(packageJson, packageEntry.section); - packageJson[packageEntry.section][packageEntry.name] = packageEntry.version; - packageJson[packageEntry.section] = sortObjectKeys(packageJson[packageEntry.section]) as Record; - } - - await fs.writeFile(packagePath, JSON.stringify(packageJson, null, 2)); - } - - public async addScripts(name: string, scripts: ScriptEntry[]) { - const packagePath = NpmRunner.buildPackageJsonPath(name); - const packageJson = await NpmRunner.loadPackageJson(packagePath); - NpmRunner.ensurePackageSection(packageJson, 'scripts'); - - for (const script of scripts) { - packageJson.scripts[script.name] = script.value; - } - - await fs.writeFile(packagePath, JSON.stringify(packageJson, null, 2)); - } + private static ensurePackageSection( + packageJson: PackageJson, + section: PackageSection, + ) { + if (!packageJson[section]) { + packageJson[section] = {}; + } + } + + private static buildPackageJsonPath(name: string) { + return join(process.cwd(), name, 'package.json'); + } + + private static async loadPackageJson(path: string) { + return JSON.parse( + await fs.readFile(path, { encoding: 'utf-8' }), + ) as PackageJson; + } + + constructor() { + super('npm'); + } + + public async install(name: string) { + const args = [`--prefix ${name}`]; + await super.run({ command: 'install', args, stdio: 'pipe' }); + } + + public async runScript(name: string, script: string) { + const args = [`--prefix ${name} ${script}`]; + await super.run({ command: 'run', args }); + } + + public async addPackages(name: string, packageEntries: PackageEntry[]) { + const packagePath = NpmRunner.buildPackageJsonPath(name); + const packageJson = await NpmRunner.loadPackageJson(packagePath); + + for (const packageEntry of packageEntries) { + NpmRunner.ensurePackageSection(packageJson, packageEntry.section); + packageJson[packageEntry.section][packageEntry.name] = + packageEntry.version; + packageJson[packageEntry.section] = sortObjectKeys( + packageJson[packageEntry.section], + ) as Record; + } + + await fs.writeFile(packagePath, JSON.stringify(packageJson, null, 2)); + } + + public async addScripts(name: string, scripts: ScriptEntry[]) { + const packagePath = NpmRunner.buildPackageJsonPath(name); + const packageJson = await NpmRunner.loadPackageJson(packagePath); + NpmRunner.ensurePackageSection(packageJson, 'scripts'); + + for (const script of scripts) { + packageJson.scripts[script.name] = script.value; + } + + await fs.writeFile(packagePath, JSON.stringify(packageJson, null, 2)); + } } diff --git a/packages/@guidesmiths/cuckoojs-cli/src/lib/runners/schematic.runner.ts b/packages/@guidesmiths/cuckoojs-cli/src/lib/runners/schematic.runner.ts index a983eb5a..f3c9979c 100644 --- a/packages/@guidesmiths/cuckoojs-cli/src/lib/runners/schematic.runner.ts +++ b/packages/@guidesmiths/cuckoojs-cli/src/lib/runners/schematic.runner.ts @@ -1,49 +1,62 @@ -import {GenericRunner} from './generic.runner'; +import { GenericRunner } from './generic.runner'; export class SchematicRunner extends GenericRunner { - private static getSchematicsCliPath(): string { - return require.resolve( - '@angular-devkit/schematics-cli/bin/schematics.js', - {paths: module.paths}, - ); - } - - constructor() { - super('node'); - } - - public async addGitignoreFile(name: string) { - const args = [`@guidesmiths/cuckoojs-schematics:gitignore --directory=${name}`]; - await super.run({command: SchematicRunner.getSchematicsCliPath(), args}); - } - - public async addCommitlint(name: string) { - const args = [`@guidesmiths/cuckoojs-schematics:commitlint --directory=${name}`]; - await super.run({command: SchematicRunner.getSchematicsCliPath(), args}); - } - - public async addPullRequestTemplate(name: string, gitProvider: string) { - const args = [`@guidesmiths/cuckoojs-schematics:pr-template --directory=${name} --git-provider=${gitProvider}`]; - await super.run({command: SchematicRunner.getSchematicsCliPath(), args}); - } - - public async addLambdaQuickstart(name: string) { - const args = [`@guidesmiths/cuckoojs-schematics:lambda-quickstart --directory=${name} --service-name=${name}`]; - await super.run({command: SchematicRunner.getSchematicsCliPath(), args}); - } - - public async addESlint(name: string) { - const args = [`@guidesmiths/cuckoojs-schematics:eslint --directory=${name}`]; - await super.run({command: SchematicRunner.getSchematicsCliPath(), args}); - } + private static getSchematicsCliPath(): string { + return require.resolve('@angular-devkit/schematics-cli/bin/schematics.js', { + paths: module.paths, + }); + } + + constructor() { + super('node'); + } + + public async addGitignoreFile(name: string) { + const args = [ + `@guidesmiths/cuckoojs-schematics:gitignore --directory=${name}`, + ]; + await super.run({ command: SchematicRunner.getSchematicsCliPath(), args }); + } + + public async addCommitlint(name: string) { + const args = [ + `@guidesmiths/cuckoojs-schematics:commitlint --directory=${name}`, + ]; + await super.run({ command: SchematicRunner.getSchematicsCliPath(), args }); + } + + public async addPullRequestTemplate(name: string, gitProvider: string) { + const args = [ + `@guidesmiths/cuckoojs-schematics:pr-template --directory=${name} --git-provider=${gitProvider}`, + ]; + await super.run({ command: SchematicRunner.getSchematicsCliPath(), args }); + } + + public async addLambdaQuickstart(name: string) { + const args = [ + `@guidesmiths/cuckoojs-schematics:lambda-quickstart --directory=${name} --service-name=${name}`, + ]; + await super.run({ command: SchematicRunner.getSchematicsCliPath(), args }); + } + + public async addESlint(name: string) { + const args = [ + `@guidesmiths/cuckoojs-schematics:eslint --directory=${name}`, + ]; + await super.run({ command: SchematicRunner.getSchematicsCliPath(), args }); + } public async addBasicTooling(name: string) { - const args = [`@guidesmiths/cuckoojs-schematics:basic-tooling --directory=${name}`]; - await super.run({command: SchematicRunner.getSchematicsCliPath(), args}); + const args = [ + `@guidesmiths/cuckoojs-schematics:basic-tooling --directory=${name}`, + ]; + await super.run({ command: SchematicRunner.getSchematicsCliPath(), args }); } public async addNestJsConfigModule(name: string) { - const args = [`@guidesmiths/cuckoojs-schematics:nestjs-config --directory=${name}`]; - await super.run({command: SchematicRunner.getSchematicsCliPath(), args}); + const args = [ + `@guidesmiths/cuckoojs-schematics:nestjs-config --directory=${name}`, + ]; + await super.run({ command: SchematicRunner.getSchematicsCliPath(), args }); } } diff --git a/packages/@guidesmiths/cuckoojs-cli/src/lib/ui/ui.ts b/packages/@guidesmiths/cuckoojs-cli/src/lib/ui/ui.ts index dc32e477..09c4198d 100644 --- a/packages/@guidesmiths/cuckoojs-cli/src/lib/ui/ui.ts +++ b/packages/@guidesmiths/cuckoojs-cli/src/lib/ui/ui.ts @@ -1,7 +1,7 @@ -import {version} from '../../../package.json'; +import { version } from '../../../package.json'; export const messages: Record = { - banner: ` + banner: ` =########+. .*%- -*#. +%- ===:.%+ .-+++=: :#: :- :=+++- diff --git a/packages/@guidesmiths/cuckoojs-cli/src/lib/utils/PackageManager/PackageManager.ts b/packages/@guidesmiths/cuckoojs-cli/src/lib/utils/PackageManager/PackageManager.ts index 3923d2de..c09f2e56 100644 --- a/packages/@guidesmiths/cuckoojs-cli/src/lib/utils/PackageManager/PackageManager.ts +++ b/packages/@guidesmiths/cuckoojs-cli/src/lib/utils/PackageManager/PackageManager.ts @@ -1,6 +1,6 @@ -import {detect} from 'detect-package-manager'; -import {resolve} from 'path'; -import {existsSync} from 'fs'; +import { detect } from 'detect-package-manager'; +import { resolve } from 'path'; +import { existsSync } from 'fs'; import spawnAsync from '../spawnAsync'; export enum PackagerManagerEnum { @@ -15,20 +15,19 @@ const lockFiles: Record = { [PackagerManagerEnum.npm]: 'package-lock.json', [PackagerManagerEnum.yarn]: 'yarn.lock', [PackagerManagerEnum.pnpm]: 'pnpm-lock.yaml', -} +}; const initArgs: Record = { [PackagerManagerEnum.npm]: 'init --y --name=', [PackagerManagerEnum.yarn]: 'init --y --name ', [PackagerManagerEnum.pnpm]: 'init --y --name ', -} +}; const installArgs: Record = { [PackagerManagerEnum.npm]: 'install', [PackagerManagerEnum.yarn]: 'install', [PackagerManagerEnum.pnpm]: 'install', -} - +}; export class PackageManager { private readonly path: string; @@ -59,9 +58,9 @@ export class PackageManager { } public detect(): Promise { - return (detect({ + return detect({ cwd: this.path, includeGlobalBun: false, - }) as Promise); + }) as Promise; } } diff --git a/packages/@guidesmiths/cuckoojs-cli/src/lib/utils/Prompter/Prompter.ts b/packages/@guidesmiths/cuckoojs-cli/src/lib/utils/Prompter/Prompter.ts index a689ca9f..e893d1e3 100644 --- a/packages/@guidesmiths/cuckoojs-cli/src/lib/utils/Prompter/Prompter.ts +++ b/packages/@guidesmiths/cuckoojs-cli/src/lib/utils/Prompter/Prompter.ts @@ -1,19 +1,20 @@ -import {createPromptModule} from 'inquirer'; +import { createPromptModule } from 'inquirer'; type PackageManagerAnswer = 'npm' | 'yarn' | 'pnpm'; export class Prompter { public static async promptPackageManager() { - const packageManagerAnswer: { packageManager: PackageManagerAnswer } = await createPromptModule()({ - name: 'packageManager', - type: 'list', - message: 'Which package manager would you like to use?', - choices: [ - {name: 'npm', value: 'npm'}, - {name: 'yarn', value: 'yarn'}, - {name: 'pnpm', value: 'pnpm'}, - ], - }); + const packageManagerAnswer: { packageManager: PackageManagerAnswer } = + await createPromptModule()({ + name: 'packageManager', + type: 'list', + message: 'Which package manager would you like to use?', + choices: [ + { name: 'npm', value: 'npm' }, + { name: 'yarn', value: 'yarn' }, + { name: 'pnpm', value: 'pnpm' }, + ], + }); return packageManagerAnswer.packageManager; } } diff --git a/packages/@guidesmiths/cuckoojs-cli/src/lib/utils/sortObjectByKeys.ts b/packages/@guidesmiths/cuckoojs-cli/src/lib/utils/sortObjectByKeys.ts index 8428e70a..b792a493 100644 --- a/packages/@guidesmiths/cuckoojs-cli/src/lib/utils/sortObjectByKeys.ts +++ b/packages/@guidesmiths/cuckoojs-cli/src/lib/utils/sortObjectByKeys.ts @@ -2,8 +2,13 @@ interface NestedObject { [key: string]: NestedObject | number | string | boolean | null | undefined; } -export default function sortObjectKeys(o: NestedObject):NestedObject { - return (Object(o) !== o || Array.isArray(o) - ? o - : Object.keys(o).sort().reduce((a, k) => ({...a, [k]: sortObjectKeys(o[k] as NestedObject)}), {})); +export default function sortObjectKeys(o: NestedObject): NestedObject { + return Object(o) !== o || Array.isArray(o) + ? o + : Object.keys(o) + .sort() + .reduce( + (a, k) => ({ ...a, [k]: sortObjectKeys(o[k] as NestedObject) }), + {}, + ); } diff --git a/packages/@guidesmiths/cuckoojs-cli/src/lib/utils/spawnAsync.ts b/packages/@guidesmiths/cuckoojs-cli/src/lib/utils/spawnAsync.ts index c47150fe..fe1625af 100644 --- a/packages/@guidesmiths/cuckoojs-cli/src/lib/utils/spawnAsync.ts +++ b/packages/@guidesmiths/cuckoojs-cli/src/lib/utils/spawnAsync.ts @@ -1,18 +1,18 @@ -import {spawn, SpawnOptions, StdioOptions} from 'child_process'; +import { spawn, SpawnOptions, StdioOptions } from 'child_process'; export interface RunObject { command: string; - args: string []; + args: string[]; cwd?: string; stdio?: StdioOptions; } export default async function ({ - command, - args = [], - cwd = process.cwd(), - stdio = 'inherit', - }: RunObject): Promise { + command, + args = [], + cwd = process.cwd(), + stdio = 'inherit', +}: RunObject): Promise { const options: SpawnOptions = { cwd, stdio, @@ -20,23 +20,21 @@ export default async function ({ }; return new Promise((resolve, reject) => { - const child = spawn( - command, - args, - options, - ); + const child = spawn(command, args, options); - child.on('error', error => { + child.on('error', (error) => { reject(new Error(`Child process filed with error: ${error.message}`)); }); - child.on('close', code => { + child.on('close', (code) => { if (code === 0) { resolve(); return; } - reject(new Error(`Failed to execute command: ${command} ${args.join(' ')}`)); + reject( + new Error(`Failed to execute command: ${command} ${args.join(' ')}`), + ); }); }); } diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/basic-tooling/basic-tooling.factory.ts b/packages/@guidesmiths/cuckoojs-schematics/src/basic-tooling/basic-tooling.factory.ts index 86729afb..0e523b28 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/basic-tooling/basic-tooling.factory.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/basic-tooling/basic-tooling.factory.ts @@ -1,34 +1,34 @@ import { - chain, - type Rule, - type SchematicContext, - type Tree, + chain, + type Rule, + type SchematicContext, + type Tree, } from '@angular-devkit/schematics'; -import {schematic} from '@angular-devkit/schematics'; -import {normalize} from '@angular-devkit/core'; -import {execSync} from 'child_process'; -import {resolve} from 'path'; +import { schematic } from '@angular-devkit/schematics'; +import { normalize } from '@angular-devkit/core'; +import { execSync } from 'child_process'; +import { resolve } from 'path'; interface Options { directory: string; } export function main(options: Options): Rule { - return (tree: Tree, context: SchematicContext) => { - context.logger.info('Adding husky, commitlint, gitignore, nvmrc...'); + return (tree: Tree, context: SchematicContext) => { + context.logger.info('Adding husky, commitlint, gitignore, nvmrc...'); if (!tree.exists(normalize(`${options.directory}/package.json`))) { - context.logger.warn( - 'package.json file not found. Initializing package.json', - ); - execSync('npm init --y', {cwd: resolve(options.directory)}); - } + context.logger.warn( + 'package.json file not found. Initializing package.json', + ); + execSync('npm init --y', { cwd: resolve(options.directory) }); + } - return chain([ - schematic('husky', options), - schematic('commitlint', options), - schematic('gitignore', options), - schematic('nvmrc', options), - ]); - }; + return chain([ + schematic('husky', options), + schematic('commitlint', options), + schematic('gitignore', options), + schematic('nvmrc', options), + ]); + }; } diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/ci/ci.factory.spec.ts b/packages/@guidesmiths/cuckoojs-schematics/src/ci/ci.factory.spec.ts index 622c0bc4..21c2a9b9 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/ci/ci.factory.spec.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/ci/ci.factory.spec.ts @@ -5,24 +5,36 @@ import * as path from 'path'; const collectionPath = path.join(__dirname, '../collection.json'); describe('ci', () => { - it('works with github', async () => { - const runner = new SchematicTestRunner('schematics', collectionPath); - const tree = await runner - .runSchematicAsync('ci', {ciProvider: 'github', dockerRegistry: 'dockerRegistry', imageName: 'imageName'}, Tree.empty()) - .toPromise(); + it('works with github', async () => { + const runner = new SchematicTestRunner('schematics', collectionPath); + const tree = await runner + .runSchematicAsync( + 'ci', + { + ciProvider: 'github', + dockerRegistry: 'dockerRegistry', + imageName: 'imageName', + }, + Tree.empty(), + ) + .toPromise(); - expect(tree.files).toEqual([ - '/.github/workflows/ci-docker-build-push.yml', - ]); - }); - it('works with azuredevops', async () => { - const runner = new SchematicTestRunner('schematics', collectionPath); - const tree = await runner - .runSchematicAsync('ci', {ciProvider: 'azuredevops', dockerRegistry: 'dockerRegistry', imageName: 'imageName'}, Tree.empty()) - .toPromise(); + expect(tree.files).toEqual(['/.github/workflows/ci-docker-build-push.yml']); + }); + it('works with azuredevops', async () => { + const runner = new SchematicTestRunner('schematics', collectionPath); + const tree = await runner + .runSchematicAsync( + 'ci', + { + ciProvider: 'azuredevops', + dockerRegistry: 'dockerRegistry', + imageName: 'imageName', + }, + Tree.empty(), + ) + .toPromise(); - expect(tree.files).toEqual([ - '/azure-pipelines.yml', - ]); - }); + expect(tree.files).toEqual(['/azure-pipelines.yml']); + }); }); diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/ci/ci.factory.ts b/packages/@guidesmiths/cuckoojs-schematics/src/ci/ci.factory.ts index 7d34bde8..1fd4fe56 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/ci/ci.factory.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/ci/ci.factory.ts @@ -1,30 +1,30 @@ import { - apply, - MergeStrategy, - mergeWith, - type Rule, - type SchematicContext, - template, - type Tree, - url, + apply, + MergeStrategy, + mergeWith, + type Rule, + type SchematicContext, + template, + type Tree, + url, } from '@angular-devkit/schematics'; -import {resolve} from 'path'; +import { resolve } from 'path'; interface Options { - ciProvider: string; - dockerRegistry: string; - imageName: string; + ciProvider: string; + dockerRegistry: string; + imageName: string; } export function main(options: Options): Rule { - return (_tree: Tree, context: SchematicContext) => { - context.logger.info('Creating CI configuration...'); + return (_tree: Tree, context: SchematicContext) => { + context.logger.info('Creating CI configuration...'); - const templateSource = apply( - url(resolve('.', 'files', options.ciProvider)), - [template({...options})], - ); + const templateSource = apply( + url(resolve('.', 'files', options.ciProvider)), + [template({ ...options })], + ); - return mergeWith(templateSource, MergeStrategy.Overwrite); - }; + return mergeWith(templateSource, MergeStrategy.Overwrite); + }; } diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/commitlint/commitlint.factory.ts b/packages/@guidesmiths/cuckoojs-schematics/src/commitlint/commitlint.factory.ts index 12a8b425..744bd4ef 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/commitlint/commitlint.factory.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/commitlint/commitlint.factory.ts @@ -1,47 +1,45 @@ -import type { - Rule, - SchematicContext, - Tree} from '@angular-devkit/schematics'; +import type { Rule, SchematicContext, Tree } from '@angular-devkit/schematics'; import { - apply, - chain, - MergeStrategy, - mergeWith, - move, - template, - url, + apply, + chain, + MergeStrategy, + mergeWith, + move, + template, + url, } from '@angular-devkit/schematics'; -import {normalize} from '@angular-devkit/core'; -import {PackageJsonUtils} from '../utils/package-json.utils'; +import { normalize } from '@angular-devkit/core'; +import { PackageJsonUtils } from '../utils/package-json.utils'; interface Options { - directory: string; + directory: string; } export function main(options: Options): Rule { - return (_tree: Tree, context: SchematicContext) => { - context.logger.info('Adding commitlint ...'); - const path = normalize(options.directory); - const templateSource = apply(url(normalize('./files')), [ - template({}), - move(path), - ]); + return (_tree: Tree, context: SchematicContext) => { + context.logger.info('Adding commitlint ...'); + const path = normalize(options.directory); + const templateSource = apply(url(normalize('./files')), [ + template({}), + move(path), + ]); - const merged = mergeWith(templateSource, MergeStrategy.Overwrite); + const merged = mergeWith(templateSource, MergeStrategy.Overwrite); - return chain([ - merged, - updatePackageJson(path), - ]); - }; + return chain([merged, updatePackageJson(path)]); + }; } function updatePackageJson(directory: string): Rule { - return (tree: Tree) => { - const path = normalize(`${directory}/package.json`); - const packageJsonUtils = new PackageJsonUtils(tree, path); - packageJsonUtils.addPackage('@commitlint/cli', '^17.1.2', true); - packageJsonUtils.addPackage('@commitlint/config-conventional', '^17.1.0', true); - return tree; - }; + return (tree: Tree) => { + const path = normalize(`${directory}/package.json`); + const packageJsonUtils = new PackageJsonUtils(tree, path); + packageJsonUtils.addPackage('@commitlint/cli', '^17.1.2', true); + packageJsonUtils.addPackage( + '@commitlint/config-conventional', + '^17.1.0', + true, + ); + return tree; + }; } diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/dockerfile/dockerfile.factory.spec.ts b/packages/@guidesmiths/cuckoojs-schematics/src/dockerfile/dockerfile.factory.spec.ts index 109bec1c..c8b1ebf8 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/dockerfile/dockerfile.factory.spec.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/dockerfile/dockerfile.factory.spec.ts @@ -5,26 +5,28 @@ import * as path from 'path'; const collectionPath = path.join(__dirname, '../collection.json'); describe('dockerignore', () => { - it('works with node basic build', async () => { - const runner = new SchematicTestRunner('schematics', collectionPath); - const tree = await runner - .runSchematicAsync('dockerfile', {directory: '.', buildType: 'basic', nodeVersion: 18}, Tree.empty()) - .toPromise(); + it('works with node basic build', async () => { + const runner = new SchematicTestRunner('schematics', collectionPath); + const tree = await runner + .runSchematicAsync( + 'dockerfile', + { directory: '.', buildType: 'basic', nodeVersion: 18 }, + Tree.empty(), + ) + .toPromise(); - expect(tree.files).toEqual([ - '/Dockerfile', - '/.dockerignore' - ]); - }); - it('works with nestjs build', async () => { - const runner = new SchematicTestRunner('schematics', collectionPath); - const tree = await runner - .runSchematicAsync('dockerfile', {directory: '.', buildType: 'nestjs', nodeVersion: 18}, Tree.empty()) - .toPromise(); + expect(tree.files).toEqual(['/Dockerfile', '/.dockerignore']); + }); + it('works with nestjs build', async () => { + const runner = new SchematicTestRunner('schematics', collectionPath); + const tree = await runner + .runSchematicAsync( + 'dockerfile', + { directory: '.', buildType: 'nestjs', nodeVersion: 18 }, + Tree.empty(), + ) + .toPromise(); - expect(tree.files).toEqual([ - '/Dockerfile', - '/.dockerignore' - ]); - }); + expect(tree.files).toEqual(['/Dockerfile', '/.dockerignore']); + }); }); diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/dockerfile/dockerfile.factory.ts b/packages/@guidesmiths/cuckoojs-schematics/src/dockerfile/dockerfile.factory.ts index 1e6115e1..06cd78fb 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/dockerfile/dockerfile.factory.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/dockerfile/dockerfile.factory.ts @@ -1,54 +1,58 @@ -import type { - Rule, - SchematicContext, - Tree} from '@angular-devkit/schematics'; +import type { Rule, SchematicContext, Tree } from '@angular-devkit/schematics'; import { - apply, chain, - MergeStrategy, - mergeWith, - template, - url, + apply, + chain, + MergeStrategy, + mergeWith, + template, + url, } from '@angular-devkit/schematics'; -import {normalize} from '@angular-devkit/core'; -import {resolve} from 'path'; +import { normalize } from '@angular-devkit/core'; +import { resolve } from 'path'; interface Options { - directory: string; - buildType: string; - nodeVersion: string; + directory: string; + buildType: string; + nodeVersion: string; } export function main(options: Options): Rule { - return (_tree: Tree, context: SchematicContext) => { - context.logger.info('Creating Dockerfile...'); + return (_tree: Tree, context: SchematicContext) => { + context.logger.info('Creating Dockerfile...'); - const templateSourceDockerfile = apply( - url(resolve('.', 'files', options.buildType)), - [template({...options})], - ); - const mergedDockerfile = mergeWith(templateSourceDockerfile, MergeStrategy.Overwrite); + const templateSourceDockerfile = apply( + url(resolve('.', 'files', options.buildType)), + [template({ ...options })], + ); + const mergedDockerfile = mergeWith( + templateSourceDockerfile, + MergeStrategy.Overwrite, + ); - const templateSourceDockerignore = apply( - url(resolve('.', 'files', 'common')), - [template({...options})], - ); - const mergedDockerignore = mergeWith(templateSourceDockerignore, MergeStrategy.Overwrite); + const templateSourceDockerignore = apply( + url(resolve('.', 'files', 'common')), + [template({ ...options })], + ); + const mergedDockerignore = mergeWith( + templateSourceDockerignore, + MergeStrategy.Overwrite, + ); - return chain([ - mergedDockerfile, - mergedDockerignore, - renameDockerignore(options), - ]); - }; + return chain([ + mergedDockerfile, + mergedDockerignore, + renameDockerignore(options), + ]); + }; } function renameDockerignore(options: Options): Rule { - return (tree: Tree) => { - const normalizedPath = normalize(options.directory); - tree.rename( - resolve(normalizedPath, 'dockerignore'), - resolve(normalizedPath, '.dockerignore'), - ); - return tree; - }; + return (tree: Tree) => { + const normalizedPath = normalize(options.directory); + tree.rename( + resolve(normalizedPath, 'dockerignore'), + resolve(normalizedPath, '.dockerignore'), + ); + return tree; + }; } diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/eslint/eslint.factory.spec.ts b/packages/@guidesmiths/cuckoojs-schematics/src/eslint/eslint.factory.spec.ts index 3e6db990..77cf6763 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/eslint/eslint.factory.spec.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/eslint/eslint.factory.spec.ts @@ -1,34 +1,32 @@ -import {Tree} from '@angular-devkit/schematics'; -import {SchematicTestRunner} from '@angular-devkit/schematics/testing'; +import { Tree } from '@angular-devkit/schematics'; +import { SchematicTestRunner } from '@angular-devkit/schematics/testing'; import * as path from 'path'; const collectionPath = path.join(__dirname, '../collection.json'); describe('eslint', () => { - it('works', async () => { - const runner = new SchematicTestRunner('schematics', collectionPath); - const folder = Tree.empty(); - folder.create('package.json',Buffer.from('{}')); - const tree = await runner - .runSchematicAsync('eslint', {directory: '.'}, folder) - .toPromise(); + it('works', async () => { + const runner = new SchematicTestRunner('schematics', collectionPath); + const folder = Tree.empty(); + folder.create('package.json', Buffer.from('{}')); + const tree = await runner + .runSchematicAsync('eslint', { directory: '.' }, folder) + .toPromise(); + expect(tree.files).toEqual(['/package.json', '/.eslintrc.js']); - expect(tree.files).toEqual([ - '/package.json', - "/.eslintrc.js" - ]); - - const actualPackageJson = JSON.parse(tree.readContent('./package.json')) as Record; - expect(actualPackageJson.devDependencies).toEqual({ - "eslint": "^8.29.0", - "eslint-config-airbnb-base": "^15.0.0", - "eslint-plugin-import": "^2.26.0", - "eslint-plugin-jest": "^27.1.6" - }) - expect(actualPackageJson.scripts).toEqual({ - "lint": "eslint .", - "lint:fix": "eslint . --fix", - }) + const actualPackageJson = JSON.parse( + tree.readContent('./package.json'), + ) as Record; + expect(actualPackageJson.devDependencies).toEqual({ + eslint: '^8.29.0', + 'eslint-config-airbnb-base': '^15.0.0', + 'eslint-plugin-import': '^2.26.0', + 'eslint-plugin-jest': '^27.1.6', + }); + expect(actualPackageJson.scripts).toEqual({ + lint: 'eslint .', + 'lint:fix': 'eslint . --fix', }); + }); }); diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/eslint/eslint.factory.ts b/packages/@guidesmiths/cuckoojs-schematics/src/eslint/eslint.factory.ts index 25454f8b..03f220d8 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/eslint/eslint.factory.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/eslint/eslint.factory.ts @@ -1,66 +1,62 @@ -import type { - Rule, - SchematicContext, - Tree} from '@angular-devkit/schematics'; +import type { Rule, SchematicContext, Tree } from '@angular-devkit/schematics'; import { - apply, chain, - MergeStrategy, - mergeWith, move, - template, - url, + apply, + chain, + MergeStrategy, + mergeWith, + move, + template, + url, } from '@angular-devkit/schematics'; -import {normalize} from '@angular-devkit/core'; -import {PackageJsonUtils} from '../utils/package-json.utils'; -import {resolve} from 'path'; +import { normalize } from '@angular-devkit/core'; +import { PackageJsonUtils } from '../utils/package-json.utils'; +import { resolve } from 'path'; interface Options { - directory: string; + directory: string; } export function main(options: Options): Rule { - return (_tree: Tree, context: SchematicContext) => { - context.logger.info('Setting up ESlint config...'); - const path = normalize(options.directory); + return (_tree: Tree, context: SchematicContext) => { + context.logger.info('Setting up ESlint config...'); + const path = normalize(options.directory); - const templateSource = apply(url(resolve('.', 'files')), [ - template({...options}), - move(path), - renameFile(options), - ]); + const templateSource = apply(url(resolve('.', 'files')), [ + template({ ...options }), + move(path), + renameFile(options), + ]); - const merged = mergeWith(templateSource, MergeStrategy.Overwrite); + const merged = mergeWith(templateSource, MergeStrategy.Overwrite); - return chain([ - merged, - updatePackageJson(path), - ]); - }; + return chain([merged, updatePackageJson(path)]); + }; } function renameFile(options: Options): Rule { - return (tree: Tree) => { - const normalizedPath = normalize(options.directory); - tree.rename( - resolve(normalizedPath, 'eslintrc.js'), - resolve(normalizedPath, '.eslintrc.js'), - ); - return tree; - }; + return (tree: Tree) => { + const normalizedPath = normalize(options.directory); + tree.rename( + resolve(normalizedPath, 'eslintrc.js'), + resolve(normalizedPath, '.eslintrc.js'), + ); + return tree; + }; } function updatePackageJson(directory: string): Rule { - return (tree: Tree) => { - const path = `${directory}/package.json`; - const packageJsonUtils = new PackageJsonUtils(tree, path); + return (tree: Tree) => { + const path = `${directory}/package.json`; + const packageJsonUtils = new PackageJsonUtils(tree, path); - packageJsonUtils.addPackage('eslint', '^8.29.0', true); - packageJsonUtils.addPackage('eslint-config-airbnb-base', '^15.0.0', true); - packageJsonUtils.addPackage('eslint-plugin-import', '^2.26.0', true); - packageJsonUtils.addPackage('eslint-plugin-jest', '^27.1.6', true); + packageJsonUtils.addPackage('eslint', '^8.29.0', true); + packageJsonUtils.addPackage('eslint-config-airbnb-base', '^15.0.0', true); + packageJsonUtils.addPackage('eslint-plugin-import', '^2.26.0', true); + packageJsonUtils.addPackage('eslint-plugin-jest', '^27.1.6', true); - packageJsonUtils.addScript('lint', 'eslint .'); - packageJsonUtils.addScript('lint:fix', 'eslint . --fix'); + packageJsonUtils.addScript('lint', 'eslint .'); + packageJsonUtils.addScript('lint:fix', 'eslint . --fix'); - return tree; - }; + return tree; + }; } diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/gitignore/gitignore.factory.spec.ts b/packages/@guidesmiths/cuckoojs-schematics/src/gitignore/gitignore.factory.spec.ts index 8231609d..836c265e 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/gitignore/gitignore.factory.spec.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/gitignore/gitignore.factory.spec.ts @@ -1,18 +1,16 @@ -import {Tree} from '@angular-devkit/schematics'; -import {SchematicTestRunner} from '@angular-devkit/schematics/testing'; +import { Tree } from '@angular-devkit/schematics'; +import { SchematicTestRunner } from '@angular-devkit/schematics/testing'; import * as path from 'path'; const collectionPath = path.join(__dirname, '../collection.json'); describe('gitignore', () => { - it('works', async () => { - const runner = new SchematicTestRunner('schematics', collectionPath); - const tree = await runner - .runSchematicAsync('gitignore', {directory: '.'}, Tree.empty()) + it('works', async () => { + const runner = new SchematicTestRunner('schematics', collectionPath); + const tree = await runner + .runSchematicAsync('gitignore', { directory: '.' }, Tree.empty()) .toPromise(); - expect(tree.files).toEqual([ - '/.gitignore' - ]); - }); + expect(tree.files).toEqual(['/.gitignore']); + }); }); diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/gitignore/gitignore.factory.ts b/packages/@guidesmiths/cuckoojs-schematics/src/gitignore/gitignore.factory.ts index d36508f8..8b8714f3 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/gitignore/gitignore.factory.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/gitignore/gitignore.factory.ts @@ -1,41 +1,38 @@ -import type { - Rule, - SchematicContext, - Tree} from '@angular-devkit/schematics'; +import type { Rule, SchematicContext, Tree } from '@angular-devkit/schematics'; import { - apply, - MergeStrategy, - mergeWith, - move, - template, - url, + apply, + MergeStrategy, + mergeWith, + move, + template, + url, } from '@angular-devkit/schematics'; -import {normalize} from '@angular-devkit/core'; +import { normalize } from '@angular-devkit/core'; interface Options { - directory: string; + directory: string; } export function main(options: Options): Rule { - return (_tree: Tree, context: SchematicContext) => { - context.logger.info('Creating .gitignore file...'); + return (_tree: Tree, context: SchematicContext) => { + context.logger.info('Creating .gitignore file...'); - const templateSource = apply(url(normalize('./files')), [ - template({}), - move(normalize(options.directory)), - renameFile(options), - ]); + const templateSource = apply(url(normalize('./files')), [ + template({}), + move(normalize(options.directory)), + renameFile(options), + ]); - return mergeWith(templateSource, MergeStrategy.Overwrite); - }; + return mergeWith(templateSource, MergeStrategy.Overwrite); + }; } function renameFile(options: Options): Rule { - return (tree: Tree) => { - tree.rename( + return (tree: Tree) => { + tree.rename( normalize(`${options.directory}/gitignore`), normalize(`${options.directory}/.gitignore`), - ); - return tree; - }; + ); + return tree; + }; } diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/helm/helm-strategies/helm.strategy.factory.ts b/packages/@guidesmiths/cuckoojs-schematics/src/helm/helm-strategies/helm.strategy.factory.ts index f8e725fc..05eecab9 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/helm/helm-strategies/helm.strategy.factory.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/helm/helm-strategies/helm.strategy.factory.ts @@ -1,5 +1,5 @@ -import {type HelmStrategy} from './helm.strategy'; +import { type HelmStrategy } from './helm.strategy'; export abstract class HelmStrategyFactory { - protected abstract create(type: string): T; + protected abstract create(type: string): T; } diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/helm/helm-strategies/helm.strategy.ts b/packages/@guidesmiths/cuckoojs-schematics/src/helm/helm-strategies/helm.strategy.ts index 6d35ff5b..b202a78e 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/helm/helm-strategies/helm.strategy.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/helm/helm-strategies/helm.strategy.ts @@ -1,17 +1,23 @@ -import {type Rule} from '@angular-devkit/schematics'; -import {apply, url, template, mergeWith, MergeStrategy} from '@angular-devkit/schematics'; -import {join} from 'path'; +import { type Rule } from '@angular-devkit/schematics'; +import { + apply, + url, + template, + mergeWith, + MergeStrategy, +} from '@angular-devkit/schematics'; +import { join } from 'path'; export abstract class HelmStrategy { - templatePath: string[] = [__dirname, '..', 'files']; + templatePath: string[] = [__dirname, '..', 'files']; - addResources = (options: Record): Rule => { - const filePath = join(...this.templatePath); - return mergeWith( - apply(url(filePath), [template({...options})]), - MergeStrategy.Overwrite, - ); - }; + addResources = (options: Record): Rule => { + const filePath = join(...this.templatePath); + return mergeWith( + apply(url(filePath), [template({ ...options })]), + MergeStrategy.Overwrite, + ); + }; - abstract enrichOptions(options: Record): Record; + abstract enrichOptions(options: Record): Record; } diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/helm/helm-strategies/ingress-controller/generic.Ingress.strategy.ts b/packages/@guidesmiths/cuckoojs-schematics/src/helm/helm-strategies/ingress-controller/generic.Ingress.strategy.ts index 453418b6..76b345c7 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/helm/helm-strategies/ingress-controller/generic.Ingress.strategy.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/helm/helm-strategies/ingress-controller/generic.Ingress.strategy.ts @@ -1,9 +1,9 @@ -import {IngressStrategy} from './ingress.strategy'; +import { IngressStrategy } from './ingress.strategy'; import { IngressTypes } from './ingressTypes.enum'; export class GenericIngressControllerStrategy extends IngressStrategy { - constructor() { - super(); - this.templatePath.push(IngressTypes.GENERIC); - } + constructor() { + super(); + this.templatePath.push(IngressTypes.GENERIC); + } } diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/helm/helm-strategies/ingress-controller/ingress.strategy.ts b/packages/@guidesmiths/cuckoojs-schematics/src/helm/helm-strategies/ingress-controller/ingress.strategy.ts index 78718e05..81a8eb00 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/helm/helm-strategies/ingress-controller/ingress.strategy.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/helm/helm-strategies/ingress-controller/ingress.strategy.ts @@ -1,13 +1,12 @@ -import {HelmStrategy} from '../helm.strategy'; +import { HelmStrategy } from '../helm.strategy'; export class IngressStrategy extends HelmStrategy { - constructor() { - super(); - this.templatePath.push('ingress'); - } + constructor() { + super(); + this.templatePath.push('ingress'); + } - enrichOptions(options: any): any { - return options; - } + enrichOptions(options: any): any { + return options; + } } - diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/helm/helm-strategies/tls-cert/tlsCert.strategy.ts b/packages/@guidesmiths/cuckoojs-schematics/src/helm/helm-strategies/tls-cert/tlsCert.strategy.ts index 9425ab15..1525741d 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/helm/helm-strategies/tls-cert/tlsCert.strategy.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/helm/helm-strategies/tls-cert/tlsCert.strategy.ts @@ -1,15 +1,15 @@ -import {HelmStrategy} from '../helm.strategy'; +import { HelmStrategy } from '../helm.strategy'; export class TlsCertStrategy extends HelmStrategy { - protected constructor(readonly isTlsEnabled: boolean) { - super(); - this.templatePath.push('dns-certs'); - } + protected constructor(readonly isTlsEnabled: boolean) { + super(); + this.templatePath.push('dns-certs'); + } - enrichOptions(options: any): any { - return { - ...options, - isTlsEnabled: this.isTlsEnabled, - }; - } + enrichOptions(options: any): any { + return { + ...options, + isTlsEnabled: this.isTlsEnabled, + }; + } } diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/helm/helm.factory.spec.ts b/packages/@guidesmiths/cuckoojs-schematics/src/helm/helm.factory.spec.ts index 87876d92..fe061061 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/helm/helm.factory.spec.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/helm/helm.factory.spec.ts @@ -1,6 +1,6 @@ -import { Tree } from "@angular-devkit/schematics"; -import { SchematicTestRunner } from "@angular-devkit/schematics/testing"; -import * as path from "path"; +import { Tree } from '@angular-devkit/schematics'; +import { SchematicTestRunner } from '@angular-devkit/schematics/testing'; +import * as path from 'path'; import { getBasicValues, getBasicIngress, @@ -9,9 +9,9 @@ import { getBasicValuesTls, getTraefikIngressTls, getBasicIngressTls, -} from "./__fixtures__"; +} from './__fixtures__'; -const collectionPath = path.join(__dirname, "../collection.json"); +const collectionPath = path.join(__dirname, '../collection.json'); const cases = [ { @@ -125,35 +125,35 @@ const cases = [ expectedIngress: getTraefikIngressTls(), }, ]; -describe("helm", () => { +describe('helm', () => { test.each(cases)( - "works for helm with $ingressType ingress controller and $tlsCertType", + 'works for helm with $ingressType ingress controller and $tlsCertType', async ({ schemaOptions, expectedFiles, expectedValues, expectedIngress, }) => { - const runner = new SchematicTestRunner("schematics", collectionPath); + const runner = new SchematicTestRunner('schematics', collectionPath); const folder = Tree.empty(); - folder.create("package.json", Buffer.from("{}")); + folder.create('package.json', Buffer.from('{}')); const tree = await runner .runSchematicAsync('helm', schemaOptions, folder) .toPromise(); expect(tree.files).toEqual(expectedFiles); - const packageJson = JSON.parse(tree.readContent("./package.json")); + const packageJson = JSON.parse(tree.readContent('./package.json')); expect(packageJson.scripts).toEqual({ - "helm:upgrade": - "helm upgrade -f ./.helm/values.yml serviceName ./.helm", + 'helm:upgrade': + 'helm upgrade -f ./.helm/values.yml serviceName ./.helm', }); - const helmValues = tree.readContent("/.helm/values.yaml"); + const helmValues = tree.readContent('/.helm/values.yaml'); expect(helmValues).toEqual(expectedValues); - const ingress = tree.readContent("/.helm/templates/ingress.yaml"); + const ingress = tree.readContent('/.helm/templates/ingress.yaml'); expect(ingress).toEqual(expectedIngress); - } + }, ); }); diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/helm/rule-builder/rule.builder.ts b/packages/@guidesmiths/cuckoojs-schematics/src/helm/rule-builder/rule.builder.ts index 33959316..7c0d5645 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/helm/rule-builder/rule.builder.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/helm/rule-builder/rule.builder.ts @@ -1,78 +1,95 @@ import { - apply, - MergeStrategy, - mergeWith, - type Rule, - SchematicsException, - template, - type Tree, - url, - chain, + apply, + MergeStrategy, + mergeWith, + type Rule, + SchematicsException, + template, + type Tree, + url, + chain, } from '@angular-devkit/schematics'; -import {join} from 'path'; -import {type LoggerApi} from '@angular-devkit/core/src/logger'; -import {type IngressStrategy} from '../helm-strategies/ingress-controller/ingress.strategy'; -import {type TlsCertStrategy} from '../helm-strategies/tls-cert/tlsCert.strategy'; -import {type HelmStrategy} from '../helm-strategies/helm.strategy'; +import { join } from 'path'; +import { type LoggerApi } from '@angular-devkit/core/src/logger'; +import { type IngressStrategy } from '../helm-strategies/ingress-controller/ingress.strategy'; +import { type TlsCertStrategy } from '../helm-strategies/tls-cert/tlsCert.strategy'; +import { type HelmStrategy } from '../helm-strategies/helm.strategy'; type PackageJson = { - scripts?: Record; + scripts?: Record; }; export class RuleBuilder { - constructor( - private readonly ingressStrategy: IngressStrategy, - private readonly tlsCertStrategy: TlsCertStrategy, - private readonly logger: LoggerApi) {} + constructor( + private readonly ingressStrategy: IngressStrategy, + private readonly tlsCertStrategy: TlsCertStrategy, + private readonly logger: LoggerApi, + ) {} - updatePackageJson = (packageJsonBuffer: Buffer, serviceName: string, tree: Tree) => { - const packageJsonString = packageJsonBuffer.toString(); - const packageJsonObject: PackageJson = JSON.parse(packageJsonString) as PackageJson; + updatePackageJson = ( + packageJsonBuffer: Buffer, + serviceName: string, + tree: Tree, + ) => { + const packageJsonString = packageJsonBuffer.toString(); + const packageJsonObject: PackageJson = JSON.parse( + packageJsonString, + ) as PackageJson; - if (packageJsonObject.scripts?.['helm:upgrade']) { - this.logger.warn('helm:upgrade script already exists in package.json. Skipping owerwritting it.'); - return; - } + if (packageJsonObject.scripts?.['helm:upgrade']) { + this.logger.warn( + 'helm:upgrade script already exists in package.json. Skipping owerwritting it.', + ); + return; + } - packageJsonObject.scripts = { - ...packageJsonObject.scripts, - // eslint-disable-next-line @typescript-eslint/naming-convention - 'helm:upgrade': `helm upgrade -f ./.helm/values.yml ${serviceName} ./.helm`, - }; + packageJsonObject.scripts = { + ...packageJsonObject.scripts, + // eslint-disable-next-line @typescript-eslint/naming-convention + 'helm:upgrade': `helm upgrade -f ./.helm/values.yml ${serviceName} ./.helm`, + }; - tree.overwrite('./package.json', JSON.stringify(packageJsonObject, null, 2)); - }; + tree.overwrite( + './package.json', + JSON.stringify(packageJsonObject, null, 2), + ); + }; - addBaseHelmChartToTemplate = (options: any) => { - const filePath = join(__dirname, '..', 'files', 'base'); - return mergeWith( - apply(url(filePath), [template({...options})]), - MergeStrategy.Overwrite, - ); - }; + addBaseHelmChartToTemplate = (options: any) => { + const filePath = join(__dirname, '..', 'files', 'base'); + return mergeWith( + apply(url(filePath), [template({ ...options })]), + MergeStrategy.Overwrite, + ); + }; - build = (options: Record, tree: Tree): Rule => { - const packageJsonBuffer = tree.read('./package.json'); - const serviceName = options?.serviceName as string | undefined; - if (!packageJsonBuffer) { - throw new SchematicsException('Could not read package.json file'); - } + build = (options: Record, tree: Tree): Rule => { + const packageJsonBuffer = tree.read('./package.json'); + const serviceName = options?.serviceName as string | undefined; + if (!packageJsonBuffer) { + throw new SchematicsException('Could not read package.json file'); + } - if (!serviceName) { - throw new SchematicsException('No service name specified'); - } + if (!serviceName) { + throw new SchematicsException('No service name specified'); + } - this.updatePackageJson(packageJsonBuffer, serviceName, tree); + this.updatePackageJson(packageJsonBuffer, serviceName, tree); - const helmStrategyStack: HelmStrategy[] = [this.tlsCertStrategy, this.ingressStrategy]; - const enrichedOptions = helmStrategyStack.reduce( - (acc, strategy) => strategy.enrichOptions(acc), - options, - ); + const helmStrategyStack: HelmStrategy[] = [ + this.tlsCertStrategy, + this.ingressStrategy, + ]; + const enrichedOptions = helmStrategyStack.reduce( + (acc, strategy) => strategy.enrichOptions(acc), + options, + ); - return chain([ - this.addBaseHelmChartToTemplate(enrichedOptions), - ...helmStrategyStack.map(strategy => strategy.addResources(enrichedOptions)), - ]); - }; + return chain([ + this.addBaseHelmChartToTemplate(enrichedOptions), + ...helmStrategyStack.map((strategy) => + strategy.addResources(enrichedOptions), + ), + ]); + }; } diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/husky/husky.factory.ts b/packages/@guidesmiths/cuckoojs-schematics/src/husky/husky.factory.ts index 37b383f9..2039d00d 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/husky/husky.factory.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/husky/husky.factory.ts @@ -1,60 +1,67 @@ import { - chain, - type Rule, - type SchematicContext, - type Tree, + chain, + type Rule, + type SchematicContext, + type Tree, } from '@angular-devkit/schematics'; -import {normalize} from '@angular-devkit/core'; -import {execSync} from 'child_process'; +import { normalize } from '@angular-devkit/core'; +import { execSync } from 'child_process'; -import {PackageJsonUtils} from '../utils/package-json.utils'; +import { PackageJsonUtils } from '../utils/package-json.utils'; interface Options { - directory: string; - skipInstall: boolean; + directory: string; + skipInstall: boolean; } export function main(options: Options): Rule { - return function (tree: Tree, context: SchematicContext) { - context.logger.info('Adding husky...'); - - if (!tree.exists(normalize(`${options.directory}/.git/HEAD`))) { - context.logger.info( - 'Git directory not found. Husky installation will not proceed. Please, consider initializing Git on this project', - ); - return; - } - - return chain([ - updatePackageJson(options.directory), - runCommand(options.directory, options.skipInstall), - ]); - }; + return function (tree: Tree, context: SchematicContext) { + context.logger.info('Adding husky...'); + + if (!tree.exists(normalize(`${options.directory}/.git/HEAD`))) { + context.logger.info( + 'Git directory not found. Husky installation will not proceed. Please, consider initializing Git on this project', + ); + return; + } + + return chain([ + updatePackageJson(options.directory), + runCommand(options.directory, options.skipInstall), + ]); + }; } function runCommand(directory: string, skipInstall: boolean): Rule { - return function(tree: Tree, context: SchematicContext) { - if (skipInstall) { - context.logger.info( - 'Husky schematic executed with skipInstall option. Husky will not be installed.', - ); - return tree; - } + return function (tree: Tree, context: SchematicContext) { + if (skipInstall) { + context.logger.info( + 'Husky schematic executed with skipInstall option. Husky will not be installed.', + ); + return tree; + } const cwd = normalize(directory); - execSync('npx husky install', { cwd }); - execSync(`npx husky add ${normalize(`.husky/commit-msg`)} 'npx --no -- commitlint --edit "$1"'`, { cwd }); - execSync(`npx husky add ${normalize(`.husky/pre-push`)} 'npm run test'`, { cwd }); - return tree; - }; + execSync('npx husky install', { cwd }); + execSync( + `npx husky add ${normalize( + `.husky/commit-msg`, + )} 'npx --no -- commitlint --edit "$1"'`, + { cwd }, + ); + execSync(`npx husky add ${normalize(`.husky/pre-push`)} 'npm run test'`, { + cwd, + }); + return tree; + }; } function updatePackageJson(directory: string): Rule { - return function(tree: Tree) { - const path = normalize(`${directory}/package.json`); - const packageJsonUtils = new PackageJsonUtils(tree, path); - packageJsonUtils.addPackage('husky', '^8.0.3', true); - packageJsonUtils.addScript('prepare', 'husky install'); - return tree; - }; + return function (tree: Tree) { + const path = normalize(`${directory}/package.json`); + const packageJsonUtils = new PackageJsonUtils(tree, path); + packageJsonUtils.addPackage('husky', '^8.0.3', true); + packageJsonUtils.addScript('prepare', 'husky install'); + return tree; + }; } diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/lambda-quickstart/lambda-quickstart.factory.spec.ts b/packages/@guidesmiths/cuckoojs-schematics/src/lambda-quickstart/lambda-quickstart.factory.spec.ts index 3ebb2308..26bfaf0f 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/lambda-quickstart/lambda-quickstart.factory.spec.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/lambda-quickstart/lambda-quickstart.factory.spec.ts @@ -1,37 +1,40 @@ -import {Tree} from '@angular-devkit/schematics'; -import {SchematicTestRunner} from '@angular-devkit/schematics/testing'; +import { Tree } from '@angular-devkit/schematics'; +import { SchematicTestRunner } from '@angular-devkit/schematics/testing'; import * as path from 'path'; const collectionPath = path.join(__dirname, '../collection.json'); describe('lambda-quickstart', () => { - it('works', async () => { - const runner = new SchematicTestRunner('schematics', collectionPath); - const tree = await runner - .runSchematicAsync('lambda-quickstart', {directory: 'some-folder', serviceName: 'anyName'}, Tree.empty()) - .toPromise(); + it('works', async () => { + const runner = new SchematicTestRunner('schematics', collectionPath); + const tree = await runner + .runSchematicAsync( + 'lambda-quickstart', + { directory: 'some-folder', serviceName: 'anyName' }, + Tree.empty(), + ) + .toPromise(); - - expect(tree.files).toEqual([ - "/some-folder/README.md", - "/some-folder/jest.config.js", - "/some-folder/package.json", - "/some-folder/serverless.yml", - "/some-folder/.nvmrc", - "/some-folder/.env.sample", - "/some-folder/docker/docker-compose.yml", - "/some-folder/docker/localstack/custom-config.sh", - "/some-folder/fixtures/hello/regularRequest.json", - "/some-folder/src/components/container.js", - "/some-folder/src/components/config/config.js", - "/some-folder/src/components/controllers/helloController.js", - "/some-folder/src/components/controllers/tests/helloController.test.js", - "/some-folder/src/components/controllers/tests/mocks/logger.js", - "/some-folder/src/components/logger/logger.js", - "/some-folder/src/handlers/hello.js", - "/some-folder/src/handlers/schemas/helloInput.js", - "/some-folder/src/handlers/utils/extractPayload.js", - "/some-folder/src/handlers/utils/httpResponse.js" - ]); - }); + expect(tree.files).toEqual([ + '/some-folder/README.md', + '/some-folder/jest.config.js', + '/some-folder/package.json', + '/some-folder/serverless.yml', + '/some-folder/.nvmrc', + '/some-folder/.env.sample', + '/some-folder/docker/docker-compose.yml', + '/some-folder/docker/localstack/custom-config.sh', + '/some-folder/fixtures/hello/regularRequest.json', + '/some-folder/src/components/container.js', + '/some-folder/src/components/config/config.js', + '/some-folder/src/components/controllers/helloController.js', + '/some-folder/src/components/controllers/tests/helloController.test.js', + '/some-folder/src/components/controllers/tests/mocks/logger.js', + '/some-folder/src/components/logger/logger.js', + '/some-folder/src/handlers/hello.js', + '/some-folder/src/handlers/schemas/helloInput.js', + '/some-folder/src/handlers/utils/extractPayload.js', + '/some-folder/src/handlers/utils/httpResponse.js', + ]); + }); }); diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/lambda-quickstart/lambda-quickstart.factory.ts b/packages/@guidesmiths/cuckoojs-schematics/src/lambda-quickstart/lambda-quickstart.factory.ts index e7bcd2bd..fb1d76a8 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/lambda-quickstart/lambda-quickstart.factory.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/lambda-quickstart/lambda-quickstart.factory.ts @@ -1,47 +1,45 @@ -import type { - Rule, - SchematicContext, - Tree} from '@angular-devkit/schematics'; +import type { Rule, SchematicContext, Tree } from '@angular-devkit/schematics'; import { - apply, - MergeStrategy, - mergeWith, move, - template, - url, + apply, + MergeStrategy, + mergeWith, + move, + template, + url, } from '@angular-devkit/schematics'; -import {normalize} from '@angular-devkit/core'; -import {resolve} from 'path'; +import { normalize } from '@angular-devkit/core'; +import { resolve } from 'path'; interface Options { - directory: string; - serviceName: string; + directory: string; + serviceName: string; } export function main(options: Options): Rule { - return (_tree: Tree, context: SchematicContext) => { - context.logger.info('Creating Lambda Quickstart...'); + return (_tree: Tree, context: SchematicContext) => { + context.logger.info('Creating Lambda Quickstart...'); - const templateSource = apply(url(resolve('.', 'files')), [ - template({...options}), - move(normalize(options.directory)), - renameFile(options), - ]); + const templateSource = apply(url(resolve('.', 'files')), [ + template({ ...options }), + move(normalize(options.directory)), + renameFile(options), + ]); - return mergeWith(templateSource, MergeStrategy.Overwrite); - }; + return mergeWith(templateSource, MergeStrategy.Overwrite); + }; } function renameFile(options: Options): Rule { - return (tree: Tree) => { - const normalizedPath = normalize(options.directory); - tree.rename( - resolve(normalizedPath, 'nvmrc'), - resolve(normalizedPath, '.nvmrc'), - ); - tree.rename( - resolve(normalizedPath, 'env.sample'), - resolve(normalizedPath, '.env.sample'), - ); - return tree; - }; + return (tree: Tree) => { + const normalizedPath = normalize(options.directory); + tree.rename( + resolve(normalizedPath, 'nvmrc'), + resolve(normalizedPath, '.nvmrc'), + ); + tree.rename( + resolve(normalizedPath, 'env.sample'), + resolve(normalizedPath, '.env.sample'), + ); + return tree; + }; } diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/nestjs-config/nestjs-config.factory.spec.ts b/packages/@guidesmiths/cuckoojs-schematics/src/nestjs-config/nestjs-config.factory.spec.ts index 7ec24c12..7cf3cd71 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/nestjs-config/nestjs-config.factory.spec.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/nestjs-config/nestjs-config.factory.spec.ts @@ -5,14 +5,12 @@ import * as path from 'path'; const collectionPath = path.join(__dirname, '../collection.json'); describe('nestjs-config', () => { - it('works', async () => { - const runner = new SchematicTestRunner('schematics', collectionPath); - const tree = await runner - .runSchematicAsync('nestjs-config', {directory: '.'}, Tree.empty()) - .toPromise(); + it('works', async () => { + const runner = new SchematicTestRunner('schematics', collectionPath); + const tree = await runner + .runSchematicAsync('nestjs-config', { directory: '.' }, Tree.empty()) + .toPromise(); - expect(tree.files).toEqual([ - '/src/config/config.ts', - ]); - }); + expect(tree.files).toEqual(['/src/config/config.ts']); + }); }); diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/nestjs-config/nestjs-config.factory.ts b/packages/@guidesmiths/cuckoojs-schematics/src/nestjs-config/nestjs-config.factory.ts index e790e304..583a6059 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/nestjs-config/nestjs-config.factory.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/nestjs-config/nestjs-config.factory.ts @@ -1,18 +1,16 @@ -import type { - Rule, - SchematicContext, - Tree} from '@angular-devkit/schematics'; +import type { Rule, SchematicContext, Tree } from '@angular-devkit/schematics'; import { - apply, - MergeStrategy, - mergeWith, move, - template, - chain, - url, + apply, + MergeStrategy, + mergeWith, + move, + template, + chain, + url, } from '@angular-devkit/schematics'; -import {normalize} from '@angular-devkit/core'; -import {addConfigToModuleRule} from './utils/add-config-to-module-rule'; -import {PackageJsonUtils} from '../utils/package-json.utils'; +import { normalize } from '@angular-devkit/core'; +import { addConfigToModuleRule } from './utils/add-config-to-module-rule'; +import { PackageJsonUtils } from '../utils/package-json.utils'; interface Options { directory: string; @@ -23,7 +21,10 @@ export function main(options: Options): Rule { context.logger.info('Creating Nest basic config files...'); const appFile = `${options.directory}/src/app.module.ts`; - if (!tree.exists(normalize(`${options.directory}/nest-cli.json`)) || !tree.exists(normalize(appFile))) { + if ( + !tree.exists(normalize(`${options.directory}/nest-cli.json`)) || + !tree.exists(normalize(appFile)) + ) { context.logger.info( 'This is not a NestJs project. Schematic will not create the config files in this folder.', ); @@ -31,7 +32,7 @@ export function main(options: Options): Rule { } const templateSource = apply(url('./files'), [ - template({...options}), + template({ ...options }), move(normalize(options.directory)), ]); @@ -54,5 +55,3 @@ function updatePackageJson(directory: string): Rule { return tree; }; } - - diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/nestjs-config/utils/add-config-to-module-change.ts b/packages/@guidesmiths/cuckoojs-schematics/src/nestjs-config/utils/add-config-to-module-change.ts index 699e4aac..fafc9836 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/nestjs-config/utils/add-config-to-module-change.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/nestjs-config/utils/add-config-to-module-change.ts @@ -1,8 +1,7 @@ - import * as ts from 'typescript'; -import {getSourceNodes, findNode, findNodes} from '../../utils/ast-utils'; -import {InsertChange} from '@schematics/angular/utility/change'; -import {SchematicsException} from '@angular-devkit/schematics'; +import { getSourceNodes, findNode, findNodes } from '../../utils/ast-utils'; +import { InsertChange } from '@schematics/angular/utility/change'; +import { SchematicsException } from '@angular-devkit/schematics'; // eslint-disable-next-line @typescript-eslint/naming-convention const IMPORT_DECLARATION = ` @@ -13,70 +12,93 @@ const IMPORT_DECLARATION = ` }),`; function getModuleDecoratorNode(nodes: ts.Node[]) { - const decoratorNodes = nodes.filter(n => n.kind === ts.SyntaxKind.Decorator); - const moduleDecoratorNodes: ts.Node[] = decoratorNodes?.filter(n => findNode(n, ts.SyntaxKind.Identifier, 'Module')); - - if (moduleDecoratorNodes.length === 0) { - throw new SchematicsException('No Module decorators found'); - } - - if (moduleDecoratorNodes.length > 1) { - throw new SchematicsException('More than one Module decorator found'); - } - - return moduleDecoratorNodes[0] as ts.Decorator; + const decoratorNodes = nodes.filter( + (n) => n.kind === ts.SyntaxKind.Decorator, + ); + const moduleDecoratorNodes: ts.Node[] = decoratorNodes?.filter((n) => + findNode(n, ts.SyntaxKind.Identifier, 'Module'), + ); + + if (moduleDecoratorNodes.length === 0) { + throw new SchematicsException('No Module decorators found'); + } + + if (moduleDecoratorNodes.length > 1) { + throw new SchematicsException('More than one Module decorator found'); + } + + return moduleDecoratorNodes[0] as ts.Decorator; } function getDecoratorArgument(node: ts.Decorator) { - const objectLiteralExpressionNodes = findNodes(node, ts.SyntaxKind.ObjectLiteralExpression) || []; - if (objectLiteralExpressionNodes.length !== 1) { - throw new SchematicsException('Invalid Module decorator arguments'); - } + const objectLiteralExpressionNodes = + findNodes(node, ts.SyntaxKind.ObjectLiteralExpression) || []; + if (objectLiteralExpressionNodes.length !== 1) { + throw new SchematicsException('Invalid Module decorator arguments'); + } - return objectLiteralExpressionNodes[0] as unknown as ts.ObjectLiteralExpression; + return objectLiteralExpressionNodes[0] as unknown as ts.ObjectLiteralExpression; } function isImportIdentifier(node: ts.Node) { - return node.kind === ts.SyntaxKind.Identifier && node.getText() === 'imports'; + return node.kind === ts.SyntaxKind.Identifier && node.getText() === 'imports'; } function getImportsNode(nodes: ts.NodeArray) { - return nodes.find(n => n.getChildren().find(isImportIdentifier)) as ts.PropertyAssignment; + return nodes.find((n) => + n.getChildren().find(isImportIdentifier), + ) as ts.PropertyAssignment; } function createAddToImportsChange(path: string, node: ts.PropertyAssignment) { - const arrayLiteralNode = node.getChildren().find(n => n.kind === ts.SyntaxKind.ArrayLiteralExpression); - const importsListNode = arrayLiteralNode?.getChildren().find(n => n.kind === ts.SyntaxKind.SyntaxList); - - if (!importsListNode) { - throw new SchematicsException('No imports list found'); - } - - return new InsertChange(path, importsListNode.getEnd() ?? 0, IMPORT_DECLARATION); + const arrayLiteralNode = node + .getChildren() + .find((n) => n.kind === ts.SyntaxKind.ArrayLiteralExpression); + const importsListNode = arrayLiteralNode + ?.getChildren() + .find((n) => n.kind === ts.SyntaxKind.SyntaxList); + + if (!importsListNode) { + throw new SchematicsException('No imports list found'); + } + + return new InsertChange( + path, + importsListNode.getEnd() ?? 0, + IMPORT_DECLARATION, + ); } function createImportsChange(path: string, node: ts.Node) { - const importToInsert = ` + const importToInsert = ` imports: [${IMPORT_DECLARATION} ],`; - const insertPosition = findNodes(node, ts.SyntaxKind.OpenBraceToken)[0].end; - return new InsertChange(path, insertPosition, importToInsert); + const insertPosition = findNodes(node, ts.SyntaxKind.OpenBraceToken)[0].end; + return new InsertChange(path, insertPosition, importToInsert); } -export function addConfigToModuleChange(sourceText: string, path: string): InsertChange { - const sourceFile = ts.createSourceFile(path, sourceText, ts.ScriptTarget.Latest, true); - const nodes = getSourceNodes(sourceFile); - - const moduleDecoratorNode = getModuleDecoratorNode(nodes); - const decoratorArgument = getDecoratorArgument(moduleDecoratorNode); - const importsPropertyNode = getImportsNode(decoratorArgument.properties); - - let importChange; - if (importsPropertyNode) { - importChange = createAddToImportsChange(path, importsPropertyNode); - } else { - importChange = createImportsChange(path, decoratorArgument); - } - - return importChange; +export function addConfigToModuleChange( + sourceText: string, + path: string, +): InsertChange { + const sourceFile = ts.createSourceFile( + path, + sourceText, + ts.ScriptTarget.Latest, + true, + ); + const nodes = getSourceNodes(sourceFile); + + const moduleDecoratorNode = getModuleDecoratorNode(nodes); + const decoratorArgument = getDecoratorArgument(moduleDecoratorNode); + const importsPropertyNode = getImportsNode(decoratorArgument.properties); + + let importChange; + if (importsPropertyNode) { + importChange = createAddToImportsChange(path, importsPropertyNode); + } else { + importChange = createImportsChange(path, decoratorArgument); + } + + return importChange; } diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/nestjs-config/utils/add-config-to-module-rule.ts b/packages/@guidesmiths/cuckoojs-schematics/src/nestjs-config/utils/add-config-to-module-rule.ts index 1b3e1ff9..bc6e2871 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/nestjs-config/utils/add-config-to-module-rule.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/nestjs-config/utils/add-config-to-module-rule.ts @@ -1,29 +1,33 @@ -import {type Rule, SchematicsException, type Tree} from '@angular-devkit/schematics'; -import {InsertChange} from '../../utils/change'; -import {addConfigToModuleChange} from './add-config-to-module-change'; -import {addImportsToFileChange} from './add-imports-to-file-change'; +import { + type Rule, + SchematicsException, + type Tree, +} from '@angular-devkit/schematics'; +import { InsertChange } from '../../utils/change'; +import { addConfigToModuleChange } from './add-config-to-module-change'; +import { addImportsToFileChange } from './add-imports-to-file-change'; export function addConfigToModuleRule(path: string): Rule { - return (tree: Tree) => { - const sourceText = tree.readText(path); - if (!sourceText) { - throw new SchematicsException('File does not exist.'); - } + return (tree: Tree) => { + const sourceText = tree.readText(path); + if (!sourceText) { + throw new SchematicsException('File does not exist.'); + } - const importsChanges = addImportsToFileChange(sourceText, path); - const moduleChange = addConfigToModuleChange(sourceText, path); + const importsChanges = addImportsToFileChange(sourceText, path); + const moduleChange = addConfigToModuleChange(sourceText, path); - const declarationRecorder = tree.beginUpdate(path); + const declarationRecorder = tree.beginUpdate(path); - for (const change of importsChanges) { - if (change instanceof InsertChange) { - declarationRecorder.insertLeft(change.pos, change.toAdd); - } - } + for (const change of importsChanges) { + if (change instanceof InsertChange) { + declarationRecorder.insertLeft(change.pos, change.toAdd); + } + } - declarationRecorder.insertLeft(moduleChange.pos, moduleChange.toAdd); - tree.commitUpdate(declarationRecorder); + declarationRecorder.insertLeft(moduleChange.pos, moduleChange.toAdd); + tree.commitUpdate(declarationRecorder); - return tree; - }; + return tree; + }; } diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/nestjs-config/utils/add-imports-to-file-change.ts b/packages/@guidesmiths/cuckoojs-schematics/src/nestjs-config/utils/add-imports-to-file-change.ts index 2455cd60..988bce18 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/nestjs-config/utils/add-imports-to-file-change.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/nestjs-config/utils/add-imports-to-file-change.ts @@ -1,15 +1,25 @@ - import * as ts from 'typescript'; -import {insertImport} from '../../utils/ast-utils'; +import { insertImport } from '../../utils/ast-utils'; export function addImportsToFileChange(sourceText: string, path: string) { - const sourceFile = ts.createSourceFile(path, sourceText, ts.ScriptTarget.Latest, true); + const sourceFile = ts.createSourceFile( + path, + sourceText, + ts.ScriptTarget.Latest, + true, + ); - const changesArr = []; + const changesArr = []; - changesArr.push(insertImport(sourceFile, path, 'ConfigModule', '@nestjs/config')); - changesArr.push(insertImport(sourceFile, path, 'config', './config/config', true)); - changesArr.push(insertImport(sourceFile, path, 'validate', './config/env-validation', true)); + changesArr.push( + insertImport(sourceFile, path, 'ConfigModule', '@nestjs/config'), + ); + changesArr.push( + insertImport(sourceFile, path, 'config', './config/config', true), + ); + changesArr.push( + insertImport(sourceFile, path, 'validate', './config/env-validation', true), + ); - return changesArr; + return changesArr; } diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/nvmrc/nvmrc.factory.ts b/packages/@guidesmiths/cuckoojs-schematics/src/nvmrc/nvmrc.factory.ts index 80555b8a..a7b66df3 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/nvmrc/nvmrc.factory.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/nvmrc/nvmrc.factory.ts @@ -1,46 +1,47 @@ -import type { - Rule, - SchematicContext, - Tree} from '@angular-devkit/schematics'; +import type { Rule, SchematicContext, Tree } from '@angular-devkit/schematics'; import { - apply, - MergeStrategy, - mergeWith, move, - template, - url, - chain, + apply, + MergeStrategy, + mergeWith, + move, + template, + url, + chain, } from '@angular-devkit/schematics'; -import {normalize} from '@angular-devkit/core'; -import {PackageJsonUtils} from '../utils/package-json.utils'; +import { normalize } from '@angular-devkit/core'; +import { PackageJsonUtils } from '../utils/package-json.utils'; interface Options { - directory: string; - nodeVersion: number; + directory: string; + nodeVersion: number; } export function main(options: Options): Rule { - return (_tree: Tree, context: SchematicContext): Rule => { - context.logger.info('Creating .nvmrc file and updating package.json...'); + return (_tree: Tree, context: SchematicContext): Rule => { + context.logger.info('Creating .nvmrc file and updating package.json...'); - const templateSource = apply(url(normalize('./files')), [ - template({...options}), - move(normalize(options.directory)), - ]); + const templateSource = apply(url(normalize('./files')), [ + template({ ...options }), + move(normalize(options.directory)), + ]); - return chain([ - mergeWith(templateSource, MergeStrategy.Overwrite), - updatePackageJson(options), - ]); - }; + return chain([ + mergeWith(templateSource, MergeStrategy.Overwrite), + updatePackageJson(options), + ]); + }; } function updatePackageJson(options: Options): Rule { - return (tree: Tree) => { - const path = normalize(`${options.directory}/package.json`); + return (tree: Tree) => { + const path = normalize(`${options.directory}/package.json`); - const packageJsonUtils = new PackageJsonUtils(tree, path); - packageJsonUtils.addWithPath(['engines', 'node'], `>=${options.nodeVersion}`); + const packageJsonUtils = new PackageJsonUtils(tree, path); + packageJsonUtils.addWithPath( + ['engines', 'node'], + `>=${options.nodeVersion}`, + ); - return tree; - }; + return tree; + }; } diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/pr-template/pr-template.factory.spec.ts b/packages/@guidesmiths/cuckoojs-schematics/src/pr-template/pr-template.factory.spec.ts index 6e908d17..3ce58e16 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/pr-template/pr-template.factory.spec.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/pr-template/pr-template.factory.spec.ts @@ -5,24 +5,30 @@ import * as path from 'path'; const collectionPath = path.join(__dirname, '../collection.json'); describe('pr-template', () => { - it('works with github', async () => { - const runner = new SchematicTestRunner('schematics', collectionPath); - const tree = await runner - .runSchematicAsync('pr-template', {directory: 'somewhere', gitProvider: 'github'}, Tree.empty()) - .toPromise(); + it('works with github', async () => { + const runner = new SchematicTestRunner('schematics', collectionPath); + const tree = await runner + .runSchematicAsync( + 'pr-template', + { directory: 'somewhere', gitProvider: 'github' }, + Tree.empty(), + ) + .toPromise(); - expect(tree.files).toEqual([ - '/somewhere/.github/pull_request_template.md', - ]); - }); - it('works with azuredevops', async () => { - const runner = new SchematicTestRunner('schematics', collectionPath); - const tree = await runner - .runSchematicAsync('pr-template', {directory: 'somewhere', gitProvider: 'azuredevops'}, Tree.empty()) - .toPromise(); + expect(tree.files).toEqual(['/somewhere/.github/pull_request_template.md']); + }); + it('works with azuredevops', async () => { + const runner = new SchematicTestRunner('schematics', collectionPath); + const tree = await runner + .runSchematicAsync( + 'pr-template', + { directory: 'somewhere', gitProvider: 'azuredevops' }, + Tree.empty(), + ) + .toPromise(); - expect(tree.files).toEqual([ - '/somewhere/.azuredevops/pull_request_template.md', - ]); - }); + expect(tree.files).toEqual([ + '/somewhere/.azuredevops/pull_request_template.md', + ]); + }); }); diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/pr-template/pr-template.factory.ts b/packages/@guidesmiths/cuckoojs-schematics/src/pr-template/pr-template.factory.ts index a08f20ab..713c2ebd 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/pr-template/pr-template.factory.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/pr-template/pr-template.factory.ts @@ -1,31 +1,29 @@ -import type { - Rule, - SchematicContext, - Tree} from '@angular-devkit/schematics'; +import type { Rule, SchematicContext, Tree } from '@angular-devkit/schematics'; import { - apply, - MergeStrategy, - mergeWith, move, - template, - url, + apply, + MergeStrategy, + mergeWith, + move, + template, + url, } from '@angular-devkit/schematics'; -import {normalize} from '@angular-devkit/core'; -import {resolve} from 'path'; +import { normalize } from '@angular-devkit/core'; +import { resolve } from 'path'; interface Options { - directory: string; - gitProvider: string; + directory: string; + gitProvider: string; } export function main(options: Options): Rule { - return (_tree: Tree, context: SchematicContext) => { - context.logger.info('Creating Pull Request Template...'); + return (_tree: Tree, context: SchematicContext) => { + context.logger.info('Creating Pull Request Template...'); - const templateSource = apply(url(resolve('.', 'files')), [ - template({...options}), - move(normalize(options.directory)), - ]); + const templateSource = apply(url(resolve('.', 'files')), [ + template({ ...options }), + move(normalize(options.directory)), + ]); - return mergeWith(templateSource, MergeStrategy.Overwrite); - }; + return mergeWith(templateSource, MergeStrategy.Overwrite); + }; } diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/utils/ast-utils.ts b/packages/@guidesmiths/cuckoojs-schematics/src/utils/ast-utils.ts index dd590d1a..1858f593 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/utils/ast-utils.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/utils/ast-utils.ts @@ -1,8 +1,8 @@ /* -* Copy-paste from https://github.com/angular/angular-cli/blob/main/packages/schematics/angular/utility/change.ts -* with some eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing annotations -* following suggestions from this issue: https://github.com/angular/angular-cli/issues/19885#issuecomment-768272337 -* */ + * Copy-paste from https://github.com/angular/angular-cli/blob/main/packages/schematics/angular/utility/change.ts + * with some eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing annotations + * following suggestions from this issue: https://github.com/angular/angular-cli/issues/19885#issuecomment-768272337 + * */ /** * @license @@ -39,12 +39,17 @@ export function insertImport( // get nodes that map to import statements from the file fileName const relevantImports = allImports.filter((node) => { - return ts.isStringLiteralLike(node.moduleSpecifier) && node.moduleSpecifier.text === fileName; + return ( + ts.isStringLiteralLike(node.moduleSpecifier) && + node.moduleSpecifier.text === fileName + ); }); if (relevantImports.length > 0) { const hasNamespaceImport = relevantImports.some((node) => { - return node.importClause?.namedBindings?.kind === ts.SyntaxKind.NamespaceImport; + return ( + node.importClause?.namedBindings?.kind === ts.SyntaxKind.NamespaceImport + ); }); // if imports * from fileName, don't add symbolName @@ -53,26 +58,41 @@ export function insertImport( } const imports = relevantImports.flatMap((node) => { - return node.importClause?.namedBindings && ts.isNamedImports(node.importClause.namedBindings) + return node.importClause?.namedBindings && + ts.isNamedImports(node.importClause.namedBindings) ? node.importClause.namedBindings.elements : []; }); // insert import if it's not there // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - if (!imports.some((node) => (node.propertyName || node.name).text === symbolName)) { + if ( + !imports.some( + (node) => (node.propertyName || node.name).text === symbolName, + ) + ) { const fallbackPos = - findNodes(relevantImports[0], ts.SyntaxKind.CloseBraceToken)[0].getStart() || + findNodes( + relevantImports[0], + ts.SyntaxKind.CloseBraceToken, + )[0].getStart() || findNodes(relevantImports[0], ts.SyntaxKind.FromKeyword)[0].getStart(); - return insertAfterLastOccurrence(imports, `, ${importExpression}`, fileToEdit, fallbackPos); + return insertAfterLastOccurrence( + imports, + `, ${importExpression}`, + fileToEdit, + fallbackPos, + ); } return new NoopChange(); } // no such import declaration exists - const useStrict = findNodes(rootNode, ts.isStringLiteral).filter((n) => n.text === 'use strict'); + const useStrict = findNodes(rootNode, ts.isStringLiteral).filter( + (n) => n.text === 'use strict', + ); let fallbackPos = 0; if (useStrict.length > 0) { fallbackPos = useStrict[0].end; @@ -188,7 +208,11 @@ export function getSourceNodes(sourceFile: ts.SourceFile): ts.Node[] { return result; } -export function findNode(node: ts.Node, kind: ts.SyntaxKind, text: string): ts.Node | null { +export function findNode( + node: ts.Node, + kind: ts.SyntaxKind, + text: string, +): ts.Node | null { if (node.kind === kind && node.getText() === text) { return node; } @@ -240,14 +264,18 @@ export function insertAfterLastOccurrence( lastItem = findNodes(lastItem, syntaxKind).sort(nodesByPosition).pop(); } if (!lastItem && fallbackPos == undefined) { - throw new Error(`tried to insert ${toInsert} as first occurence with no fallback position`); + throw new Error( + `tried to insert ${toInsert} as first occurence with no fallback position`, + ); } const lastItemPosition: number = lastItem ? lastItem.getEnd() : fallbackPos; return new InsertChange(file, lastItemPosition, toInsert); } -function _angularImportsFromNode(node: ts.ImportDeclaration): Record { +function _angularImportsFromNode( + node: ts.ImportDeclaration, +): Record { const ms = node.moduleSpecifier; let modulePath: string; switch (ms.kind) { @@ -278,7 +306,9 @@ function _angularImportsFromNode(node: ts.ImportDeclaration): Record (is.propertyName ? is.propertyName.text : is.name.text)) + .map((is: ts.ImportSpecifier) => + is.propertyName ? is.propertyName.text : is.name.text, + ) .reduce((acc: Record, curr: string) => { acc[curr] = modulePath; @@ -322,7 +352,9 @@ export function getDecoratorMetadata( const id = expr.expression as ts.Identifier; return id.text == identifier && angularImports[id.text] === module; - } else if (expr.expression.kind == ts.SyntaxKind.PropertyAccessExpression) { + } else if ( + expr.expression.kind == ts.SyntaxKind.PropertyAccessExpression + ) { // This covers foo.NgModule when importing * as foo. const paExpr = expr.expression as ts.PropertyAccessExpression; // If the left expression is not an identifier, just give up at that point. @@ -340,7 +372,8 @@ export function getDecoratorMetadata( }) .filter( (expr) => - expr.arguments[0] && expr.arguments[0].kind == ts.SyntaxKind.ObjectLiteralExpression, + expr.arguments[0] && + expr.arguments[0].kind == ts.SyntaxKind.ObjectLiteralExpression, ) .map((expr) => expr.arguments[0] as ts.ObjectLiteralExpression); } @@ -355,7 +388,10 @@ export function getMetadataField( // Filter out every fields that's not "metadataField". Also handles string literals // (but not expressions). .filter(({ name }) => { - return (ts.isIdentifier(name) || ts.isStringLiteral(name)) && name.text === metadataField; + return ( + (ts.isIdentifier(name) || ts.isStringLiteral(name)) && + name.text === metadataField + ); }) ); } @@ -384,7 +420,9 @@ export function addSymbolToNgModuleMetadata( let toInsert: string; if (node.properties.length == 0) { position = node.getEnd() - 1; - toInsert = `\n ${metadataField}: [\n${tags.indentBy(4)`${symbolName}`}\n ]\n`; + toInsert = `\n ${metadataField}: [\n${tags.indentBy( + 4, + )`${symbolName}`}\n ]\n`; } else { const childNode = node.properties[node.properties.length - 1]; position = childNode.getEnd(); @@ -394,7 +432,9 @@ export function addSymbolToNgModuleMetadata( if (matches) { toInsert = `,${matches[0]}${metadataField}: [${matches[1]}` + - `${tags.indentBy(matches[2].length + 2)`${symbolName}`}${matches[0]}]`; + `${tags.indentBy(matches[2].length + 2)`${symbolName}`}${ + matches[0] + }]`; } else { toInsert = `, ${metadataField}: [${symbolName}]`; } @@ -402,7 +442,12 @@ export function addSymbolToNgModuleMetadata( if (importPath !== null) { return [ new InsertChange(ngModulePath, position, toInsert), - insertImport(source, ngModulePath, symbolName.replace(/\..*$/, ''), importPath), + insertImport( + source, + ngModulePath, + symbolName.replace(/\..*$/, ''), + importPath, + ), ]; } else { return [new InsertChange(ngModulePath, position, toInsert)]; @@ -423,7 +468,9 @@ export function addSymbolToNgModuleMetadata( const elements = assignmentInit.elements; if (elements.length) { - const symbolsArray = elements.map((node) => tags.oneLine`${node.getText()}`); + const symbolsArray = elements.map( + (node) => tags.oneLine`${node.getText()}`, + ); if (symbolsArray.includes(tags.oneLine`${symbolName}`)) { return []; } @@ -444,7 +491,9 @@ export function addSymbolToNgModuleMetadata( const text = expresssion.getFullText(source); const matches = text.match(/^(\r?\n)(\s*)/); if (matches) { - toInsert = `,${matches[1]}${tags.indentBy(matches[2].length)`${symbolName}`}`; + toInsert = `,${matches[1]}${tags.indentBy( + matches[2].length, + )`${symbolName}`}`; } else { toInsert = `, ${symbolName}`; } @@ -453,7 +502,12 @@ export function addSymbolToNgModuleMetadata( if (importPath !== null) { return [ new InsertChange(ngModulePath, position, toInsert), - insertImport(source, ngModulePath, symbolName.replace(/\..*$/, ''), importPath), + insertImport( + source, + ngModulePath, + symbolName.replace(/\..*$/, ''), + importPath, + ), ]; } @@ -488,7 +542,13 @@ export function addImportToModule( classifiedName: string, importPath: string, ): Change[] { - return addSymbolToNgModuleMetadata(source, modulePath, 'imports', classifiedName, importPath); + return addSymbolToNgModuleMetadata( + source, + modulePath, + 'imports', + classifiedName, + importPath, + ); } /** @@ -500,7 +560,13 @@ export function addProviderToModule( classifiedName: string, importPath: string, ): Change[] { - return addSymbolToNgModuleMetadata(source, modulePath, 'providers', classifiedName, importPath); + return addSymbolToNgModuleMetadata( + source, + modulePath, + 'providers', + classifiedName, + importPath, + ); } /** @@ -512,7 +578,13 @@ export function addExportToModule( classifiedName: string, importPath: string, ): Change[] { - return addSymbolToNgModuleMetadata(source, modulePath, 'exports', classifiedName, importPath); + return addSymbolToNgModuleMetadata( + source, + modulePath, + 'exports', + classifiedName, + importPath, + ); } /** @@ -524,7 +596,13 @@ export function addBootstrapToModule( classifiedName: string, importPath: string, ): Change[] { - return addSymbolToNgModuleMetadata(source, modulePath, 'bootstrap', classifiedName, importPath); + return addSymbolToNgModuleMetadata( + source, + modulePath, + 'bootstrap', + classifiedName, + importPath, + ); } /** @@ -539,7 +617,9 @@ export function isImported( const matchingNodes = allNodes .filter(ts.isImportDeclaration) .filter( - (imp) => ts.isStringLiteral(imp.moduleSpecifier) && imp.moduleSpecifier.text === importPath, + (imp) => + ts.isStringLiteral(imp.moduleSpecifier) && + imp.moduleSpecifier.text === importPath, ) .filter((imp) => { if (!imp.importClause) { @@ -558,7 +638,9 @@ export function isImported( /** * Returns the RouterModule declaration from NgModule metadata, if any. */ -export function getRouterModuleDeclaration(source: ts.SourceFile): ts.Expression | undefined { +export function getRouterModuleDeclaration( + source: ts.SourceFile, +): ts.Expression | undefined { const result = getDecoratorMetadata(source, 'NgModule', '@angular/core'); const node = result[0]; if (!node || !ts.isObjectLiteralExpression(node)) { @@ -595,14 +677,18 @@ export function addRouteDeclarationToModule( if (!routerModuleExpr) { throw new Error( `Couldn't find a route declaration in ${fileToAdd}.\n` + - `Use the '--module' option to specify a different routing module.`, + `Use the '--module' option to specify a different routing module.`, ); } - const scopeConfigMethodArgs = (routerModuleExpr as ts.CallExpression).arguments; + const scopeConfigMethodArgs = (routerModuleExpr as ts.CallExpression) + .arguments; if (!scopeConfigMethodArgs.length) { - const { line } = source.getLineAndCharacterOfPosition(routerModuleExpr.getStart()); + const { line } = source.getLineAndCharacterOfPosition( + routerModuleExpr.getStart(), + ); throw new Error( - `The router module method doesn't have arguments ` + `at line ${line} in ${fileToAdd}`, + `The router module method doesn't have arguments ` + + `at line ${line} in ${fileToAdd}`, ); } @@ -618,15 +704,19 @@ export function addRouteDeclarationToModule( let routesVar; if (routesArg.kind === ts.SyntaxKind.Identifier) { routesVar = source.statements.filter(ts.isVariableStatement).find((v) => { - return v.declarationList.declarations[0].name.getText() === routesVarName; + return ( + v.declarationList.declarations[0].name.getText() === routesVarName + ); }); } if (!routesVar) { - const { line } = source.getLineAndCharacterOfPosition(routesArg.getStart()); + const { line } = source.getLineAndCharacterOfPosition( + routesArg.getStart(), + ); throw new Error( `No route declaration array was found that corresponds ` + - `to router module at line ${line} in ${fileToAdd}`, + `to router module at line ${line} in ${fileToAdd}`, ); } @@ -714,7 +804,9 @@ export function hasTopLevelIdentifier( node.moduleSpecifier.text !== skipModule && node.importClause?.namedBindings && ts.isNamedImports(node.importClause.namedBindings) && - node.importClause.namedBindings.elements.some((el) => el.name.text === symbolName) + node.importClause.namedBindings.elements.some( + (el) => el.name.text === symbolName, + ) ) { return true; } diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/utils/change.ts b/packages/@guidesmiths/cuckoojs-schematics/src/utils/change.ts index bafa8fc2..db44ceb8 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/utils/change.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/utils/change.ts @@ -1,7 +1,7 @@ /* -* Copy-paste from https://github.com/angular/angular-cli/blob/main/packages/schematics/angular/utility/change.ts -* following suggestions from this issue: https://github.com/angular/angular-cli/issues/19885#issuecomment-768272337 -* */ + * Copy-paste from https://github.com/angular/angular-cli/blob/main/packages/schematics/angular/utility/change.ts + * following suggestions from this issue: https://github.com/angular/angular-cli/issues/19885#issuecomment-768272337 + * */ /** * @license @@ -51,7 +51,11 @@ export class InsertChange implements Change { order: number; description: string; - constructor(public path: string, public pos: number, public toAdd: string) { + constructor( + public path: string, + public pos: number, + public toAdd: string, + ) { if (pos < 0) { throw new Error('Negative positions are invalid'); } @@ -79,7 +83,11 @@ export class RemoveChange implements Change { order: number; description: string; - constructor(public path: string, private pos: number, public toRemove: string) { + constructor( + public path: string, + private pos: number, + public toRemove: string, + ) { if (pos < 0) { throw new Error('Negative positions are invalid'); } @@ -125,7 +133,9 @@ export class ReplaceChange implements Change { const text = content.substring(this.pos, this.pos + this.oldText.length); if (text !== this.oldText) { - return Promise.reject(new Error(`Invalid replace: "${text}" != "${this.oldText}".`)); + return Promise.reject( + new Error(`Invalid replace: "${text}" != "${this.oldText}".`), + ); } // TODO: throw error if oldText doesn't match removed string. @@ -134,7 +144,10 @@ export class ReplaceChange implements Change { } } -export function applyToUpdateRecorder(recorder: UpdateRecorder, changes: Change[]): void { +export function applyToUpdateRecorder( + recorder: UpdateRecorder, + changes: Change[], +): void { for (const change of changes) { if (change instanceof InsertChange) { recorder.insertLeft(change.pos, change.toAdd); @@ -144,7 +157,9 @@ export function applyToUpdateRecorder(recorder: UpdateRecorder, changes: Change[ recorder.remove(change.order, change.oldText.length); recorder.insertLeft(change.order, change.newText); } else if (!(change instanceof NoopChange)) { - throw new Error('Unknown Change type encountered when updating a recorder.'); + throw new Error( + 'Unknown Change type encountered when updating a recorder.', + ); } } } diff --git a/packages/@guidesmiths/cuckoojs-schematics/src/utils/package-json.utils.ts b/packages/@guidesmiths/cuckoojs-schematics/src/utils/package-json.utils.ts index e9cc1b6b..05d7c01c 100644 --- a/packages/@guidesmiths/cuckoojs-schematics/src/utils/package-json.utils.ts +++ b/packages/@guidesmiths/cuckoojs-schematics/src/utils/package-json.utils.ts @@ -1,99 +1,122 @@ -import {type Tree} from '@angular-devkit/schematics'; +import { type Tree } from '@angular-devkit/schematics'; import { - type ParseError, - type JSONPath, - type Segment, - parseTree, - printParseErrorCode, - modify, - applyEdits, - findNodeAtLocation, + type ParseError, + type JSONPath, + type Segment, + parseTree, + printParseErrorCode, + modify, + applyEdits, + findNodeAtLocation, } from 'jsonc-parser'; interface IInsertDependencyOptions { - ordered?: boolean; - overwrite?: boolean; + ordered?: boolean; + overwrite?: boolean; } export class PackageJsonUtils { - content: string; - host: Tree; - path: string; + content: string; + host: Tree; + path: string; - constructor(host: Tree, path = './package.json') { - const buffer = host.read(path); - if (!buffer) { - throw new Error(`Path ${path} not found.`); - } + constructor(host: Tree, path = './package.json') { + const buffer = host.read(path); + if (!buffer) { + throw new Error(`Path ${path} not found.`); + } - this.content = buffer.toString(); + this.content = buffer.toString(); - this.host = host; - this.path = path; + this.host = host; + this.path = path; - this.checkFileContent(); - } + this.checkFileContent(); + } - // @TODO: deprecate and replace all usages with addDependency or addDevDependency - addPackage(name: string, version: string, dev = false) { - const section = dev ? 'devDependencies' : 'dependencies'; - this.addWithPath([section, name], version, {ordered: true, overwrite: true}); - } + // @TODO: deprecate and replace all usages with addDependency or addDevDependency + addPackage(name: string, version: string, dev = false) { + const section = dev ? 'devDependencies' : 'dependencies'; + this.addWithPath([section, name], version, { + ordered: true, + overwrite: true, + }); + } - addDependency(name: string, version: string) { - this.addWithPath(['dependencies', name], version, {ordered: true, overwrite: true}); - } + addDependency(name: string, version: string) { + this.addWithPath(['dependencies', name], version, { + ordered: true, + overwrite: true, + }); + } - addDevDependency(name: string, version: string) { - this.addWithPath(['devDependencies', name], version, {ordered: true, overwrite: true}); - } + addDevDependency(name: string, version: string) { + this.addWithPath(['devDependencies', name], version, { + ordered: true, + overwrite: true, + }); + } - addScript(name: string, value: string) { - this.addWithPath(['scripts', name], value); - } + addScript(name: string, value: string) { + this.addWithPath(['scripts', name], value); + } - addWithPath(path: string[], value: string, options: IInsertDependencyOptions = {}) { - this.content = this.insertDependency(path, value, options); - this.host.overwrite(this.path, this.content); - } + addWithPath( + path: string[], + value: string, + options: IInsertDependencyOptions = {}, + ) { + this.content = this.insertDependency(path, value, options); + this.host.overwrite(this.path, this.content); + } - private checkFileContent() { - const packageErrors: ParseError[] | undefined = []; - parseTree(this.content, packageErrors); - if (packageErrors.length) { - const {error, offset: errorLocation} = packageErrors[0]; - throw new Error(`Failed to parse file ${this.path}. ${printParseErrorCode(error)} at location ${errorLocation}.`); - } - } + private checkFileContent() { + const packageErrors: ParseError[] | undefined = []; + parseTree(this.content, packageErrors); + if (packageErrors.length) { + const { error, offset: errorLocation } = packageErrors[0]; + throw new Error( + `Failed to parse file ${this.path}. ${printParseErrorCode( + error, + )} at location ${errorLocation}.`, + ); + } + } - private insertDependency(path: JSONPath, value: string, options: IInsertDependencyOptions = {ordered: false, overwrite: false}) { - const propertyToInsert = path.slice(-1)[0]; - const getInsertionIndex = options.ordered - // eslint-disable-next-line @typescript-eslint/require-array-sort-compare - ? (properties: Segment[]) => [...properties, propertyToInsert] - .sort() - .findIndex(p => p === propertyToInsert) - : undefined; + private insertDependency( + path: JSONPath, + value: string, + options: IInsertDependencyOptions = { ordered: false, overwrite: false }, + ) { + const propertyToInsert = path.slice(-1)[0]; + const getInsertionIndex = options.ordered + ? // eslint-disable-next-line @typescript-eslint/require-array-sort-compare + (properties: Segment[]) => + [...properties, propertyToInsert] + .sort() + .findIndex((p) => p === propertyToInsert) + : undefined; - if (!options.overwrite) { - const tree = parseTree(this.content); - if (tree) { - const prevValue: string = findNodeAtLocation(tree, path)?.value as string; - if (prevValue && !prevValue.includes(value)) { - value = value.concat(' && ', prevValue); - } - } - } + if (!options.overwrite) { + const tree = parseTree(this.content); + if (tree) { + const prevValue: string = findNodeAtLocation(tree, path) + ?.value as string; + if (prevValue && !prevValue.includes(value)) { + value = value.concat(' && ', prevValue); + } + } + } - const editResult = modify(this.content, path, value, { - formattingOptions: { - tabSize: 2, - insertSpaces: true, - }, - getInsertionIndex, - }); - const updatedPackage = applyEdits(this.content, editResult); - this.checkFileContent(); - return updatedPackage; - } + const editResult = modify(this.content, path, value, { + formattingOptions: { + tabSize: 2, + insertSpaces: true, + }, + getInsertionIndex, + }); + const updatedPackage = applyEdits(this.content, editResult); + this.checkFileContent(); + return updatedPackage; + } }