Skip to content

Commit a9b68b1

Browse files
fix: remove lib from ignored folders
1 parent 9f8b702 commit a9b68b1

35 files changed

+20535
-4886
lines changed

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ node_modules/
66

77
# output
88
coverage
9-
lib
10-
bin
9+
/lib
10+
/bin
1111

1212
# configuration
1313
/.vscode

package-lock.json

Lines changed: 14543 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,20 @@
2020
"node": ">= 10.13.0",
2121
"npm": ">= 6.11.0"
2222
},
23+
"main": "bin/fun.js",
24+
"preferGlobal": true,
2325
"bin": {
2426
"fun": "bin/fun.js"
2527
},
2628
"files": [
27-
"lib",
28-
"bin"
29+
"bin",
30+
"lib"
2931
],
3032
"scripts": {
3133
"build": "tsc",
32-
"format": "prettier --write \"**/*.ts\"",
3334
"lint": "eslint 'src/**/*.ts' --fix",
3435
"start": "node bin/fun.js",
35-
"prepublish:next": "npm run build",
36-
"publish:next": "npm publish --access public --tag next",
37-
"prepublish:npm": "npm run build",
38-
"publish:npm": "npm publish --access public",
39-
"test": "jest --config jest.config.js",
40-
"test:dev": "jest --config jest.config.js --watchAll",
41-
"prerelease": "npm run build"
36+
"test": "jest --config jest.config.js"
4237
},
4338
"repository": {
4439
"type": "git",

src/lib/actions/abstract.action.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { Input } from '../commands/command.input';
2+
3+
export abstract class AbstractAction {
4+
setup(this: AbstractAction): (...args: any[]) => Promise<void> {
5+
return async (...args: any[]) => {
6+
const inputs = this.mountInputs(...args);
7+
8+
try {
9+
await this.handle(inputs);
10+
} catch (e) {
11+
process.exit(1);
12+
}
13+
};
14+
}
15+
16+
public abstract handle(
17+
inputs?: Input[],
18+
options?: Input[],
19+
extraFlags?: string[],
20+
): Promise<void>;
21+
22+
public abstract mountInputs(...args: any[]): Input[];
23+
}

src/lib/actions/add.action.ts

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import chalk from 'chalk';
2+
import { Command } from 'commander';
3+
import * as fs from 'fs';
4+
5+
import { Input } from '../commands/command.input';
6+
import { buildProject } from '../core/project/builder/project.builder';
7+
import { ProjectRepository } from '../core/project/persistence/repository';
8+
import {
9+
ADD_ACTION_SUCCESS,
10+
PROJECT_ALREADY_EXISTS,
11+
PROJECT_DETAILS_HELP,
12+
RUN_COMMAND_HELP,
13+
} from '../core/ui/messages';
14+
import { AbstractAction } from './abstract.action';
15+
import { createInputsFromAlias, getProjectAlias } from './input.handler';
16+
17+
export class AddAction extends AbstractAction {
18+
constructor(private repository: ProjectRepository) {
19+
super();
20+
}
21+
22+
public mountInputs(alias: string, command: Command): Input[] {
23+
const inputs = createInputsFromAlias(alias);
24+
inputs.push({ name: 'path', value: command.path });
25+
26+
return inputs;
27+
}
28+
29+
public async handle(inputs: Input[]) {
30+
const projectAlias = getProjectAlias(inputs);
31+
await this._ensureProjectDoesNotExists(projectAlias);
32+
33+
const projectPath = this._getProjectPath(inputs);
34+
const project = await buildProject(projectAlias, projectPath);
35+
36+
await this.repository.create(project);
37+
38+
console.log(ADD_ACTION_SUCCESS(project));
39+
console.log(RUN_COMMAND_HELP(project));
40+
}
41+
42+
private async _ensureProjectDoesNotExists(
43+
projectAlias: string,
44+
): Promise<void> {
45+
const project = await this.repository.findOne(projectAlias);
46+
47+
if (!!project) {
48+
const errorMessage = PROJECT_ALREADY_EXISTS(projectAlias);
49+
50+
console.error(errorMessage);
51+
console.info(PROJECT_DETAILS_HELP(projectAlias));
52+
53+
throw new Error(errorMessage);
54+
}
55+
}
56+
57+
private _getProjectPath(inputs: Input[]): string {
58+
const pathInput: Input = inputs.find(
59+
(input) => input.name === 'path',
60+
) as Input;
61+
62+
if (!pathInput) {
63+
throw new Error('No path found in command input');
64+
}
65+
66+
const path = pathInput.value as string;
67+
68+
if (!fs.existsSync(path)) {
69+
const errorMessage = `\nPath "${path}" not exists or is unacessible\n`;
70+
71+
console.error(chalk.red(errorMessage));
72+
73+
throw new Error(errorMessage);
74+
}
75+
76+
if (!fs.lstatSync(path).isDirectory()) {
77+
const errorMessage = '\nPath must be a directory\n';
78+
79+
console.error(chalk.red(errorMessage));
80+
81+
throw new Error(errorMessage);
82+
}
83+
84+
return path;
85+
}
86+
}

src/lib/actions/delete.action.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import * as inquirer from 'inquirer';
2+
3+
import { Input } from '../commands/command.input';
4+
import { buildDeleteProjectConfirmationQuestion } from '../core/project/builder/questions.builder';
5+
import { ProjectRepository } from '../core/project/persistence/repository';
6+
import { Project } from '../core/project/project.entity';
7+
import {
8+
DELETE_FAIL_JOKE,
9+
NOT_CONFIRMED_DELETION,
10+
PROJECT_DELETED_WITH_SUCCESS,
11+
UNEXPECTED_ERROR,
12+
} from '../core/ui/messages';
13+
import { AbstractAction } from './abstract.action';
14+
import { createInputsFromAlias, getProjectAlias } from './input.handler';
15+
16+
export class DeleteAction extends AbstractAction {
17+
constructor(private repository: ProjectRepository) {
18+
super();
19+
}
20+
21+
public mountInputs(alias: string): Input[] {
22+
return createInputsFromAlias(alias);
23+
}
24+
25+
public async handle(inputs: Input[]) {
26+
const project = await this._getProject(inputs);
27+
28+
const question = buildDeleteProjectConfirmationQuestion(project);
29+
30+
const answers = await inquirer.prompt(question);
31+
32+
if (!answers.shouldDelete) {
33+
return console.info(NOT_CONFIRMED_DELETION);
34+
}
35+
36+
const deleted = await this.repository.delete(project.getAlias());
37+
38+
if (deleted) {
39+
return console.info(PROJECT_DELETED_WITH_SUCCESS(project));
40+
}
41+
42+
console.error(UNEXPECTED_ERROR);
43+
console.info(DELETE_FAIL_JOKE(project));
44+
}
45+
46+
private async _getProject(inputs: Input[]): Promise<Project> {
47+
const projectAlias = getProjectAlias(inputs);
48+
49+
return this.repository.findOneOrFail(projectAlias);
50+
}
51+
}

src/lib/actions/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export * from './abstract.action';
2+
export * from './add.action';
3+
export * from './with.action';
4+
export * from './delete.action';
5+
export * from './list.action';

src/lib/actions/input.handler.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { Input } from '../commands/command.input';
2+
3+
export function getProjectAlias(inputs: Input[]): string {
4+
const aliasInput: Input = inputs.find(
5+
(input) => input.name === 'alias',
6+
) as Input;
7+
8+
if (!aliasInput) {
9+
throw new Error('No alias found in command input');
10+
}
11+
12+
return aliasInput.value as string;
13+
}
14+
15+
export function createInputsFromAlias(alias: string): Input[] {
16+
const inputs: Input[] = [];
17+
inputs.push({ name: 'alias', value: alias });
18+
19+
return inputs;
20+
}

src/lib/actions/list.action.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { Input } from '../commands/command.input';
2+
import { ProjectRepository } from '../core/project/persistence/repository';
3+
import {
4+
ADD_PROJECT_HELP,
5+
EMPTY_PROJECTS,
6+
LIST_PROJECTS,
7+
PROJECT_DETAILS_HELP,
8+
} from '../core/ui/messages';
9+
import { AbstractAction } from './abstract.action';
10+
11+
export class ListAction extends AbstractAction {
12+
constructor(private repository: ProjectRepository) {
13+
super();
14+
}
15+
16+
public mountInputs(): Input[] {
17+
return [];
18+
}
19+
20+
public async handle() {
21+
const projects = await this.repository.listAll();
22+
23+
if (projects.length === 0) {
24+
console.info(EMPTY_PROJECTS);
25+
console.info(ADD_PROJECT_HELP);
26+
return;
27+
}
28+
29+
console.info(LIST_PROJECTS(projects));
30+
console.info(PROJECT_DETAILS_HELP());
31+
}
32+
}

src/lib/actions/with.action.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { Input } from '../commands/command.input';
2+
import { createProjectRepository } from '../core/project/persistence/repository.factory';
3+
import { Project } from '../core/project/project.entity';
4+
import { Task } from '../core/project/tasks/abstract.task';
5+
import {
6+
TASK_EXECUTED_WITH_SUCCESS,
7+
TASK_EXECUTION_FAILED,
8+
TASK_EXECUTION_STARTED,
9+
WITH_ACTION_DONE,
10+
WITH_ACTION_STARTED,
11+
} from '../core/ui/messages';
12+
import { AbstractAction } from './abstract.action';
13+
import { createInputsFromAlias, getProjectAlias } from './input.handler';
14+
15+
export class WithAction extends AbstractAction {
16+
public mountInputs(alias: string): Input[] {
17+
return createInputsFromAlias(alias);
18+
}
19+
20+
public async handle(inputs: Input[]) {
21+
const project = await this._getProject(inputs);
22+
23+
console.info(WITH_ACTION_STARTED);
24+
25+
const tasksExecution = project
26+
.getTasks()
27+
.map((task) => this._executeTask(task, project));
28+
29+
await Promise.all(tasksExecution);
30+
31+
console.info(WITH_ACTION_DONE(project));
32+
}
33+
34+
private async _getProject(inputs: Input[]): Promise<Project> {
35+
const projectAlias = getProjectAlias(inputs);
36+
37+
const repository = createProjectRepository();
38+
39+
return repository.findOneOrFail(projectAlias);
40+
}
41+
42+
private async _executeTask(task: Task, project: Project): Promise<void> {
43+
process.stdout.write(TASK_EXECUTION_STARTED(task));
44+
45+
const executed = await task.execute(project);
46+
if (executed) {
47+
process.stdout.write(TASK_EXECUTED_WITH_SUCCESS(task));
48+
} else {
49+
process.stdout.write(TASK_EXECUTION_FAILED(task));
50+
}
51+
}
52+
}

0 commit comments

Comments
 (0)