@boristype/bt-cli 0.1.0-alpha.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.
Files changed (116) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +66 -0
  3. package/build/builder/config.js +88 -0
  4. package/build/cli/commands/artifact.js +14 -0
  5. package/build/cli/commands/build.js +25 -0
  6. package/build/cli/commands/dev.js +190 -0
  7. package/build/cli/commands/index.js +18 -0
  8. package/build/cli/commands/init.js +15 -0
  9. package/build/cli/commands/link.js +18 -0
  10. package/build/cli/commands/push.js +28 -0
  11. package/build/cli/index.js +14 -0
  12. package/build/cli/types.js +2 -0
  13. package/build/core/artifacting/context.js +54 -0
  14. package/build/core/artifacting/index.js +37 -0
  15. package/build/core/artifacting/stages/index.js +10 -0
  16. package/build/core/artifacting/stages/main-archive.js +72 -0
  17. package/build/core/artifacting/stages/validate.js +70 -0
  18. package/build/core/artifacting/types.js +6 -0
  19. package/build/core/artifacting/utils/index.js +10 -0
  20. package/build/core/artifacting/utils/zip.js +94 -0
  21. package/build/core/babel.js +96 -0
  22. package/build/core/btconfig.types.js +6 -0
  23. package/build/core/build.js +280 -0
  24. package/build/core/building/compile-mode.js +146 -0
  25. package/build/core/building/compiler.js +281 -0
  26. package/build/core/building/coordinator.js +71 -0
  27. package/build/core/building/files.js +290 -0
  28. package/build/core/building/index.js +102 -0
  29. package/build/core/building/output.js +92 -0
  30. package/build/core/building/transformers.js +110 -0
  31. package/build/core/building/types.js +19 -0
  32. package/build/core/config.js +157 -0
  33. package/build/core/dependencies.js +223 -0
  34. package/build/core/linking/cache.js +260 -0
  35. package/build/core/linking/context.js +149 -0
  36. package/build/core/linking/dependencies.js +240 -0
  37. package/build/core/linking/executables.js +61 -0
  38. package/build/core/linking/generators/api-ext.js +57 -0
  39. package/build/core/linking/generators/component.js +83 -0
  40. package/build/core/linking/generators/filemap.js +53 -0
  41. package/build/core/linking/generators/index.js +21 -0
  42. package/build/core/linking/generators/init-xml.js +37 -0
  43. package/build/core/linking/generators/package-json.js +50 -0
  44. package/build/core/linking/index.js +213 -0
  45. package/build/core/linking/linkers/component.js +175 -0
  46. package/build/core/linking/linkers/index.js +69 -0
  47. package/build/core/linking/linkers/standalone.js +144 -0
  48. package/build/core/linking/linkers/system.js +86 -0
  49. package/build/core/linking/parsers.js +278 -0
  50. package/build/core/linking/types.js +6 -0
  51. package/build/core/linking/utils/copy.js +101 -0
  52. package/build/core/linking/utils/index.js +26 -0
  53. package/build/core/linking/utils/node-modules.js +226 -0
  54. package/build/core/linking/utils/package-type.js +101 -0
  55. package/build/core/linking/utils/url.js +73 -0
  56. package/build/core/linking/utils/write.js +91 -0
  57. package/build/core/logger.js +10 -0
  58. package/build/core/pushing/config.js +90 -0
  59. package/build/core/pushing/index.js +96 -0
  60. package/build/core/pushing/init-scripts.js +173 -0
  61. package/build/core/pushing/queue.js +95 -0
  62. package/build/core/pushing/reinit.js +61 -0
  63. package/build/core/pushing/session.js +167 -0
  64. package/build/core/pushing/types.js +6 -0
  65. package/build/core/pushing/upload.js +35 -0
  66. package/build/core/tsconfig.js +78 -0
  67. package/build/core/utils/index.js +17 -0
  68. package/build/core/utils/logger.js +46 -0
  69. package/build/core/utils/properties.js +81 -0
  70. package/build/core/utils/xml.js +44 -0
  71. package/build/core/utils.js +59 -0
  72. package/build/index.js +76 -0
  73. package/build/plugins/destructuring.js +83 -0
  74. package/build/plugins/forOfToForIn.js +14 -0
  75. package/build/plugins/loopHoistVariables.js +160 -0
  76. package/build/plugins/precedence.js +172 -0
  77. package/build/plugins/removeImportExport.js +42 -0
  78. package/build/plugins/replaceDollar.js +16 -0
  79. package/build/plugins/spreadArray.js +42 -0
  80. package/build/plugins/spreadObject.js +91 -0
  81. package/build/transformers/arrayFunctional.js +467 -0
  82. package/build/transformers/arrayGeneral.js +222 -0
  83. package/build/transformers/blockScoping.js +212 -0
  84. package/build/transformers/destructuring.js +133 -0
  85. package/build/transformers/dirname.js +79 -0
  86. package/build/transformers/enumsToObjects.js +25 -0
  87. package/build/transformers/execObj.js +220 -0
  88. package/build/transformers/forOfToForIn.js +45 -0
  89. package/build/transformers/funcSemantic.js +113 -0
  90. package/build/transformers/functions.js +270 -0
  91. package/build/transformers/globalCache.js +34 -0
  92. package/build/transformers/loopHoistVariables.js +352 -0
  93. package/build/transformers/math.js +39 -0
  94. package/build/transformers/namespaces.js +22 -0
  95. package/build/transformers/numericSeparator.js +46 -0
  96. package/build/transformers/objectProperties.js +54 -0
  97. package/build/transformers/precedence.js +192 -0
  98. package/build/transformers/propSemantic.js +467 -0
  99. package/build/transformers/remodule.js +620 -0
  100. package/build/transformers/removeImportExport.js +135 -0
  101. package/build/transformers/replaceDollar.js +46 -0
  102. package/build/transformers/shorthandProperties.js +34 -0
  103. package/build/transformers/spreadArray.js +68 -0
  104. package/build/transformers/spreadObject.js +134 -0
  105. package/build/transformers/string.js +138 -0
  106. package/build/transformers/templateLiterals.js +104 -0
  107. package/build/transformers/tocodelibrary.js +178 -0
  108. package/build/transformers/utils.js +202 -0
  109. package/build/wshcm/client.js +193 -0
  110. package/build/wshcm/evaluator.js +111 -0
  111. package/build/wshcm/exceptions.js +25 -0
  112. package/build/wshcm/index.js +20 -0
  113. package/build/wshcm/soap-utils.js +228 -0
  114. package/build/wshcm/types.js +2 -0
  115. package/build/wshcm/uploader.js +320 -0
  116. package/package.json +51 -0
@@ -0,0 +1,157 @@
1
+ "use strict";
2
+ /**
3
+ * Конфигурация проекта — tsconfig.json и btconfig.json
4
+ *
5
+ * Единый модуль для чтения, парсинга и генерации конфигурационных файлов.
6
+ * Также содержит типы для btconfig.json.
7
+ *
8
+ * @module core/config
9
+ */
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
22
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
23
+ }) : function(o, v) {
24
+ o["default"] = v;
25
+ });
26
+ var __importStar = (this && this.__importStar) || (function () {
27
+ var ownKeys = function(o) {
28
+ ownKeys = Object.getOwnPropertyNames || function (o) {
29
+ var ar = [];
30
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
31
+ return ar;
32
+ };
33
+ return ownKeys(o);
34
+ };
35
+ return function (mod) {
36
+ if (mod && mod.__esModule) return mod;
37
+ var result = {};
38
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
39
+ __setModuleDefault(result, mod);
40
+ return result;
41
+ };
42
+ })();
43
+ var __importDefault = (this && this.__importDefault) || function (mod) {
44
+ return (mod && mod.__esModule) ? mod : { "default": mod };
45
+ };
46
+ Object.defineProperty(exports, "__esModule", { value: true });
47
+ exports.getTSConfig = getTSConfig;
48
+ exports.generateDefaultTSConfig = generateDefaultTSConfig;
49
+ exports.getBTConfig = getBTConfig;
50
+ const typescript_1 = __importDefault(require("typescript"));
51
+ const fs = __importStar(require("node:fs"));
52
+ const path = __importStar(require("node:path"));
53
+ const logger_js_1 = require("./utils/logger.js");
54
+ // ─── tsconfig.json ──────────────────────────────────────────────
55
+ /**
56
+ * Читает и парсит tsconfig.json.
57
+ *
58
+ * @param cwd - Рабочая директория для поиска tsconfig
59
+ * @param project - Имя файла конфигурации (по умолчанию tsconfig.json)
60
+ * @returns Распарсенная конфигурация TypeScript
61
+ */
62
+ function getTSConfig(cwd, project = 'tsconfig.json') {
63
+ const tsconfigPath = typescript_1.default.findConfigFile(cwd, typescript_1.default.sys.fileExists, project);
64
+ if (!tsconfigPath) {
65
+ logger_js_1.logger.error(`There is no any configuration files at "${cwd}". Execute npx tsc -init to create a new one.`);
66
+ process.exit(1);
67
+ }
68
+ const { config, error } = typescript_1.default.readConfigFile(tsconfigPath, typescript_1.default.sys.readFile);
69
+ if (error) {
70
+ logger_js_1.logger.error(error.messageText.toString());
71
+ process.exit(1);
72
+ }
73
+ // Используем директорию tsconfig.json как базу для резолва путей
74
+ const configDir = path.dirname(tsconfigPath);
75
+ const configFileContent = typescript_1.default.parseJsonConfigFileContent(config, typescript_1.default.sys, configDir);
76
+ if (configFileContent.errors.length > 0) {
77
+ configFileContent.errors.forEach(diagnostic => {
78
+ logger_js_1.logger.error(diagnostic.messageText.toString());
79
+ });
80
+ process.exit(1);
81
+ }
82
+ return configFileContent;
83
+ }
84
+ /**
85
+ * Генерирует tsconfig.json с дефолтными настройками для BorisType проекта.
86
+ *
87
+ * @param cwd - Рабочая директория (по умолчанию process.cwd())
88
+ * @returns true если файл создан, false если уже существует
89
+ */
90
+ function generateDefaultTSConfig(cwd = process.cwd()) {
91
+ const tsconfigContent = `{
92
+ "compilerOptions": {
93
+ "target": "esnext",
94
+ "module": "esnext",
95
+ "moduleResolution": "Bundler",
96
+ "rootDir": "./src/",
97
+ "outDir": "./build/",
98
+ "strict": true,
99
+ "noImplicitAny": true,
100
+ "allowJs": true,
101
+ "strictNullChecks": true,
102
+ "strictFunctionTypes": true,
103
+ "strictBindCallApply": true,
104
+ "noImplicitThis": true,
105
+ "alwaysStrict": true,
106
+ "noLib": true,
107
+ "typeRoots": [
108
+ "node_modules/@boristype/types/lib",
109
+ "node_modules/@boristype/types/lib/xml"
110
+ ]
111
+ },
112
+ "include": [
113
+ "src/**/*"
114
+ ],
115
+ "exclude": [
116
+ "node_modules"
117
+ ]
118
+ }
119
+ `;
120
+ const tsconfigPath = path.join(cwd, 'tsconfig.json');
121
+ if (fs.existsSync(tsconfigPath)) {
122
+ logger_js_1.logger.warning('⚠️ tsconfig.json already exists. Skipping generation.');
123
+ return false;
124
+ }
125
+ try {
126
+ fs.writeFileSync(tsconfigPath, tsconfigContent, 'utf8');
127
+ logger_js_1.logger.success('Created a new tsconfig.json');
128
+ return true;
129
+ }
130
+ catch (error) {
131
+ logger_js_1.logger.error('❌ Failed to create tsconfig.json');
132
+ throw error;
133
+ }
134
+ }
135
+ // ─── btconfig.json ──────────────────────────────────────────────
136
+ /**
137
+ * Читает и парсит btconfig.json.
138
+ *
139
+ * @param cwd - Рабочая директория
140
+ * @param project - Имя файла конфигурации (по умолчанию btconfig.json)
141
+ * @returns Объект конфигурации BtConfig или undefined если файл не найден
142
+ */
143
+ function getBTConfig(cwd, project = 'btconfig.json') {
144
+ const btconfigPath = path.join(cwd, project);
145
+ if (!fs.existsSync(btconfigPath)) {
146
+ return undefined;
147
+ }
148
+ try {
149
+ const configContent = fs.readFileSync(btconfigPath, 'utf-8');
150
+ const config = JSON.parse(configContent);
151
+ return config;
152
+ }
153
+ catch (error) {
154
+ logger_js_1.logger.error(`Error reading or parsing ${project}: ${error}`);
155
+ process.exit(1);
156
+ }
157
+ }
@@ -0,0 +1,223 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.DependencyNode = void 0;
37
+ exports.getCompilerRequiredDependencies = getCompilerRequiredDependencies;
38
+ exports.buildDependencyTree = buildDependencyTree;
39
+ exports.flattenDependencyTreeIterative = flattenDependencyTreeIterative;
40
+ exports.printDependencyTree = printDependencyTree;
41
+ exports.printFlattenedTree = printFlattenedTree;
42
+ exports.extractBorisTypeDependencies = extractBorisTypeDependencies;
43
+ const fs_1 = require("fs");
44
+ const path = __importStar(require("path"));
45
+ const crypto_1 = require("crypto");
46
+ // Класс для узла дерева зависимостей
47
+ class DependencyNode {
48
+ packageJson;
49
+ constructor(packageJson, projectPath = '') {
50
+ this.packageJson = packageJson;
51
+ this.name = packageJson.name;
52
+ this.version = packageJson.version;
53
+ this.dependencies = [];
54
+ this.projectPath = projectPath;
55
+ this.hash = (0, crypto_1.randomUUID)();
56
+ }
57
+ name;
58
+ version;
59
+ dependencies;
60
+ projectPath;
61
+ hash;
62
+ }
63
+ exports.DependencyNode = DependencyNode;
64
+ async function getCompilerRequiredDependencies(projectPath) {
65
+ const rootPackageJsonPath = path.join(projectPath, 'package.json');
66
+ const nodeModulesPath = path.join(projectPath, 'node_modules');
67
+ const rootPackageJson = JSON.parse(await fs_1.promises.readFile(rootPackageJsonPath, 'utf-8'));
68
+ const devDependencies = rootPackageJson.devDependencies || {};
69
+ const btcRemoteDependency = devDependencies['@boristype/btc'] !== undefined;
70
+ const btcLocalDependency = devDependencies['btc'] !== undefined;
71
+ if (!btcLocalDependency && !btcRemoteDependency) {
72
+ console.warn(`Предупреждение: В devDependencies отсутствует зависимость 'btc'.`);
73
+ return [];
74
+ }
75
+ const btcPath = btcRemoteDependency ? path.join(nodeModulesPath, '@boristype', 'btc') : path.join(nodeModulesPath, 'btc');
76
+ const btcPackageJsonPath = path.join(btcPath, 'package.json');
77
+ const btcPackageJson = JSON.parse(await fs_1.promises.readFile(btcPackageJsonPath, 'utf-8'));
78
+ const btcDependencies = btcPackageJson.dependencies || {};
79
+ const result = [];
80
+ console.log(`Загрузка зависимостей компилятора из ${btcPath}`);
81
+ for (const [depName, depVersion] of Object.entries(btcDependencies)) {
82
+ if (depName.startsWith('@boristype/')) {
83
+ // Если btc установлен из репозитория, ищем в node_modules проекта
84
+ // Если btc установлен локально (file:...), ищем в node_modules внутри btc
85
+ const btcNodeModulesPath = btcRemoteDependency ? nodeModulesPath : path.join(btcPath, 'node_modules');
86
+ const depPath = btcRemoteDependency ? path.join(btcNodeModulesPath, '@boristype', depName.replace('@boristype/', '')) : path.join(btcNodeModulesPath, depName);
87
+ console.log(`Загрузка зависимости компилятора: ${depName} из ${depPath}`);
88
+ try {
89
+ const depPackageJsonPath = path.join(depPath, 'package.json');
90
+ const depPackageJson = JSON.parse(await fs_1.promises.readFile(depPackageJsonPath, 'utf-8'));
91
+ const depNode = new DependencyNode(depPackageJson, depPath);
92
+ result.push(depNode);
93
+ }
94
+ catch (err) {
95
+ if (err instanceof Error) {
96
+ console.warn(`Не удалось обработать зависимость ${depName}: ${err.message}`);
97
+ }
98
+ else {
99
+ console.warn(`Не удалось обработать зависимость ${depName}: ${String(err)}`);
100
+ }
101
+ }
102
+ }
103
+ }
104
+ return result;
105
+ }
106
+ async function buildDependencyTree(projectPath) {
107
+ const rootPackageJsonPath = path.join(projectPath, 'package.json');
108
+ const nodeModulesPath = path.join(projectPath, 'node_modules');
109
+ const rootPackageJson = JSON.parse(await fs_1.promises.readFile(rootPackageJsonPath, 'utf-8'));
110
+ const rootNode = new DependencyNode(rootPackageJson, projectPath);
111
+ const processedModules = new Map();
112
+ async function processDependencies(parentNode, nodeModulesDir, packageJsonPath, visited = new Set()) {
113
+ let dependencies = {};
114
+ try {
115
+ const packageJson = JSON.parse(await fs_1.promises.readFile(packageJsonPath, 'utf-8'));
116
+ dependencies = packageJson.dependencies || {};
117
+ }
118
+ catch (err) {
119
+ console.warn(`Не удалось прочитать package.json для ${parentNode.name}: ${packageJsonPath}`);
120
+ return;
121
+ }
122
+ for (const [depName, depVersion] of Object.entries(dependencies)) {
123
+ const depKey = `${depName}@${depVersion}`;
124
+ if (visited.has(depKey)) {
125
+ console.warn(`Обнаружена циклическая зависимость: ${depKey}`);
126
+ continue;
127
+ }
128
+ const depPath = path.join(nodeModulesDir, depName);
129
+ try {
130
+ const depPackageJsonPath = path.join(depPath, 'package.json');
131
+ const depPackageJson = JSON.parse(await fs_1.promises.readFile(depPackageJsonPath, 'utf-8'));
132
+ const processedKey = `${depPackageJson.name}@${depPackageJson.version}`;
133
+ let depNode;
134
+ if (processedModules.has(processedKey)) {
135
+ depNode = processedModules.get(processedKey);
136
+ }
137
+ else {
138
+ depNode = new DependencyNode(depPackageJson, depPath);
139
+ processedModules.set(processedKey, depNode);
140
+ const newVisited = new Set(visited);
141
+ newVisited.add(depKey);
142
+ await processDependencies(depNode, nodeModulesDir, depPackageJsonPath, newVisited);
143
+ }
144
+ parentNode.dependencies.push(depNode);
145
+ }
146
+ catch (err) {
147
+ if (err instanceof Error) {
148
+ console.warn(`Не удалось обработать зависимость ${depName}: ${err.message}`);
149
+ }
150
+ else {
151
+ console.warn(`Не удалось обработать зависимость ${depName}: ${String(err)}`);
152
+ }
153
+ }
154
+ }
155
+ }
156
+ await processDependencies(rootNode, nodeModulesPath, rootPackageJsonPath);
157
+ return rootNode;
158
+ }
159
+ // Альтернативная версия с итеративным подходом (более безопасная для больших деревьев)
160
+ function flattenDependencyTreeIterative(rootNode) {
161
+ const visited = new Set();
162
+ const result = [];
163
+ const stack = [];
164
+ stack.push({ node: rootNode, path: new Set() });
165
+ while (stack.length > 0) {
166
+ const { node, path } = stack.pop();
167
+ // Проверяем циклические зависимости
168
+ if (path.has(node.hash)) {
169
+ console.warn(`Обнаружена циклическая зависимость: ${node.name}@${node.version}`);
170
+ continue;
171
+ }
172
+ // Если узел уже был обработан, пропускаем
173
+ if (visited.has(node.hash)) {
174
+ continue;
175
+ }
176
+ // Проверяем, все ли зависимости уже обработаны
177
+ const unprocessedDeps = node.dependencies.filter(dep => !visited.has(dep.hash));
178
+ if (unprocessedDeps.length === 0) {
179
+ // Все зависимости обработаны - добавляем текущий узел
180
+ visited.add(node.hash);
181
+ result.push(node);
182
+ }
183
+ else {
184
+ // Есть необработанные зависимости - откладываем текущий узел и обрабатываем зависимости
185
+ stack.push({ node, path });
186
+ // Добавляем необработанные зависимости в стек
187
+ const newPath = new Set(path);
188
+ newPath.add(node.hash);
189
+ for (const dep of unprocessedDeps) {
190
+ if (!path.has(dep.hash)) { // Проверяем циклы только для новых узлов
191
+ stack.push({ node: dep, path: newPath });
192
+ }
193
+ }
194
+ }
195
+ }
196
+ return result;
197
+ }
198
+ // Функция для вывода дерева (без изменений)
199
+ function printDependencyTree(node, depth = 0) {
200
+ console.log('\n📦 Дерево зависимостей:');
201
+ function printInternal(node, depth) {
202
+ console.log('='.repeat(50));
203
+ console.log(`${' '.repeat(depth * 2)}${node.name}@${node.version} [${node.hash}]`);
204
+ for (const dep of node.dependencies) {
205
+ printInternal(dep, depth + 1);
206
+ }
207
+ }
208
+ printInternal(node, depth);
209
+ }
210
+ // Функция для вывода плоского массива
211
+ function printFlattenedTree(flatTree) {
212
+ console.log('\n📦 Плоский список зависимостей (в порядке загрузки):');
213
+ console.log('='.repeat(50));
214
+ flatTree.forEach((node, index) => {
215
+ console.log(`${(index + 1).toString().padStart(2)}. ${node.name}@${node.version} [${node.hash}]`);
216
+ });
217
+ }
218
+ function extractBorisTypeDependencies(flatTree) {
219
+ return flatTree.filter(node => {
220
+ const wsPackage = node.packageJson['ws:package']; // для libs
221
+ return typeof wsPackage === 'string';
222
+ });
223
+ }
@@ -0,0 +1,260 @@
1
+ "use strict";
2
+ /**
3
+ * Кэширование для линковки
4
+ *
5
+ * Управляет кэшем в директории .btc/ для оптимизации линковки:
6
+ * - Кэширование hash от package-lock.json для node_modules
7
+ * - Позволяет пропускать копирование если зависимости не изменились
8
+ *
9
+ * @module linking/cache
10
+ */
11
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ var desc = Object.getOwnPropertyDescriptor(m, k);
14
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
+ desc = { enumerable: true, get: function() { return m[k]; } };
16
+ }
17
+ Object.defineProperty(o, k2, desc);
18
+ }) : (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ o[k2] = m[k];
21
+ }));
22
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
24
+ }) : function(o, v) {
25
+ o["default"] = v;
26
+ });
27
+ var __importStar = (this && this.__importStar) || (function () {
28
+ var ownKeys = function(o) {
29
+ ownKeys = Object.getOwnPropertyNames || function (o) {
30
+ var ar = [];
31
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
32
+ return ar;
33
+ };
34
+ return ownKeys(o);
35
+ };
36
+ return function (mod) {
37
+ if (mod && mod.__esModule) return mod;
38
+ var result = {};
39
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
40
+ __setModuleDefault(result, mod);
41
+ return result;
42
+ };
43
+ })();
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.LinkingCache = void 0;
46
+ const fs = __importStar(require("fs"));
47
+ const path = __importStar(require("path"));
48
+ const crypto = __importStar(require("crypto"));
49
+ /** Текущая версия формата кэша */
50
+ const CACHE_VERSION = 1;
51
+ /** Имя директории кэша */
52
+ const CACHE_DIR_NAME = '.btc';
53
+ /** Имя файла состояния кэша */
54
+ const CACHE_STATE_FILE = 'linking-cache.json';
55
+ /**
56
+ * Менеджер кэша линковки
57
+ *
58
+ * @remarks
59
+ * Хранит состояние кэша в `.btc/linking-cache.json`
60
+ * Позволяет проверять нужно ли перекопировать node_modules
61
+ */
62
+ class LinkingCache {
63
+ projectPath;
64
+ cachePath;
65
+ stateFilePath;
66
+ state;
67
+ enabled;
68
+ /**
69
+ * Создаёт экземпляр менеджера кэша
70
+ *
71
+ * @param projectPath - Корневая директория проекта
72
+ * @param enabled - Включён ли кэш (false при --no-cache)
73
+ */
74
+ constructor(projectPath, enabled = true) {
75
+ this.projectPath = projectPath;
76
+ this.cachePath = path.join(projectPath, CACHE_DIR_NAME);
77
+ this.stateFilePath = path.join(this.cachePath, CACHE_STATE_FILE);
78
+ this.enabled = enabled;
79
+ this.state = this.loadState();
80
+ }
81
+ /**
82
+ * Загружает состояние кэша из файла
83
+ */
84
+ loadState() {
85
+ if (!this.enabled) {
86
+ return this.createEmptyState();
87
+ }
88
+ try {
89
+ if (fs.existsSync(this.stateFilePath)) {
90
+ const content = fs.readFileSync(this.stateFilePath, 'utf-8');
91
+ const state = JSON.parse(content);
92
+ // Проверяем версию кэша
93
+ if (state.version !== CACHE_VERSION) {
94
+ // Версия устарела - сбрасываем кэш
95
+ return this.createEmptyState();
96
+ }
97
+ return state;
98
+ }
99
+ }
100
+ catch (error) {
101
+ // Ошибка чтения - начинаем с чистого состояния
102
+ }
103
+ return this.createEmptyState();
104
+ }
105
+ /**
106
+ * Создаёт пустое состояние кэша
107
+ */
108
+ createEmptyState() {
109
+ return {
110
+ version: CACHE_VERSION,
111
+ nodeModules: {}
112
+ };
113
+ }
114
+ /**
115
+ * Сохраняет состояние кэша в файл
116
+ */
117
+ saveState() {
118
+ if (!this.enabled) {
119
+ return;
120
+ }
121
+ try {
122
+ // Создаём директорию .btc если её нет
123
+ if (!fs.existsSync(this.cachePath)) {
124
+ fs.mkdirSync(this.cachePath, { recursive: true });
125
+ }
126
+ fs.writeFileSync(this.stateFilePath, JSON.stringify(this.state, null, 2), 'utf-8');
127
+ }
128
+ catch (error) {
129
+ // Не критично если не удалось сохранить кэш
130
+ console.warn('Warning: Failed to save linking cache:', error);
131
+ }
132
+ }
133
+ /**
134
+ * Вычисляет hash от содержимого файла
135
+ *
136
+ * @param filePath - Путь к файлу
137
+ * @returns SHA256 hash или null если файл не существует
138
+ */
139
+ computeFileHash(filePath) {
140
+ try {
141
+ if (!fs.existsSync(filePath)) {
142
+ return null;
143
+ }
144
+ const content = fs.readFileSync(filePath);
145
+ return crypto.createHash('sha256').update(content).digest('hex');
146
+ }
147
+ catch (error) {
148
+ return null;
149
+ }
150
+ }
151
+ /**
152
+ * Получает hash от lockfile пакета
153
+ * Пробует package-lock.json, затем pnpm-lock.yaml, затем package.json как fallback
154
+ *
155
+ * @param packagePath - Путь к директории пакета
156
+ * @returns Hash от lockfile
157
+ */
158
+ getLockfileHash(packagePath) {
159
+ // Сначала пробуем package-lock.json (npm)
160
+ const npmLockPath = path.join(packagePath, 'package-lock.json');
161
+ let hash = this.computeFileHash(npmLockPath);
162
+ if (hash) {
163
+ return hash;
164
+ }
165
+ // Затем пробуем pnpm-lock.yaml (pnpm workspaces)
166
+ const pnpmLockPath = path.join(packagePath, 'pnpm-lock.yaml');
167
+ hash = this.computeFileHash(pnpmLockPath);
168
+ if (hash) {
169
+ return hash;
170
+ }
171
+ // Fallback на package.json
172
+ const packageJsonPath = path.join(packagePath, 'package.json');
173
+ return this.computeFileHash(packageJsonPath);
174
+ }
175
+ /**
176
+ * Проверяет нужно ли копировать node_modules для пакета
177
+ *
178
+ * @param wsName - ws:name пакета
179
+ * @param packagePath - Путь к директории пакета (где находится package-lock.json)
180
+ * @returns true если нужно копировать, false если можно пропустить
181
+ *
182
+ * @remarks
183
+ * Возвращает true (нужно копировать) если:
184
+ * - Кэш отключён (--no-cache)
185
+ * - Нет записи в кэше для этого пакета
186
+ * - Hash от package-lock.json изменился
187
+ * - Не удалось вычислить hash
188
+ */
189
+ shouldCopyNodeModules(wsName, packagePath) {
190
+ if (!this.enabled) {
191
+ return true;
192
+ }
193
+ const currentHash = this.getLockfileHash(packagePath);
194
+ if (!currentHash) {
195
+ // Не удалось получить hash - копируем на всякий случай
196
+ return true;
197
+ }
198
+ const cached = this.state.nodeModules[wsName];
199
+ if (!cached) {
200
+ // Нет записи в кэше
201
+ return true;
202
+ }
203
+ // Сравниваем hash
204
+ return cached.lockfileHash !== currentHash;
205
+ }
206
+ /**
207
+ * Обновляет запись кэша после копирования node_modules
208
+ *
209
+ * @param wsName - ws:name пакета
210
+ * @param packagePath - Путь к директории пакета
211
+ */
212
+ updateNodeModulesCache(wsName, packagePath) {
213
+ if (!this.enabled) {
214
+ return;
215
+ }
216
+ const hash = this.getLockfileHash(packagePath);
217
+ if (!hash) {
218
+ // Удаляем запись если не можем вычислить hash
219
+ delete this.state.nodeModules[wsName];
220
+ }
221
+ else {
222
+ this.state.nodeModules[wsName] = {
223
+ lockfileHash: hash,
224
+ linkedAt: new Date().toISOString(),
225
+ version: CACHE_VERSION
226
+ };
227
+ }
228
+ this.saveState();
229
+ }
230
+ /**
231
+ * Очищает весь кэш
232
+ */
233
+ clear() {
234
+ this.state = this.createEmptyState();
235
+ try {
236
+ if (fs.existsSync(this.stateFilePath)) {
237
+ fs.unlinkSync(this.stateFilePath);
238
+ }
239
+ }
240
+ catch (error) {
241
+ // Не критично
242
+ }
243
+ }
244
+ /**
245
+ * Полностью удаляет директорию .btc
246
+ */
247
+ static removeAll(projectPath) {
248
+ const cachePath = path.join(projectPath, CACHE_DIR_NAME);
249
+ if (fs.existsSync(cachePath)) {
250
+ fs.rmSync(cachePath, { recursive: true, force: true });
251
+ }
252
+ }
253
+ /**
254
+ * Проверяет включён ли кэш
255
+ */
256
+ isEnabled() {
257
+ return this.enabled;
258
+ }
259
+ }
260
+ exports.LinkingCache = LinkingCache;