johankit 0.1.3 → 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 +45 -62
- package/dist/cli/commands/sync.js +38 -59
- package/dist/core/validation.js +7 -20
- package/dist/core/write.js +10 -9
- package/dist/src/cli/commands/copy.js +11 -0
- package/dist/src/cli/commands/paste.js +128 -0
- package/dist/src/cli/commands/prompt.js +54 -0
- package/dist/src/cli/commands/sync.js +166 -0
- package/dist/src/core/clipboard.js +64 -0
- package/dist/src/core/config.js +41 -0
- package/dist/{core → src/core}/diff.js +10 -14
- package/dist/{core → src/core}/git.js +1 -2
- package/dist/src/core/scan.js +75 -0
- package/dist/src/core/schema.js +18 -0
- package/dist/src/core/validation.js +11 -0
- package/dist/src/core/write.js +24 -0
- package/dist/src/index.js +39 -0
- package/dist/src/tests/cleanCodeBlock.test.js +23 -0
- package/dist/src/tests/scan.test.js +35 -0
- package/dist/src/tests/schema.test.js +22 -0
- package/dist/src/utils/cleanCodeBlock.js +13 -0
- package/dist/types.js +1 -0
- package/johankit.yml +6 -0
- package/package.json +20 -10
- package/src/cli/commands/copy.ts +6 -19
- package/src/cli/commands/paste.ts +79 -31
- package/src/cli/commands/prompt.ts +24 -64
- package/src/cli/commands/sync.ts +112 -71
- package/src/core/clipboard.ts +46 -80
- package/src/core/config.ts +22 -32
- package/src/core/diff.ts +10 -21
- package/src/core/scan.ts +52 -43
- package/src/core/schema.ts +17 -34
- package/src/core/validation.ts +8 -27
- package/src/core/write.ts +11 -17
- package/src/index.ts +43 -77
- package/src/tests/cleanCodeBlock.test.ts +21 -0
- package/src/tests/scan.test.ts +33 -0
- package/src/tests/schema.test.ts +24 -0
- package/src/types.ts +4 -50
- package/src/utils/cleanCodeBlock.ts +12 -12
- package/tsconfig.json +14 -5
- package/Readme.md +0 -56
- package/dist/cli/commands/copy.js +0 -29
- package/dist/cli/commands/paste.js +0 -49
- package/dist/cli/commands/prompt.js +0 -89
- package/dist/cli/commands/three.js +0 -106
- package/dist/cli/commands/tree.js +0 -107
- package/dist/core/clipboard.js +0 -89
- package/dist/core/config.js +0 -52
- package/dist/core/scan.js +0 -67
- package/dist/core/schema.js +0 -41
- package/dist/index.js +0 -72
- package/dist/services/JohankitService.js +0 -59
- package/dist/utils/cleanCodeBlock.js +0 -12
- package/dist/utils/createAsciiTree.js +0 -46
- package/johankit.yaml +0 -2
- package/src/cli/commands/tree.ts +0 -119
- package/src/services/JohankitService.ts +0 -70
- package/src/utils/createAsciiTree.ts +0 -53
- package/types.ts +0 -11
- /package/{types.js → dist/src/types.js} +0 -0
package/dist/core/schema.js
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.validatePatches = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* Valida se um objeto se parece com um Patch de DiffPatch válido.
|
|
6
|
-
* Não faz validação completa de esquema (JSON Schema), mas verifica a estrutura básica.
|
|
7
|
-
*/
|
|
8
|
-
function isValidPatch(patch) {
|
|
9
|
-
if (typeof patch !== "object" || patch === null)
|
|
10
|
-
return false;
|
|
11
|
-
if (typeof patch.path !== "string" || patch.path.length === 0)
|
|
12
|
-
return false;
|
|
13
|
-
const validTypes = ["modify", "create", "delete"];
|
|
14
|
-
if (!validTypes.includes(patch.type))
|
|
15
|
-
return false;
|
|
16
|
-
if (patch.type === "delete") {
|
|
17
|
-
return patch.content === undefined;
|
|
18
|
-
}
|
|
19
|
-
else {
|
|
20
|
-
return typeof patch.content === "string";
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Valida um array de patches de diff (DiffPatch[]).
|
|
25
|
-
* @param patches O array a ser validado.
|
|
26
|
-
* @returns O array de patches se for válido.
|
|
27
|
-
* @throws Um erro se a validação falhar.
|
|
28
|
-
*/
|
|
29
|
-
function validatePatches(patches) {
|
|
30
|
-
if (!Array.isArray(patches)) {
|
|
31
|
-
throw new Error("O patch deve ser um array JSON válido");
|
|
32
|
-
}
|
|
33
|
-
for (const [index, patch] of patches.entries()) {
|
|
34
|
-
if (!isValidPatch(patch)) {
|
|
35
|
-
throw new Error(`Patch inválido no índice ${index}: ${JSON.stringify(patch, null, 2)}.\nEsperado: { type: 'modify'|'create'|'delete', path: string, content?: string }`);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
// Assume que o array validado está no formato correto de DiffPatch[]
|
|
39
|
-
return patches;
|
|
40
|
-
}
|
|
41
|
-
exports.validatePatches = validatePatches;
|
package/dist/index.js
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.JohankitService = void 0;
|
|
5
|
-
const JohankitService_1 = require("./services/JohankitService");
|
|
6
|
-
Object.defineProperty(exports, "JohankitService", { enumerable: true, get: function () { return JohankitService_1.JohankitService; } });
|
|
7
|
-
const [, , command, ...args] = process.argv;
|
|
8
|
-
const service = new JohankitService_1.JohankitService();
|
|
9
|
-
async function main() {
|
|
10
|
-
try {
|
|
11
|
-
switch (command) {
|
|
12
|
-
case "copy": {
|
|
13
|
-
const dir = args[0] ?? ".";
|
|
14
|
-
await service.copy(dir);
|
|
15
|
-
break;
|
|
16
|
-
}
|
|
17
|
-
case "paste": {
|
|
18
|
-
const dir = args[0] ?? ".";
|
|
19
|
-
await service.paste(dir);
|
|
20
|
-
break;
|
|
21
|
-
}
|
|
22
|
-
case "prompt": {
|
|
23
|
-
const dir = args[0] ?? ".";
|
|
24
|
-
const diff = args.includes("--diff");
|
|
25
|
-
const userPrompt = args.filter(a => a !== "--diff").slice(1).join(" ");
|
|
26
|
-
await service.prompt(dir, userPrompt, diff);
|
|
27
|
-
break;
|
|
28
|
-
}
|
|
29
|
-
case "sync": {
|
|
30
|
-
const dir = args[0] ?? ".";
|
|
31
|
-
await service.sync(dir);
|
|
32
|
-
break;
|
|
33
|
-
}
|
|
34
|
-
case "tree": {
|
|
35
|
-
const dir = args[0] ?? ".";
|
|
36
|
-
const output = await service.tree(dir);
|
|
37
|
-
console.log(output);
|
|
38
|
-
break;
|
|
39
|
-
}
|
|
40
|
-
default:
|
|
41
|
-
showHelp();
|
|
42
|
-
break;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
catch (error) {
|
|
46
|
-
if (error instanceof Error) {
|
|
47
|
-
console.error("Error:", error.message);
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
console.error("Unexpected error:", error);
|
|
51
|
-
}
|
|
52
|
-
process.exit(1);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
function showHelp() {
|
|
56
|
-
console.log(`
|
|
57
|
-
Usage:
|
|
58
|
-
johankit copy <dir>
|
|
59
|
-
johankit paste <dir>
|
|
60
|
-
johankit prompt <dir> "<user request>" [--diff]
|
|
61
|
-
johankit sync <dir>
|
|
62
|
-
johankit tree <dir>
|
|
63
|
-
|
|
64
|
-
Examples:
|
|
65
|
-
johankit copy src
|
|
66
|
-
johankit paste src
|
|
67
|
-
johankit prompt src "refactor to async/await"
|
|
68
|
-
johankit sync src
|
|
69
|
-
johankit tree src
|
|
70
|
-
`);
|
|
71
|
-
}
|
|
72
|
-
main();
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.JohankitService = void 0;
|
|
7
|
-
const createAsciiTree_1 = __importDefault(require("../utils/createAsciiTree"));
|
|
8
|
-
const copy_1 = require("../cli/commands/copy");
|
|
9
|
-
const paste_1 = require("../cli/commands/paste");
|
|
10
|
-
const prompt_1 = require("../cli/commands/prompt");
|
|
11
|
-
const tree_1 = require("../cli/commands/tree");
|
|
12
|
-
const scan_1 = require("../core/scan");
|
|
13
|
-
const diff_1 = require("../core/diff");
|
|
14
|
-
const validation_1 = require("../core/validation");
|
|
15
|
-
const write_1 = require("../core/write");
|
|
16
|
-
class JohankitService {
|
|
17
|
-
constructor(options = {}) {
|
|
18
|
-
this.isolated = options.isolated ?? false;
|
|
19
|
-
}
|
|
20
|
-
setInput(input) {
|
|
21
|
-
this.internalInput = input;
|
|
22
|
-
}
|
|
23
|
-
async copy(dir = ".") {
|
|
24
|
-
return (0, copy_1.copy)(dir);
|
|
25
|
-
}
|
|
26
|
-
async paste(dir = ".") {
|
|
27
|
-
return (0, paste_1.paste)(dir);
|
|
28
|
-
}
|
|
29
|
-
async prompt(dir, userPrompt, diff = false) {
|
|
30
|
-
if (!userPrompt) {
|
|
31
|
-
throw new Error("Missing user prompt");
|
|
32
|
-
}
|
|
33
|
-
return (0, prompt_1.prompt)(dir, userPrompt, diff);
|
|
34
|
-
}
|
|
35
|
-
async sync(dir = ".", diff = false) {
|
|
36
|
-
const snapshotBefore = (0, scan_1.scanDir)(dir);
|
|
37
|
-
const input = this.isolated ? this.internalInput : undefined;
|
|
38
|
-
if (!this.isolated && input === undefined) {
|
|
39
|
-
throw new Error("sync() without isolation must be used via CLI (stdin)");
|
|
40
|
-
}
|
|
41
|
-
if (!input) {
|
|
42
|
-
throw new Error("No input provided for isolated sync");
|
|
43
|
-
}
|
|
44
|
-
if (diff) {
|
|
45
|
-
const validated = (0, validation_1.validatePatches)(input);
|
|
46
|
-
(0, diff_1.applyDiff)(dir, validated);
|
|
47
|
-
}
|
|
48
|
-
else {
|
|
49
|
-
(0, write_1.writeFiles)(dir, input, true);
|
|
50
|
-
}
|
|
51
|
-
const snapshotAfter = (0, scan_1.scanDir)(dir);
|
|
52
|
-
return { before: snapshotBefore, after: snapshotAfter };
|
|
53
|
-
}
|
|
54
|
-
async tree(dir = ".") {
|
|
55
|
-
const _tree = await (0, tree_1.tree)(dir);
|
|
56
|
-
return (0, createAsciiTree_1.default)(_tree);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
exports.JohankitService = JohankitService;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
function cleanCodeBlock(content) {
|
|
4
|
-
const langMatch = content.match(/^```(\w+)?/);
|
|
5
|
-
const lang = langMatch ? langMatch[1] : null;
|
|
6
|
-
let cleaned = content.replace(/^\uFEFF/, '');
|
|
7
|
-
cleaned = cleaned.replace(/^```(\w+)?\s*/, '').replace(/```$/, '');
|
|
8
|
-
cleaned = cleaned.replace(/[\u0000-\u0008\u000B-\u000C\u000E-\u001F\u007F-\u009F]/g, '');
|
|
9
|
-
cleaned = cleaned.trim();
|
|
10
|
-
return { lang, cleaned };
|
|
11
|
-
}
|
|
12
|
-
exports.default = cleanCodeBlock;
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
function createAsciiTree(files) {
|
|
4
|
-
let out = "";
|
|
5
|
-
files.forEach((file, i) => {
|
|
6
|
-
const lastFile = i === files.length - 1;
|
|
7
|
-
const fPrefix = lastFile ? "└── " : "├── ";
|
|
8
|
-
const fIndent = lastFile ? " " : "│ ";
|
|
9
|
-
out += `${fPrefix}📄 ${file.path} (${file.kind})\n`;
|
|
10
|
-
/* -------- Imports -------- */
|
|
11
|
-
if (file.imports.length) {
|
|
12
|
-
out += `${fIndent}├── 📦 Imports [${file.imports.length}]\n`;
|
|
13
|
-
file.imports.forEach((imp, idx) => {
|
|
14
|
-
const last = idx === file.imports.length - 1;
|
|
15
|
-
out += `${fIndent}${last ? "└── " : "├── "}${imp}\n`;
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
/* -------- Exports -------- */
|
|
19
|
-
if (file.exports.length) {
|
|
20
|
-
out += `${fIndent}├── 🔑 Exports\n`;
|
|
21
|
-
file.exports.forEach((e, idx) => {
|
|
22
|
-
const last = idx === file.exports.length - 1;
|
|
23
|
-
const main = e.name === file.mainExport ? " ⭐" : "";
|
|
24
|
-
out += `${fIndent}${last ? "└── " : "├── "}${e.name} (${e.kind})${main}\n`;
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
/* -------- Variables -------- */
|
|
28
|
-
file.variables.forEach(v => {
|
|
29
|
-
out += `${fIndent}├── 💡 ${v.name}: ${v.type} (${v.scope})\n`;
|
|
30
|
-
});
|
|
31
|
-
/* -------- Functions -------- */
|
|
32
|
-
file.functions.forEach(fn => {
|
|
33
|
-
out += `${fIndent}├── ⚡ ${fn.name}(${fn.params.join(", ")}): ${fn.returnType}\n`;
|
|
34
|
-
});
|
|
35
|
-
/* -------- Classes -------- */
|
|
36
|
-
file.classes.forEach(cls => {
|
|
37
|
-
out += `${fIndent}├── ⚙️ Class ${cls.name}\n`;
|
|
38
|
-
cls.methods.forEach((m, mi) => {
|
|
39
|
-
const last = mi === cls.methods.length - 1;
|
|
40
|
-
out += `${fIndent}│ ${last ? "└── " : "├── "}➡️ ${m.name}(${m.params.join(", ")}): ${m.returnType}\n`;
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
return out;
|
|
45
|
-
}
|
|
46
|
-
exports.default = createAsciiTree;
|
package/johankit.yaml
DELETED
package/src/cli/commands/tree.ts
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import path from "path";
|
|
2
|
-
import { Project, SourceFile, SyntaxKind } from "ts-morph";
|
|
3
|
-
import {
|
|
4
|
-
FileTree,
|
|
5
|
-
ClassInfo,
|
|
6
|
-
FunctionInfo,
|
|
7
|
-
VariableInfo,
|
|
8
|
-
ExportInfo,
|
|
9
|
-
FileKind
|
|
10
|
-
} from "types";
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Heurística simples para classificar arquivos
|
|
14
|
-
*/
|
|
15
|
-
function detectFileKind(filePath: string, exportsCount: number): FileKind {
|
|
16
|
-
if (filePath.includes("/cli/")) return "cli";
|
|
17
|
-
if (filePath.endsWith("index.ts") || filePath.endsWith("main.ts")) return "entry";
|
|
18
|
-
if (exportsCount === 0) return "util";
|
|
19
|
-
if (exportsCount > 3) return "domain";
|
|
20
|
-
return "unknown";
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export async function tree(dir: string): Promise<FileTree[]> {
|
|
24
|
-
const project = new Project({});
|
|
25
|
-
|
|
26
|
-
project.addSourceFilesAtPaths([
|
|
27
|
-
`${dir}/**/*.{ts,tsx,js,jsx}`,
|
|
28
|
-
`!${dir}/**/node_modules/**/*`,
|
|
29
|
-
`!${dir}/**/dist/**/*`,
|
|
30
|
-
]);
|
|
31
|
-
|
|
32
|
-
const tree: FileTree[] = [];
|
|
33
|
-
|
|
34
|
-
for (const file of project.getSourceFiles()) {
|
|
35
|
-
const absolutePath = file.getFilePath();
|
|
36
|
-
const filePath = path.relative(dir, absolutePath);
|
|
37
|
-
|
|
38
|
-
console.log(filePath);
|
|
39
|
-
|
|
40
|
-
if (filePath.includes("node_modules") || filePath.includes("/dist/")) {
|
|
41
|
-
continue;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/* ---------------- IMPORTS ---------------- */
|
|
45
|
-
const imports = file
|
|
46
|
-
.getImportDeclarations()
|
|
47
|
-
.map(i => i.getModuleSpecifierValue());
|
|
48
|
-
|
|
49
|
-
/* ---------------- CLASSES ---------------- */
|
|
50
|
-
const classes: ClassInfo[] = file.getClasses().map(cls => ({
|
|
51
|
-
name: cls.getName() || "<anonymous>",
|
|
52
|
-
methods: cls.getMethods().map(m => ({
|
|
53
|
-
name: m.getName(),
|
|
54
|
-
params: m.getParameters().map(p => p.getName()),
|
|
55
|
-
returnType: safeType(() => m.getReturnType().getText()),
|
|
56
|
-
scope: "class",
|
|
57
|
-
}))
|
|
58
|
-
}));
|
|
59
|
-
|
|
60
|
-
/* ---------------- FUNCTIONS ---------------- */
|
|
61
|
-
const functions: FunctionInfo[] = file.getFunctions().map(fn => ({
|
|
62
|
-
name: fn.getName() || "<anonymous>",
|
|
63
|
-
params: fn.getParameters().map(p => p.getName()),
|
|
64
|
-
returnType: safeType(() => fn.getReturnType().getText()),
|
|
65
|
-
scope: "global",
|
|
66
|
-
}));
|
|
67
|
-
|
|
68
|
-
/* ---------------- VARIABLES ---------------- */
|
|
69
|
-
const variables: VariableInfo[] = file.getVariableDeclarations().map(v => ({
|
|
70
|
-
name: v.getName(),
|
|
71
|
-
type: safeType(() => v.getType().getText()),
|
|
72
|
-
scope: v.getParent() instanceof SourceFile ? "global" : "local",
|
|
73
|
-
}));
|
|
74
|
-
|
|
75
|
-
/* ---------------- EXPORTS ---------------- */
|
|
76
|
-
const exports: ExportInfo[] = [];
|
|
77
|
-
let mainExport: string | undefined;
|
|
78
|
-
|
|
79
|
-
file.getExportedDeclarations().forEach((decls, name) => {
|
|
80
|
-
decls.forEach(d => {
|
|
81
|
-
let kind: ExportInfo["kind"] = "unknown";
|
|
82
|
-
|
|
83
|
-
if (d.getKind() === SyntaxKind.ClassDeclaration) kind = "class";
|
|
84
|
-
if (d.getKind() === SyntaxKind.FunctionDeclaration) kind = "function";
|
|
85
|
-
if (d.getKind() === SyntaxKind.VariableDeclaration) kind = "variable";
|
|
86
|
-
if (d.getKind() === SyntaxKind.TypeAliasDeclaration) kind = "type";
|
|
87
|
-
|
|
88
|
-
exports.push({ name, kind });
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
if (exports.length === 1) {
|
|
93
|
-
mainExport = exports[0].name;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const kind = detectFileKind(filePath, exports.length);
|
|
97
|
-
|
|
98
|
-
tree.push({
|
|
99
|
-
path: filePath,
|
|
100
|
-
kind,
|
|
101
|
-
imports,
|
|
102
|
-
classes,
|
|
103
|
-
functions,
|
|
104
|
-
variables,
|
|
105
|
-
exports,
|
|
106
|
-
mainExport,
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return tree;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function safeType(fn: () => string): string {
|
|
114
|
-
try {
|
|
115
|
-
return fn();
|
|
116
|
-
} catch {
|
|
117
|
-
return "unknown";
|
|
118
|
-
}
|
|
119
|
-
}
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import createAsciiTree from "../utils/createAsciiTree";
|
|
2
|
-
import { copy } from "../cli/commands/copy";
|
|
3
|
-
import { paste } from "../cli/commands/paste";
|
|
4
|
-
import { prompt } from "../cli/commands/prompt";
|
|
5
|
-
import { tree as treeCommand } from "../cli/commands/tree";
|
|
6
|
-
import { scanDir } from "../core/scan";
|
|
7
|
-
import { applyDiff, DiffPatch } from "../core/diff";
|
|
8
|
-
import { validatePatches } from "../core/validation";
|
|
9
|
-
import { writeFiles } from "../core/write";
|
|
10
|
-
|
|
11
|
-
interface JohankitServiceOptions {
|
|
12
|
-
isolated?: boolean;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export class JohankitService {
|
|
16
|
-
private isolated: boolean;
|
|
17
|
-
private internalInput?: any;
|
|
18
|
-
|
|
19
|
-
constructor(options: JohankitServiceOptions = {}) {
|
|
20
|
-
this.isolated = options.isolated ?? false;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
setInput(input: any) {
|
|
24
|
-
this.internalInput = input;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
async copy(dir: string = ".") {
|
|
28
|
-
return copy(dir);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
async paste(dir: string = ".") {
|
|
32
|
-
return paste(dir);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
async prompt(dir: string, userPrompt: string, diff = false) {
|
|
36
|
-
if (!userPrompt) {
|
|
37
|
-
throw new Error("Missing user prompt");
|
|
38
|
-
}
|
|
39
|
-
return prompt(dir, userPrompt, diff);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
async sync(dir: string = ".", diff = false) {
|
|
43
|
-
const snapshotBefore = scanDir(dir);
|
|
44
|
-
|
|
45
|
-
const input = this.isolated ? this.internalInput : undefined;
|
|
46
|
-
|
|
47
|
-
if (!this.isolated && input === undefined) {
|
|
48
|
-
throw new Error("sync() without isolation must be used via CLI (stdin)");
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (!input) {
|
|
52
|
-
throw new Error("No input provided for isolated sync");
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
if (diff) {
|
|
56
|
-
const validated = validatePatches(input) as DiffPatch[];
|
|
57
|
-
applyDiff(dir, validated);
|
|
58
|
-
} else {
|
|
59
|
-
writeFiles(dir, input, true);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const snapshotAfter = scanDir(dir);
|
|
63
|
-
return { before: snapshotBefore, after: snapshotAfter };
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
async tree(dir: string = ".") {
|
|
67
|
-
const _tree = await treeCommand(dir);
|
|
68
|
-
return createAsciiTree(_tree);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { FileTree } from "types";
|
|
2
|
-
|
|
3
|
-
export default function createAsciiTree(files: FileTree[]): string {
|
|
4
|
-
let out = "";
|
|
5
|
-
|
|
6
|
-
files.forEach((file, i) => {
|
|
7
|
-
const lastFile = i === files.length - 1;
|
|
8
|
-
const fPrefix = lastFile ? "└── " : "├── ";
|
|
9
|
-
const fIndent = lastFile ? " " : "│ ";
|
|
10
|
-
|
|
11
|
-
out += `${fPrefix}📄 ${file.path} (${file.kind})\n`;
|
|
12
|
-
|
|
13
|
-
/* -------- Imports -------- */
|
|
14
|
-
if (file.imports.length) {
|
|
15
|
-
out += `${fIndent}├── 📦 Imports [${file.imports.length}]\n`;
|
|
16
|
-
file.imports.forEach((imp, idx) => {
|
|
17
|
-
const last = idx === file.imports.length - 1;
|
|
18
|
-
out += `${fIndent}${last ? "└── " : "├── "}${imp}\n`;
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/* -------- Exports -------- */
|
|
23
|
-
if (file.exports.length) {
|
|
24
|
-
out += `${fIndent}├── 🔑 Exports\n`;
|
|
25
|
-
file.exports.forEach((e, idx) => {
|
|
26
|
-
const last = idx === file.exports.length - 1;
|
|
27
|
-
const main = e.name === file.mainExport ? " ⭐" : "";
|
|
28
|
-
out += `${fIndent}${last ? "└── " : "├── "}${e.name} (${e.kind})${main}\n`;
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/* -------- Variables -------- */
|
|
33
|
-
file.variables.forEach(v => {
|
|
34
|
-
out += `${fIndent}├── 💡 ${v.name}: ${v.type} (${v.scope})\n`;
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
/* -------- Functions -------- */
|
|
38
|
-
file.functions.forEach(fn => {
|
|
39
|
-
out += `${fIndent}├── ⚡ ${fn.name}(${fn.params.join(", ")}): ${fn.returnType}\n`;
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
/* -------- Classes -------- */
|
|
43
|
-
file.classes.forEach(cls => {
|
|
44
|
-
out += `${fIndent}├── ⚙️ Class ${cls.name}\n`;
|
|
45
|
-
cls.methods.forEach((m, mi) => {
|
|
46
|
-
const last = mi === cls.methods.length - 1;
|
|
47
|
-
out += `${fIndent}│ ${last ? "└── " : "├── "}➡️ ${m.name}(${m.params.join(", ")}): ${m.returnType}\n`;
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
return out;
|
|
53
|
-
}
|
package/types.ts
DELETED
|
File without changes
|