@napo98/wc-tool 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -0
- package/bun.lock +69 -0
- package/package.json +29 -0
- package/src/config/plugins/yargs.plugin.ts +36 -0
- package/src/domain/use-cases/countBytes.usecase.ts +27 -0
- package/src/domain/use-cases/countCharacters.usecase.ts +23 -0
- package/src/domain/use-cases/countLines.usecase.ts +23 -0
- package/src/domain/use-cases/countWords.usecase.ts +23 -0
- package/src/index.ts +32 -0
- package/src/presentation/server.ts +52 -0
- package/test.txt +7144 -0
- package/tsconfig.json +27 -0
package/README.md
ADDED
package/bun.lock
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"lockfileVersion": 1,
|
|
3
|
+
"workspaces": {
|
|
4
|
+
"": {
|
|
5
|
+
"name": "wc-tool",
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"yargs": "17.7.2",
|
|
8
|
+
},
|
|
9
|
+
"devDependencies": {
|
|
10
|
+
"@types/bun": "latest",
|
|
11
|
+
"@types/yargs": "^17.0.33",
|
|
12
|
+
},
|
|
13
|
+
"peerDependencies": {
|
|
14
|
+
"typescript": "^5.0.0",
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
"packages": {
|
|
19
|
+
"@types/bun": ["@types/bun@1.2.19", "", { "dependencies": { "bun-types": "1.2.19" } }, "sha512-d9ZCmrH3CJ2uYKXQIUuZ/pUnTqIvLDS0SK7pFmbx8ma+ziH/FRMoAq5bYpRG7y+w1gl+HgyNZbtqgMq4W4e2Lg=="],
|
|
20
|
+
|
|
21
|
+
"@types/node": ["@types/node@24.1.0", "", { "dependencies": { "undici-types": "~7.8.0" } }, "sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w=="],
|
|
22
|
+
|
|
23
|
+
"@types/react": ["@types/react@19.1.8", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g=="],
|
|
24
|
+
|
|
25
|
+
"@types/yargs": ["@types/yargs@17.0.33", "", { "dependencies": { "@types/yargs-parser": "*" } }, "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA=="],
|
|
26
|
+
|
|
27
|
+
"@types/yargs-parser": ["@types/yargs-parser@21.0.3", "", {}, "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ=="],
|
|
28
|
+
|
|
29
|
+
"ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
|
30
|
+
|
|
31
|
+
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
|
32
|
+
|
|
33
|
+
"bun-types": ["bun-types@1.2.19", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-uAOTaZSPuYsWIXRpj7o56Let0g/wjihKCkeRqUBhlLVM/Bt+Fj9xTo+LhC1OV1XDaGkz4hNC80et5xgy+9KTHQ=="],
|
|
34
|
+
|
|
35
|
+
"cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="],
|
|
36
|
+
|
|
37
|
+
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
|
|
38
|
+
|
|
39
|
+
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
|
|
40
|
+
|
|
41
|
+
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
|
42
|
+
|
|
43
|
+
"emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
|
44
|
+
|
|
45
|
+
"escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
|
|
46
|
+
|
|
47
|
+
"get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="],
|
|
48
|
+
|
|
49
|
+
"is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
|
|
50
|
+
|
|
51
|
+
"require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="],
|
|
52
|
+
|
|
53
|
+
"string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
|
54
|
+
|
|
55
|
+
"strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
|
56
|
+
|
|
57
|
+
"typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
|
|
58
|
+
|
|
59
|
+
"undici-types": ["undici-types@7.8.0", "", {}, "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw=="],
|
|
60
|
+
|
|
61
|
+
"wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
|
|
62
|
+
|
|
63
|
+
"y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="],
|
|
64
|
+
|
|
65
|
+
"yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="],
|
|
66
|
+
|
|
67
|
+
"yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="],
|
|
68
|
+
}
|
|
69
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@napo98/wc-tool",
|
|
3
|
+
|
|
4
|
+
"module": "index.ts",
|
|
5
|
+
"description": "Una herramienta tipo wc escrita en TypeScript con Bun",
|
|
6
|
+
"version": "1.0.0",
|
|
7
|
+
"main": "src/index.ts",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"scripts": {
|
|
10
|
+
"dev": "bun run src/index.ts ",
|
|
11
|
+
"build": "bun build src/index.ts --outdir dist --target bun",
|
|
12
|
+
"start": "bun run build && bun run dist/index.js",
|
|
13
|
+
"test": "bun test"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@types/bun": "latest",
|
|
17
|
+
"@types/yargs": "^17.0.33"
|
|
18
|
+
},
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"typescript": "^5.0.0"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"yargs": "17.7.2"
|
|
24
|
+
},
|
|
25
|
+
"bin": {
|
|
26
|
+
"wc-tool": "./src/index.ts"
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import yargs from 'yargs';
|
|
2
|
+
import { hideBin } from 'yargs/helpers';
|
|
3
|
+
|
|
4
|
+
export const yargsPlugin = yargs(hideBin(process.argv))
|
|
5
|
+
.option('c', {
|
|
6
|
+
alias: 'count',
|
|
7
|
+
type: 'boolean',
|
|
8
|
+
default: false,
|
|
9
|
+
describe: 'Returns the number of bytes in a file'
|
|
10
|
+
})
|
|
11
|
+
.option('l', {
|
|
12
|
+
alias: 'lines',
|
|
13
|
+
type: 'boolean',
|
|
14
|
+
default: false,
|
|
15
|
+
describe: 'Returns the number of lines in a file'
|
|
16
|
+
})
|
|
17
|
+
.option('w', {
|
|
18
|
+
alias: 'words',
|
|
19
|
+
type: 'boolean',
|
|
20
|
+
default: false,
|
|
21
|
+
describe: 'Returns the number of words in a file'
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
.option('m', {
|
|
25
|
+
alias: 'characters',
|
|
26
|
+
type: 'boolean',
|
|
27
|
+
default: false,
|
|
28
|
+
describe: 'Returns the number of characters in a file'
|
|
29
|
+
})
|
|
30
|
+
.option('f', {
|
|
31
|
+
alias: 'file',
|
|
32
|
+
type: 'string',
|
|
33
|
+
describe: 'File path'
|
|
34
|
+
})
|
|
35
|
+
.strict()
|
|
36
|
+
.parseSync();
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
|
|
3
|
+
//TODO: IF THERE IS MORE OPTIONS, CREATE A OPTIONS INTERFACE
|
|
4
|
+
interface CountBytesUseCase {
|
|
5
|
+
execute: (content?: string, file?: string) => Promise<number>;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export class CountBytes implements CountBytesUseCase {
|
|
9
|
+
async execute(content?: string, file?: string) {
|
|
10
|
+
let stats: any;
|
|
11
|
+
// console.log(content, file);
|
|
12
|
+
try {
|
|
13
|
+
if (content) {
|
|
14
|
+
return Buffer.byteLength(content!, 'utf-8');
|
|
15
|
+
} else {
|
|
16
|
+
stats = await fs.statSync(file!);
|
|
17
|
+
return stats.size;
|
|
18
|
+
}
|
|
19
|
+
} catch (error) {
|
|
20
|
+
console.log(error);
|
|
21
|
+
}
|
|
22
|
+
return -1;
|
|
23
|
+
// const content = fs.readFileSync(file, { encoding: 'utf-8' });
|
|
24
|
+
|
|
25
|
+
// console.log(content.split('\n').length);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
|
|
3
|
+
interface CountCharactersUseCase {
|
|
4
|
+
execute: (file: string) => number;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export class CountCharacters implements CountCharactersUseCase {
|
|
8
|
+
execute(content?: string, file?: string) {
|
|
9
|
+
let characters: string[] = [];
|
|
10
|
+
try {
|
|
11
|
+
if (file) {
|
|
12
|
+
const content = fs.readFileSync(file, { encoding: 'utf-8' });
|
|
13
|
+
characters = content.split('');
|
|
14
|
+
} else {
|
|
15
|
+
characters = content!.split('');
|
|
16
|
+
}
|
|
17
|
+
return characters.length;
|
|
18
|
+
} catch (error) {
|
|
19
|
+
console.log(error);
|
|
20
|
+
}
|
|
21
|
+
return -1;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
|
|
3
|
+
interface CountLinesUseCase {
|
|
4
|
+
execute: (content?: string, file?: string) => number;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export class CountLines implements CountLinesUseCase {
|
|
8
|
+
execute(content?: string, file?: string) {
|
|
9
|
+
let lines: number = 1;
|
|
10
|
+
try {
|
|
11
|
+
if (file) {
|
|
12
|
+
const content = fs.readFileSync(file, { encoding: 'utf-8' });
|
|
13
|
+
lines = content!.split('\n').length;
|
|
14
|
+
} else {
|
|
15
|
+
lines = content!.split('\n').length;
|
|
16
|
+
}
|
|
17
|
+
return lines;
|
|
18
|
+
} catch (error) {
|
|
19
|
+
console.log(error);
|
|
20
|
+
}
|
|
21
|
+
return -1;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
|
|
3
|
+
interface CountWordsUseCase {
|
|
4
|
+
execute: (content?: string, file?: string) => number;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export class CountWords implements CountWordsUseCase {
|
|
8
|
+
execute(content?: string, file?: string) {
|
|
9
|
+
let words: string[] = [];
|
|
10
|
+
try {
|
|
11
|
+
if (file) {
|
|
12
|
+
const content = fs.readFileSync(file, { encoding: 'utf-8' });
|
|
13
|
+
words = content!.trim().split(/\s+/);
|
|
14
|
+
} else {
|
|
15
|
+
words = content!.trim().split(/\s+/);
|
|
16
|
+
}
|
|
17
|
+
return words.length;
|
|
18
|
+
} catch (error) {
|
|
19
|
+
console.log(error);
|
|
20
|
+
}
|
|
21
|
+
return -1;
|
|
22
|
+
}
|
|
23
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import { yargsPlugin } from "./config/plugins/yargs.plugin";
|
|
3
|
+
import { WcTool } from "./presentation/server";
|
|
4
|
+
|
|
5
|
+
(() => {
|
|
6
|
+
main();
|
|
7
|
+
})();
|
|
8
|
+
|
|
9
|
+
function main() {
|
|
10
|
+
let {
|
|
11
|
+
c: bytes,
|
|
12
|
+
l: lines,
|
|
13
|
+
w: words,
|
|
14
|
+
m: characters,
|
|
15
|
+
f: filePath,
|
|
16
|
+
} = yargsPlugin;
|
|
17
|
+
if (!process.stdin.isTTY) {
|
|
18
|
+
let content = "";
|
|
19
|
+
|
|
20
|
+
process.stdin.on("data", (chunk) => {
|
|
21
|
+
content += chunk.toString();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
process.stdin.on("end", () => {
|
|
25
|
+
WcTool.execute({ bytes, lines, words, characters, content, filePath });
|
|
26
|
+
});
|
|
27
|
+
} else {
|
|
28
|
+
filePath = filePath ?? "test.txt";
|
|
29
|
+
|
|
30
|
+
WcTool.execute({ bytes, lines, words, characters, filePath });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { CountBytes } from "../domain/use-cases/countBytes.usecase";
|
|
2
|
+
import { CountCharacters } from "../domain/use-cases/countCharacters.usecase";
|
|
3
|
+
import { CountLines } from "../domain/use-cases/countLines.usecase";
|
|
4
|
+
import { CountWords } from "../domain/use-cases/countWords.usecase";
|
|
5
|
+
|
|
6
|
+
interface runOptions {
|
|
7
|
+
bytes?: boolean;
|
|
8
|
+
lines?: boolean;
|
|
9
|
+
words?: boolean;
|
|
10
|
+
characters?: boolean;
|
|
11
|
+
filePath?: string;
|
|
12
|
+
content?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class WcTool {
|
|
16
|
+
static async execute({
|
|
17
|
+
bytes,
|
|
18
|
+
lines,
|
|
19
|
+
words,
|
|
20
|
+
characters,
|
|
21
|
+
filePath,
|
|
22
|
+
content,
|
|
23
|
+
}: runOptions) {
|
|
24
|
+
let fileBytes: number,
|
|
25
|
+
fileLines: number,
|
|
26
|
+
fileWords: number,
|
|
27
|
+
fileCharacters: number = 0;
|
|
28
|
+
if (filePath) {
|
|
29
|
+
console.log(`File path: ${filePath}`);
|
|
30
|
+
fileBytes = await new CountBytes().execute(undefined, filePath);
|
|
31
|
+
fileLines = new CountLines().execute(undefined, filePath);
|
|
32
|
+
fileWords = new CountWords().execute(undefined, filePath);
|
|
33
|
+
fileCharacters = new CountCharacters().execute(undefined, filePath);
|
|
34
|
+
} else {
|
|
35
|
+
fileBytes = await new CountBytes().execute(content);
|
|
36
|
+
fileLines = new CountLines().execute(content);
|
|
37
|
+
fileWords = new CountWords().execute(content);
|
|
38
|
+
fileCharacters = new CountCharacters().execute(content);
|
|
39
|
+
}
|
|
40
|
+
if (!bytes && !lines && !words && !characters) {
|
|
41
|
+
// console.log(`Bytes: ${fileBytes}`);
|
|
42
|
+
console.log(`Lines: ${fileLines}`);
|
|
43
|
+
console.log(`Words: ${fileWords}`);
|
|
44
|
+
console.log(`Characters: ${fileCharacters}`);
|
|
45
|
+
}
|
|
46
|
+
if (words) console.log(`Words: ${fileWords}`);
|
|
47
|
+
if (bytes) console.log(`Bytes: ${fileBytes}`);
|
|
48
|
+
if (lines) console.log(`Lines: ${fileLines}`);
|
|
49
|
+
if (characters) console.log(`Lines: ${fileCharacters}`);
|
|
50
|
+
// if () console.log(`Lines: ${fileLines}`);
|
|
51
|
+
}
|
|
52
|
+
}
|