@kabanooovd/kaban 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dmitry Kabanov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,74 @@
1
+ # kaban
2
+
3
+ CLI-утилита: собирает структуру каталога и содержимое файлов в один `.md`-файл для любых нужд.
4
+
5
+ Полезно, когда нужно создать листинг для заказчика, передать проект нейронке, прочитать код с телефона или быстро окинуть взглядом структуру репозитория.
6
+
7
+ ## Установка
8
+
9
+ Нужен Node.js 18+.
10
+
11
+ ```bash
12
+ npm install -g @kabanooovd/kaban
13
+ ```
14
+
15
+ После этого команда `kaban` доступна из любого каталога.
16
+
17
+ ### Обновление
18
+
19
+ ```bash
20
+ npm install -g @kabanooovd/kaban@latest
21
+ ```
22
+
23
+ ### Удаление
24
+
25
+ ```bash
26
+ npm uninstall -g @kabanooovd/kaban
27
+ ```
28
+
29
+ ## Использование
30
+
31
+ ```bash
32
+ # Сканирует текущий каталог → kaban.md
33
+ kaban
34
+
35
+ # Сканирует ./src → kaban.md
36
+ kaban ./src
37
+
38
+ # Сканирует ./src → отчёт в DOC.md
39
+ kaban ./src -o DOC.md
40
+
41
+ # Игнорирует папки tmp и logs
42
+ kaban -i "tmp,logs"
43
+
44
+ # Только .js и .ts файлы
45
+ kaban -e js,ts
46
+
47
+ # Только структура, без содержимого файлов
48
+ kaban --no-content
49
+
50
+ # Справка
51
+ kaban -h
52
+ ```
53
+
54
+ ## По умолчанию
55
+
56
+ - Игнорируются: `.git`, `node_modules`, `dist`, `__pycache__`, `.venv`, lock-файлы и другие типовые артефакты.
57
+ - Файлы больше 512 КБ не включаются в отчёт.
58
+ - Бинарные файлы пропускаются.
59
+ - Выходной файл: `kaban.md`.
60
+
61
+ ## Разработка
62
+
63
+ ```bash
64
+ git clone https://gitverse.ru/kabanooovd/kaban.git
65
+ cd kaban
66
+ npm install
67
+ npm link
68
+ ```
69
+
70
+ После `npm link` команда `kaban` будет указывать на локальный код. Изменения в `src/` вступают в силу после `npm run build`.
71
+
72
+ ## Лицензия
73
+
74
+ MIT
package/dist/args.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import type { ParsedArgs } from "./types.js";
2
+ export declare const DEFAULT_IGNORES: readonly string[];
3
+ export declare const HELP = "\nkaban \u2014 \u0433\u0435\u043D\u0435\u0440\u0430\u0442\u043E\u0440 Markdown-\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 \u0438\u0437 \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u044B \u043A\u0430\u0442\u0430\u043B\u043E\u0433\u0430\n\n\u0418\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435:\n kaban [\u043E\u043F\u0446\u0438\u0438] [\u043F\u0443\u0442\u044C]\n\n\u0410\u0440\u0433\u0443\u043C\u0435\u043D\u0442\u044B:\n \u043F\u0443\u0442\u044C \u041A\u0430\u0442\u0430\u043B\u043E\u0433 \u0434\u043B\u044F \u0441\u043A\u0430\u043D\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F (\u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E: \u0442\u0435\u043A\u0443\u0449\u0438\u0439)\n\n\u041E\u043F\u0446\u0438\u0438:\n -o, --output <file> \u0418\u043C\u044F \u0432\u044B\u0445\u043E\u0434\u043D\u043E\u0433\u043E \u0444\u0430\u0439\u043B\u0430 (\u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E: kaban.md)\n -i, --ignore <names> \u0421\u043F\u0438\u0441\u043E\u043A \u0438\u0433\u043D\u043E\u0440\u0438\u0440\u0443\u0435\u043C\u044B\u0445 \u0438\u043C\u0451\u043D \u0447\u0435\u0440\u0435\u0437 \u0437\u0430\u043F\u044F\u0442\u0443\u044E\n -e, --ext <exts> \u0412\u043A\u043B\u044E\u0447\u0430\u0442\u044C \u0442\u043E\u043B\u044C\u043A\u043E \u0444\u0430\u0439\u043B\u044B \u0441 \u0443\u043A\u0430\u0437\u0430\u043D\u043D\u044B\u043C\u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F\u043C\u0438\n -m, --max-size <kb> \u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u044B\u0439 \u0440\u0430\u0437\u043C\u0435\u0440 \u0444\u0430\u0439\u043B\u0430 \u0432 \u041A\u0411 (\u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E: 512)\n --no-content \u041D\u0435 \u0432\u043A\u043B\u044E\u0447\u0430\u0442\u044C \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u043C\u043E\u0435 \u0444\u0430\u0439\u043B\u043E\u0432\n --no-default-ignore \u041D\u0435 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C \u0432\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u044B\u0439 \u0441\u043F\u0438\u0441\u043E\u043A \u0438\u0433\u043D\u043E\u0440\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F\n -h, --help \u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u044D\u0442\u0443 \u0441\u043F\u0440\u0430\u0432\u043A\u0443\n -v, --version \u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0432\u0435\u0440\u0441\u0438\u044E\n\n\u041F\u0440\u0438\u043C\u0435\u0440\u044B:\n kaban\n kaban ./src -o DOC.md\n kaban -i \"tmp,logs,.env\"\n";
4
+ export declare function parseArguments(argv: string[]): ParsedArgs;
package/dist/args.js ADDED
@@ -0,0 +1,153 @@
1
+ export const DEFAULT_IGNORES = [
2
+ '.git',
3
+ '.svn',
4
+ '.hg',
5
+ '.DS_Store',
6
+ 'Thumbs.db',
7
+ '.idea',
8
+ '.vscode',
9
+ '.vs',
10
+ 'node_modules',
11
+ 'dist',
12
+ 'build',
13
+ 'out',
14
+ 'coverage',
15
+ '.next',
16
+ '.nuxt',
17
+ '.svelte-kit',
18
+ '.turbo',
19
+ '.parcel-cache',
20
+ '.cache',
21
+ '__pycache__',
22
+ '.pytest_cache',
23
+ '.mypy_cache',
24
+ '.ruff_cache',
25
+ '.tox',
26
+ '.venv',
27
+ 'venv',
28
+ 'env',
29
+ '.eggs',
30
+ 'target',
31
+ '.gradle',
32
+ '.mvn',
33
+ 'vendor',
34
+ '.go-build',
35
+ 'obj',
36
+ 'tmp',
37
+ 'temp',
38
+ '.tmp',
39
+ 'package-lock.json',
40
+ 'yarn.lock',
41
+ 'pnpm-lock.yaml',
42
+ 'composer.lock',
43
+ 'Gemfile.lock',
44
+ 'poetry.lock',
45
+ ];
46
+ export const HELP = `
47
+ kaban — генератор Markdown-документа из структуры каталога
48
+
49
+ Использование:
50
+ kaban [опции] [путь]
51
+
52
+ Аргументы:
53
+ путь Каталог для сканирования (по умолчанию: текущий)
54
+
55
+ Опции:
56
+ -o, --output <file> Имя выходного файла (по умолчанию: kaban.md)
57
+ -i, --ignore <names> Список игнорируемых имён через запятую
58
+ -e, --ext <exts> Включать только файлы с указанными расширениями
59
+ -m, --max-size <kb> Максимальный размер файла в КБ (по умолчанию: 512)
60
+ --no-content Не включать содержимое файлов
61
+ --no-default-ignore Не использовать встроенный список игнорирования
62
+ -h, --help Показать эту справку
63
+ -v, --version Показать версию
64
+
65
+ Примеры:
66
+ kaban
67
+ kaban ./src -o DOC.md
68
+ kaban -i "tmp,logs,.env"
69
+ `;
70
+ export function parseArguments(argv) {
71
+ const opts = {
72
+ target: process.cwd(),
73
+ output: 'kaban.md',
74
+ ignore: [],
75
+ extensions: null,
76
+ maxSizeKb: 512,
77
+ useDefaultIgnore: true,
78
+ includeContent: true,
79
+ help: false,
80
+ version: false,
81
+ };
82
+ let targetSet = false;
83
+ for (let i = 0; i < argv.length; i++) {
84
+ const arg = argv[i];
85
+ if (arg === '-o' || arg === '--output') {
86
+ const value = argv[i + 1];
87
+ if (value === undefined)
88
+ throw new Error(`Флаг ${arg} требует значения`);
89
+ opts.output = value;
90
+ i++;
91
+ continue;
92
+ }
93
+ if (arg === '-i' || arg === '--ignore') {
94
+ const value = argv[i + 1];
95
+ if (value === undefined)
96
+ throw new Error(`Флаг ${arg} требует значения`);
97
+ const items = value.split(',').map((s) => s.trim()).filter(Boolean);
98
+ opts.ignore.push(...items);
99
+ i++;
100
+ continue;
101
+ }
102
+ if (arg === '-e' || arg === '--ext') {
103
+ const value = argv[i + 1];
104
+ if (value === undefined)
105
+ throw new Error(`Флаг ${arg} требует значения`);
106
+ const items = value
107
+ .split(',')
108
+ .map((s) => s.trim().replace(/^\./, '').toLowerCase())
109
+ .filter(Boolean);
110
+ opts.extensions = items;
111
+ i++;
112
+ continue;
113
+ }
114
+ if (arg === '-m' || arg === '--max-size') {
115
+ const value = argv[i + 1];
116
+ if (value === undefined)
117
+ throw new Error(`Флаг ${arg} требует значения`);
118
+ const num = Number(value);
119
+ if (!Number.isFinite(num) || num <= 0) {
120
+ throw new Error(`Некорректное значение для ${arg}: ${value}`);
121
+ }
122
+ opts.maxSizeKb = num;
123
+ i++;
124
+ continue;
125
+ }
126
+ if (arg === '-h' || arg === '--help') {
127
+ opts.help = true;
128
+ continue;
129
+ }
130
+ if (arg === '-v' || arg === '--version') {
131
+ opts.version = true;
132
+ continue;
133
+ }
134
+ if (arg === '--no-content') {
135
+ opts.includeContent = false;
136
+ continue;
137
+ }
138
+ if (arg === '--no-default-ignore') {
139
+ opts.useDefaultIgnore = false;
140
+ continue;
141
+ }
142
+ if (arg.startsWith('-')) {
143
+ throw new Error(`Неизвестный флаг: ${arg}`);
144
+ }
145
+ if (!targetSet) {
146
+ opts.target = arg;
147
+ targetSet = true;
148
+ continue;
149
+ }
150
+ }
151
+ return opts;
152
+ }
153
+ //# sourceMappingURL=args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ import { run } from '../index.js';
3
+ run(process.argv.slice(2)).catch((err) => {
4
+ const msg = err instanceof Error ? err.message : String(err);
5
+ console.error('❌ Ошибка:', msg);
6
+ process.exit(1);
7
+ });
8
+ //# sourceMappingURL=kaban.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kaban.js","sourceRoot":"","sources":["../../src/bin/kaban.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAElC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IAChD,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC7D,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;IAChC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function run(argv: string[]): Promise<void>;
package/dist/index.js ADDED
@@ -0,0 +1,37 @@
1
+ import fs from 'node:fs/promises';
2
+ import { DEFAULT_IGNORES, HELP, parseArguments } from './args.js';
3
+ import path from 'node:path';
4
+ import { buildTree } from './tree.js';
5
+ import { renderMarkdown } from './render.js';
6
+ export async function run(argv) {
7
+ const opts = parseArguments(argv);
8
+ if (opts.help) {
9
+ console.log(HELP);
10
+ return;
11
+ }
12
+ if (opts.version) {
13
+ const pkg = JSON.parse(await fs.readFile(new URL('../package.json', import.meta.url), 'utf8'));
14
+ console.log(pkg.version);
15
+ return;
16
+ }
17
+ const targetAbs = path.resolve(opts.target);
18
+ const ignoreSet = new Set();
19
+ if (opts.useDefaultIgnore) {
20
+ for (const name of DEFAULT_IGNORES)
21
+ ignoreSet.add(name);
22
+ }
23
+ for (const name of opts.ignore)
24
+ ignoreSet.add(name);
25
+ ignoreSet.add(path.basename(opts.output));
26
+ const tree = await buildTree(targetAbs, {
27
+ ignore: ignoreSet,
28
+ extensions: opts.extensions,
29
+ maxSizeKb: opts.maxSizeKb,
30
+ includeContent: opts.includeContent,
31
+ });
32
+ const md = renderMarkdown(tree, { rootName: path.basename(targetAbs) });
33
+ const outPath = path.resolve(opts.output);
34
+ await fs.writeFile(outPath, md, 'utf8');
35
+ console.log(`Файл успешно создан: ${outPath}`);
36
+ }
37
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,IAAc;IACtC,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,CAAA;IAEjC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClB,OAAO;IACT,CAAC;IAED,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACpB,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAChD,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACzB,OAAO;IACT,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAE5C,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IACpC,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC1B,KAAK,MAAM,IAAI,IAAI,eAAe;YAAE,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC1D,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM;QAAE,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAEpD,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAE1C,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,SAAS,EAAE;QACtC,MAAM,EAAE,SAAS;QACjB,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,cAAc,EAAE,IAAI,CAAC,cAAc;KACpC,CAAC,CAAC;IAEH,MAAM,EAAE,GAAG,cAAc,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACxE,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,wBAAwB,OAAO,EAAE,CAAC,CAAC;AACjD,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { DirNode, RenderOptions } from "./types.js";
2
+ export declare function renderMarkdown(tree: DirNode, opts: RenderOptions): string;
package/dist/render.js ADDED
@@ -0,0 +1,22 @@
1
+ import { renderContents, renderTree } from "./utils/index.js";
2
+ export function renderMarkdown(tree, opts) {
3
+ const lines = [];
4
+ lines.push(`# ${opts.rootName}`);
5
+ lines.push('');
6
+ lines.push(`> Сгенерировано утилитой **kaban**`);
7
+ lines.push('');
8
+ // Секция структуры
9
+ lines.push('## Структура');
10
+ lines.push('');
11
+ lines.push('```');
12
+ lines.push(opts.rootName + '/');
13
+ renderTree(tree, '', lines);
14
+ lines.push('```');
15
+ lines.push('');
16
+ // Секция содержимого
17
+ lines.push('## Содержимое файлов');
18
+ lines.push('');
19
+ renderContents(tree, lines);
20
+ return lines.join('\n');
21
+ }
22
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9D,MAAM,UAAU,cAAc,CAAC,IAAa,EAAE,IAAmB;IAC/D,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IACjC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;IACjD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,mBAAmB;IACnB,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAC,CAAC;IAChC,UAAU,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;IAC5B,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,qBAAqB;IACrB,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IACnC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAE5B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
package/dist/tree.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import { type BuildTreeOptions, type DirNode } from './types.js';
2
+ export declare function buildTree(rootAbs: string, opts: BuildTreeOptions): Promise<DirNode>;
package/dist/tree.js ADDED
@@ -0,0 +1,70 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { isBinary, stripBom } from './utils/index.js';
4
+ export async function buildTree(rootAbs, opts) {
5
+ const rootName = path.basename(rootAbs);
6
+ const root = { type: 'dir', name: rootName, relPath: '', children: [] };
7
+ await walk(rootAbs, root, '', opts);
8
+ return root;
9
+ }
10
+ async function walk(dirAbs, parentNode, relPath, opts) {
11
+ const entries = await fs.readdir(dirAbs, { withFileTypes: true });
12
+ for (const entry of entries) {
13
+ if (opts.ignore.has(entry.name))
14
+ continue;
15
+ const childRelPath = relPath ? `${relPath}/${entry.name}` : entry.name;
16
+ const childAbs = path.join(dirAbs, entry.name);
17
+ if (entry.isDirectory()) {
18
+ // Каталог — создаём узел, потом заходим внутрь рекурсивно
19
+ const dirNode = {
20
+ type: 'dir',
21
+ name: entry.name,
22
+ relPath: childRelPath,
23
+ children: [],
24
+ };
25
+ parentNode.children.push(dirNode);
26
+ await walk(childAbs, dirNode, childRelPath, opts);
27
+ }
28
+ else if (entry.isFile()) {
29
+ if (opts.extensions !== null) {
30
+ const ext = path.extname(entry.name).slice(1).toLowerCase();
31
+ if (!opts.extensions.includes(ext))
32
+ continue;
33
+ }
34
+ const stat = await fs.stat(childAbs);
35
+ const fileNode = {
36
+ type: 'file',
37
+ name: entry.name,
38
+ relPath: childRelPath,
39
+ size: stat.size,
40
+ content: null,
41
+ skipped: false,
42
+ };
43
+ if (opts.includeContent) {
44
+ const maxBytes = opts.maxSizeKb * 1024;
45
+ if (stat.size > maxBytes) {
46
+ fileNode.skipped = true;
47
+ fileNode.skipReason = `too large (${stat.size} > ${maxBytes} bytes)`;
48
+ }
49
+ else {
50
+ try {
51
+ const buf = await fs.readFile(childAbs);
52
+ if (isBinary(buf)) {
53
+ fileNode.skipped = true;
54
+ fileNode.skipReason = 'binary';
55
+ }
56
+ else {
57
+ fileNode.content = stripBom(buf.toString('utf8'));
58
+ }
59
+ }
60
+ catch (err) {
61
+ fileNode.skipped = true;
62
+ fileNode.skipReason = 'read error';
63
+ }
64
+ }
65
+ }
66
+ parentNode.children.push(fileNode);
67
+ }
68
+ }
69
+ }
70
+ //# sourceMappingURL=tree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree.js","sourceRoot":"","sources":["../src/tree.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ export interface ParsedArgs {
2
+ target: string;
3
+ output: string;
4
+ ignore: string[];
5
+ extensions: string[] | null;
6
+ maxSizeKb: number;
7
+ useDefaultIgnore: boolean;
8
+ includeContent: boolean;
9
+ help: boolean;
10
+ version: boolean;
11
+ }
12
+ export interface DirNode {
13
+ type: 'dir';
14
+ name: string;
15
+ relPath: string;
16
+ children: TreeNode[];
17
+ }
18
+ export interface FileNode {
19
+ type: 'file';
20
+ name: string;
21
+ relPath: string;
22
+ size: number;
23
+ content: string | null;
24
+ skipped: boolean;
25
+ skipReason?: string;
26
+ }
27
+ export type TreeNode = DirNode | FileNode;
28
+ export interface BuildTreeOptions {
29
+ ignore: Set<string>;
30
+ extensions: string[] | null;
31
+ maxSizeKb: number;
32
+ includeContent: boolean;
33
+ }
34
+ export interface RenderOptions {
35
+ rootName: string;
36
+ }
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ export declare function getLanguage(fileName: string): string;
@@ -0,0 +1,34 @@
1
+ export function getLanguage(fileName) {
2
+ const ext = fileName.split('.').pop()?.toLowerCase() ?? '';
3
+ const map = {
4
+ js: 'js',
5
+ mjs: 'js',
6
+ cjs: 'js',
7
+ ts: 'ts',
8
+ tsx: 'tsx',
9
+ jsx: 'jsx',
10
+ json: 'json',
11
+ md: 'md',
12
+ html: 'html',
13
+ css: 'css',
14
+ scss: 'scss',
15
+ py: 'python',
16
+ rb: 'ruby',
17
+ go: 'go',
18
+ rs: 'rust',
19
+ java: 'java',
20
+ kt: 'kotlin',
21
+ cs: 'csharp',
22
+ php: 'php',
23
+ sh: 'bash',
24
+ bash: 'bash',
25
+ zsh: 'bash',
26
+ yml: 'yaml',
27
+ yaml: 'yaml',
28
+ toml: 'toml',
29
+ xml: 'xml',
30
+ sql: 'sql',
31
+ };
32
+ return map[ext] ?? '';
33
+ }
34
+ //# sourceMappingURL=getLanguage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getLanguage.js","sourceRoot":"","sources":["../../src/utils/getLanguage.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW,CAAC,QAAgB;IAC1C,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IAC3D,MAAM,GAAG,GAA2B;QAClC,EAAE,EAAE,IAAI;QACR,GAAG,EAAE,IAAI;QACT,GAAG,EAAE,IAAI;QACT,EAAE,EAAE,IAAI;QACR,GAAG,EAAE,KAAK;QACV,GAAG,EAAE,KAAK;QACV,IAAI,EAAE,MAAM;QACZ,EAAE,EAAE,IAAI;QACR,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE,KAAK;QACV,IAAI,EAAE,MAAM;QACZ,EAAE,EAAE,QAAQ;QACZ,EAAE,EAAE,MAAM;QACV,EAAE,EAAE,IAAI;QACR,EAAE,EAAE,MAAM;QACV,IAAI,EAAE,MAAM;QACZ,EAAE,EAAE,QAAQ;QACZ,EAAE,EAAE,QAAQ;QACZ,GAAG,EAAE,KAAK;QACV,EAAE,EAAE,MAAM;QACV,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE,MAAM;QACX,GAAG,EAAE,MAAM;QACX,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE,KAAK;QACV,GAAG,EAAE,KAAK;KACX,CAAC;IACF,OAAO,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;AACxB,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { renderContents } from './renderContents.js';
2
+ export { getLanguage } from './getLanguage.js';
3
+ export { renderTree } from './renderTree.js';
4
+ export { isBinary } from './isBinary.js';
5
+ export { stripBom } from './stripBom.js';
@@ -0,0 +1,6 @@
1
+ export { renderContents } from './renderContents.js';
2
+ export { getLanguage } from './getLanguage.js';
3
+ export { renderTree } from './renderTree.js';
4
+ export { isBinary } from './isBinary.js';
5
+ export { stripBom } from './stripBom.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA"}
@@ -0,0 +1 @@
1
+ export declare function isBinary(buf: Buffer): boolean;
@@ -0,0 +1,9 @@
1
+ export function isBinary(buf) {
2
+ const len = Math.min(buf.length, 1024);
3
+ for (let i = 0; i < len; i++) {
4
+ if (buf[i] === 0)
5
+ return true;
6
+ }
7
+ return false;
8
+ }
9
+ //# sourceMappingURL=isBinary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isBinary.js","sourceRoot":"","sources":["../../src/utils/isBinary.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,QAAQ,CAAC,GAAW;IAClC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7B,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;IAChC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { DirNode } from "../types.js";
2
+ export declare function renderContents(node: DirNode, lines: string[]): void;
@@ -0,0 +1,24 @@
1
+ import { getLanguage } from "./getLanguage.js";
2
+ export function renderContents(node, lines) {
3
+ for (const child of node.children) {
4
+ if (child.type === 'dir') {
5
+ renderContents(child, lines);
6
+ }
7
+ else if (child.content !== null) {
8
+ const lang = getLanguage(child.name);
9
+ lines.push(`### \`${child.relPath}\``);
10
+ lines.push('');
11
+ lines.push('```' + lang);
12
+ lines.push(child.content.replace(/\s+$/, ''));
13
+ lines.push('```');
14
+ lines.push('');
15
+ }
16
+ else if (child.skipped) {
17
+ lines.push(`### \`${child.relPath}\``);
18
+ lines.push('');
19
+ lines.push(`_Не включено: ${child.skipReason}._`);
20
+ lines.push('');
21
+ }
22
+ }
23
+ }
24
+ //# sourceMappingURL=renderContents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderContents.js","sourceRoot":"","sources":["../../src/utils/renderContents.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,MAAM,UAAU,cAAc,CAAC,IAAa,EAAE,KAAe;IAC3D,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClC,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YACzB,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC/B,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YAClC,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACrC,KAAK,CAAC,IAAI,CAAC,SAAS,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;YACvC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;YACzB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;YAC9C,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAClB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YACzB,KAAK,CAAC,IAAI,CAAC,SAAS,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;YACvC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,iBAAiB,KAAK,CAAC,UAAU,IAAI,CAAC,CAAC;YAClD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { type DirNode } from "../types.js";
2
+ export declare function renderTree(node: DirNode, prefix: string, lines: string[]): void;
@@ -0,0 +1,15 @@
1
+ export function renderTree(node, prefix, lines) {
2
+ const children = node.children;
3
+ const lastIndex = children.length - 1;
4
+ children.forEach((child, idx) => {
5
+ const isLast = idx === lastIndex;
6
+ const branch = isLast ? '└── ' : '├── ';
7
+ const suffix = child.type === 'dir' ? '/' : '';
8
+ lines.push(prefix + branch + child.name + suffix);
9
+ if (child.type === 'dir') {
10
+ const childPrefix = prefix + (isLast ? ' ' : '│ ');
11
+ renderTree(child, childPrefix, lines);
12
+ }
13
+ });
14
+ }
15
+ //# sourceMappingURL=renderTree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderTree.js","sourceRoot":"","sources":["../../src/utils/renderTree.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,UAAU,CAAC,IAAa,EAAE,MAAc,EAAE,KAAe;IACvE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;IAC/B,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IAEtC,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QAC9B,MAAM,MAAM,GAAG,GAAG,KAAK,SAAS,CAAC;QACjC,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;QACxC,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAE/C,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;QAElD,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YACzB,MAAM,WAAW,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YACxD,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;QACxC,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function stripBom(str: string): string;
@@ -0,0 +1,4 @@
1
+ export function stripBom(str) {
2
+ return str.charCodeAt(0) === 0xfeff ? str.slice(1) : str;
3
+ }
4
+ //# sourceMappingURL=stripBom.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stripBom.js","sourceRoot":"","sources":["../../src/utils/stripBom.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,QAAQ,CAAC,GAAW;IAClC,OAAO,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AAC3D,CAAC"}
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "@kabanooovd/kaban",
3
+ "version": "1.0.0",
4
+ "description": "Генерирует .md файл со структурой и содержимым каталога",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "type": "module",
9
+ "bin": {
10
+ "kaban": "./dist/bin/kaban.js"
11
+ },
12
+ "files": [
13
+ "dist"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsc",
17
+ "dev": "tsc --watch",
18
+ "prepare": "tsc"
19
+ },
20
+ "engines": {
21
+ "node": ">=18"
22
+ },
23
+ "devDependencies": {
24
+ "@types/node": "^22.0.0",
25
+ "typescript": "^5.6.0"
26
+ },
27
+ "license": "MIT"
28
+ }