@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,290 @@
1
+ "use strict";
2
+ /**
3
+ * Работа с файлами для сборки
4
+ *
5
+ * Отвечает за:
6
+ * - Сбор non-TypeScript файлов из проекта
7
+ * - Копирование non-TypeScript файлов в output директорию
8
+ * - Watch mode для non-TypeScript файлов
9
+ *
10
+ * @module build/files
11
+ */
12
+ var __importDefault = (this && this.__importDefault) || function (mod) {
13
+ return (mod && mod.__esModule) ? mod : { "default": mod };
14
+ };
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.collectNonTypescriptFiles = collectNonTypescriptFiles;
17
+ exports.copyNonTypescriptFiles = copyNonTypescriptFiles;
18
+ exports.watchNonTypescriptFiles = watchNonTypescriptFiles;
19
+ const node_fs_1 = __importDefault(require("node:fs"));
20
+ const node_path_1 = require("node:path");
21
+ const chokidar_1 = __importDefault(require("chokidar"));
22
+ const logger_js_1 = require("../logger.js");
23
+ /**
24
+ * Расширения TypeScript файлов (исключаются из копирования)
25
+ */
26
+ const TS_EXTENSIONS = ['.ts', '.tsx'];
27
+ /**
28
+ * Проверяет, является ли путь вложенным в другой путь
29
+ */
30
+ function isSubpath(parent, child) {
31
+ const normalizedParent = (0, node_path_1.normalize)(parent).replace(/\\/g, '/');
32
+ const normalizedChild = (0, node_path_1.normalize)(child).replace(/\\/g, '/');
33
+ return normalizedChild.startsWith(normalizedParent + '/');
34
+ }
35
+ /**
36
+ * Определяет rootDir из конфигурации
37
+ *
38
+ * Если rootDir не указан явно, пытается вычислить из include паттернов
39
+ * или использует директорию tsconfig.
40
+ */
41
+ function inferRootDir(configuration, configDir) {
42
+ // Явно указанный rootDir
43
+ if (configuration.options.rootDir) {
44
+ return (0, node_path_1.resolve)(configDir, configuration.options.rootDir);
45
+ }
46
+ // Пытаемся извлечь общий prefix из include паттернов
47
+ const { include } = configuration.raw || {};
48
+ if (include && include.length > 0) {
49
+ // Берём первый паттерн и извлекаем базовую директорию
50
+ const firstPattern = include[0];
51
+ const baseDir = firstPattern.split('*')[0].replace(/\/+$/, '') || '.';
52
+ return (0, node_path_1.resolve)(configDir, baseDir);
53
+ }
54
+ // Fallback: директория tsconfig
55
+ return configDir;
56
+ }
57
+ /**
58
+ * Собирает список non-TypeScript файлов из rootDir
59
+ *
60
+ * Сканирует все файлы в rootDir, исключая:
61
+ * - TypeScript файлы (.ts, .tsx)
62
+ * - Файлы из exclude паттернов tsconfig
63
+ * - outDir (если находится внутри rootDir)
64
+ * - node_modules
65
+ *
66
+ * @param configuration - ParsedCommandLine от TypeScript
67
+ * @param configDir - Директория где находится tsconfig (для resolve путей)
68
+ * @returns Список абсолютных путей к non-TypeScript файлам
69
+ */
70
+ function collectNonTypescriptFiles(configuration, configDir = process.cwd()) {
71
+ const { outDir } = configuration.options;
72
+ if (outDir === undefined) {
73
+ throw new Error('The outDir option is not set in the tsconfig.json file.');
74
+ }
75
+ // fs.globSync доступен только в Node.js 22+
76
+ if (parseInt(process.versions.node.split('.')[0]) < 22) {
77
+ throw new Error('Non-TypeScript files processing requires Node.js v22 or later');
78
+ }
79
+ const rootDir = inferRootDir(configuration, configDir);
80
+ const absoluteOutDir = (0, node_path_1.resolve)(configDir, outDir);
81
+ // Базовые исключения
82
+ const ignore = [
83
+ '**/node_modules/**',
84
+ ];
85
+ // Добавляем exclude из tsconfig
86
+ const { exclude } = configuration.raw || {};
87
+ if (exclude) {
88
+ for (const pattern of exclude) {
89
+ ignore.push(pattern);
90
+ }
91
+ }
92
+ // Исключаем outDir если он внутри rootDir
93
+ if (isSubpath(rootDir, absoluteOutDir)) {
94
+ const relativeOutDir = (0, node_path_1.relative)(rootDir, absoluteOutDir);
95
+ ignore.push(`${relativeOutDir}/**`);
96
+ }
97
+ // Сканируем rootDir
98
+ const pattern = (0, node_path_1.join)(rootDir, '**', '*').replace(/\\/g, '/');
99
+ // Node.js fs.globSync возвращает string[], фильтруем вручную
100
+ return node_fs_1.default.globSync(pattern, {
101
+ exclude: (fileName) => {
102
+ // Проверяем ignore паттерны
103
+ const relativePath = (0, node_path_1.relative)(rootDir, fileName).replace(/\\/g, '/');
104
+ // Если путь выходит за пределы rootDir, пропускаем проверку
105
+ // (fs.globSync может вызывать exclude для родительских директорий)
106
+ if (relativePath.startsWith('..')) {
107
+ return false;
108
+ }
109
+ return ignore.some(p => {
110
+ if (typeof p === 'string') {
111
+ // Простая проверка glob паттернов
112
+ if (p.includes('**')) {
113
+ // Для паттернов типа "**/node_modules/**" проверяем вхождение
114
+ const innerPattern = p.replace(/\*\*/g, '').replace(/^\/+|\/+$/g, '');
115
+ if (innerPattern) {
116
+ return relativePath.includes(innerPattern);
117
+ }
118
+ return false; // Паттерн только из ** - игнорируем
119
+ }
120
+ return relativePath === p || relativePath.startsWith(p + '/');
121
+ }
122
+ return false;
123
+ });
124
+ },
125
+ })
126
+ // Фильтруем директории
127
+ .filter(f => node_fs_1.default.statSync(f).isFile())
128
+ // Фильтруем TypeScript файлы
129
+ .filter(f => !TS_EXTENSIONS.some(ext => f.endsWith(ext)));
130
+ }
131
+ /**
132
+ * Фильтрует файлы по заданному списку
133
+ */
134
+ function selectFiles(allFiles, filterFiles) {
135
+ if (filterFiles.length === 0) {
136
+ return allFiles;
137
+ }
138
+ return allFiles.filter(x => filterFiles.includes(x));
139
+ }
140
+ /**
141
+ * Копирует non-TypeScript файлы в output директорию
142
+ *
143
+ * Сохраняет структуру директорий относительно rootDir.
144
+ *
145
+ * @param context - Контекст сборки
146
+ */
147
+ function copyNonTypescriptFiles(context) {
148
+ const { tsConfig, options, files, cwd } = context;
149
+ const configDir = cwd || process.cwd();
150
+ logger_js_1.logger.warning('📁 Copying non-TypeScript files...');
151
+ if (options.includeNonTsFiles === false) {
152
+ logger_js_1.logger.warning('Non-TypeScript files copy is disabled');
153
+ return;
154
+ }
155
+ const { outDir } = tsConfig.options;
156
+ if (!outDir) {
157
+ logger_js_1.logger.warning('outDir not set, skipping non-TypeScript files copy');
158
+ return;
159
+ }
160
+ const rootDir = inferRootDir(tsConfig, configDir);
161
+ const absoluteOutDir = (0, node_path_1.resolve)(configDir, outDir);
162
+ const entries = collectNonTypescriptFiles(tsConfig, configDir);
163
+ const selectedFiles = selectFiles(entries, files);
164
+ logger_js_1.logger.warning(`📁 Found ${entries.length} non-TypeScript files, copying ${selectedFiles.length} files...`);
165
+ for (const filePath of selectedFiles) {
166
+ const relativePath = (0, node_path_1.relative)(rootDir, filePath);
167
+ const outputFilePath = (0, node_path_1.resolve)(absoluteOutDir, relativePath);
168
+ node_fs_1.default.mkdirSync((0, node_path_1.dirname)(outputFilePath), { recursive: true });
169
+ node_fs_1.default.writeFileSync(outputFilePath, node_fs_1.default.readFileSync((0, node_path_1.resolve)(filePath), 'utf-8'));
170
+ }
171
+ }
172
+ /**
173
+ * Создаёт watcher для non-TypeScript файлов
174
+ *
175
+ * Использует chokidar для отслеживания изменений в non-ts файлах
176
+ * и копирует их в output директорию при изменении.
177
+ * Использует ту же логику определения rootDir, что и collectNonTypescriptFiles.
178
+ *
179
+ * @param context - Контекст сборки
180
+ * @param onChange - Callback при изменении файла (опционально)
181
+ * @returns Контроллер для остановки watch
182
+ */
183
+ function watchNonTypescriptFiles(context, onChange) {
184
+ const { tsConfig, options, cwd } = context;
185
+ if (options.includeNonTsFiles === false) {
186
+ // Возвращаем пустой контроллер если non-ts файлы отключены
187
+ return { close: () => { } };
188
+ }
189
+ const { outDir } = tsConfig.options;
190
+ const configDir = cwd || process.cwd();
191
+ if (!outDir) {
192
+ logger_js_1.logger.warning('outDir not set, skipping non-TypeScript files watch');
193
+ return { close: () => { } };
194
+ }
195
+ // Используем ту же логику что и collectNonTypescriptFiles
196
+ const rootDir = inferRootDir(tsConfig, configDir);
197
+ const absoluteOutDir = (0, node_path_1.resolve)(configDir, outDir);
198
+ // Формируем ignored паттерны
199
+ const { exclude } = tsConfig.raw || {};
200
+ const ignoredPatterns = [
201
+ /node_modules/,
202
+ // Игнорируем TypeScript файлы
203
+ (filePath) => TS_EXTENSIONS.some(ext => filePath.endsWith(ext)),
204
+ ];
205
+ // Добавляем exclude из tsconfig
206
+ if (exclude) {
207
+ for (const pattern of exclude) {
208
+ ignoredPatterns.push((0, node_path_1.resolve)(configDir, pattern).replace(/\\/g, '/'));
209
+ }
210
+ }
211
+ // Исключаем outDir
212
+ if (isSubpath(rootDir, absoluteOutDir)) {
213
+ ignoredPatterns.push((filePath) => isSubpath(absoluteOutDir, filePath) || filePath === absoluteOutDir);
214
+ }
215
+ logger_js_1.logger.info(`📁 Watching non-TS files in: ${rootDir}`);
216
+ // Создаём watcher на rootDir
217
+ const watcher = chokidar_1.default.watch(rootDir, {
218
+ ignored: ignoredPatterns,
219
+ ignoreInitial: true,
220
+ persistent: true,
221
+ });
222
+ // Debug events
223
+ watcher.on('ready', () => {
224
+ logger_js_1.logger.info('📁 Non-TS watcher ready');
225
+ });
226
+ watcher.on('error', (error) => {
227
+ logger_js_1.logger.error(`📁 Non-TS watcher error: ${error}`);
228
+ });
229
+ /**
230
+ * Проверяет, является ли файл non-TS файлом для копирования
231
+ * (дополнительная проверка, т.к. chokidar ignored может пропустить)
232
+ */
233
+ const isNonTsFile = (filePath) => {
234
+ return !TS_EXTENSIONS.some(ext => filePath.endsWith(ext));
235
+ };
236
+ /**
237
+ * Копирует файл в output директорию
238
+ */
239
+ const copyFile = (filePath) => {
240
+ // Фильтруем TypeScript файлы
241
+ if (!isNonTsFile(filePath)) {
242
+ return;
243
+ }
244
+ try {
245
+ const relativePath = (0, node_path_1.relative)(rootDir, filePath);
246
+ const outputFilePath = (0, node_path_1.resolve)(absoluteOutDir, relativePath);
247
+ node_fs_1.default.mkdirSync((0, node_path_1.dirname)(outputFilePath), { recursive: true });
248
+ node_fs_1.default.copyFileSync(filePath, outputFilePath);
249
+ logger_js_1.logger.info(`📄 Copied: ${relativePath}`);
250
+ if (onChange) {
251
+ onChange(filePath);
252
+ }
253
+ }
254
+ catch (error) {
255
+ logger_js_1.logger.error(`Failed to copy ${filePath}: ${error}`);
256
+ }
257
+ };
258
+ /**
259
+ * Удаляет файл из output директории
260
+ */
261
+ const deleteFile = (filePath) => {
262
+ // Фильтруем TypeScript файлы
263
+ if (!isNonTsFile(filePath)) {
264
+ return;
265
+ }
266
+ try {
267
+ const relativePath = (0, node_path_1.relative)(rootDir, filePath);
268
+ const outputFilePath = (0, node_path_1.resolve)(absoluteOutDir, relativePath);
269
+ if (node_fs_1.default.existsSync(outputFilePath)) {
270
+ node_fs_1.default.unlinkSync(outputFilePath);
271
+ logger_js_1.logger.info(`🗑️ Deleted: ${relativePath}`);
272
+ if (onChange) {
273
+ onChange(filePath);
274
+ }
275
+ }
276
+ }
277
+ catch (error) {
278
+ logger_js_1.logger.error(`Failed to delete ${filePath}: ${error}`);
279
+ }
280
+ };
281
+ // Обработчики событий
282
+ watcher.on('add', copyFile);
283
+ watcher.on('change', copyFile);
284
+ watcher.on('unlink', deleteFile);
285
+ return {
286
+ close: () => {
287
+ watcher.close();
288
+ },
289
+ };
290
+ }
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ /**
3
+ * Build Pipeline
4
+ *
5
+ * Основной модуль сборки TypeScript в BorisScript.
6
+ * Предоставляет unified API для single и watch режимов.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * // Single build
11
+ * const result = BuildPipeline.run({
12
+ * tsConfig: parsedConfig,
13
+ * options: btcOptions,
14
+ * });
15
+ *
16
+ * // Watch mode (будущее)
17
+ * const watcher = BuildPipeline.watch(config, {
18
+ * onRebuild: (result) => console.log('Rebuilt!', result.success),
19
+ * });
20
+ * watcher.close();
21
+ * ```
22
+ *
23
+ * @module build
24
+ */
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.default = exports.BuildPipeline = exports.copyNonTypescriptFiles = exports.collectNonTypescriptFiles = exports.compile = exports.decodeUnicodeEscapes = exports.indentString = exports.stripControlChars = exports.transformOutput = exports.createBuildContext = void 0;
27
+ const logger_js_1 = require("../logger.js");
28
+ const types_js_1 = require("./types.js");
29
+ const compiler_js_1 = require("./compiler.js");
30
+ const files_js_1 = require("./files.js");
31
+ // Re-exports
32
+ var types_js_2 = require("./types.js");
33
+ Object.defineProperty(exports, "createBuildContext", { enumerable: true, get: function () { return types_js_2.createBuildContext; } });
34
+ var output_js_1 = require("./output.js");
35
+ Object.defineProperty(exports, "transformOutput", { enumerable: true, get: function () { return output_js_1.transformOutput; } });
36
+ Object.defineProperty(exports, "stripControlChars", { enumerable: true, get: function () { return output_js_1.stripControlChars; } });
37
+ Object.defineProperty(exports, "indentString", { enumerable: true, get: function () { return output_js_1.indentString; } });
38
+ Object.defineProperty(exports, "decodeUnicodeEscapes", { enumerable: true, get: function () { return output_js_1.decodeUnicodeEscapes; } });
39
+ var compiler_js_2 = require("./compiler.js");
40
+ Object.defineProperty(exports, "compile", { enumerable: true, get: function () { return compiler_js_2.compile; } });
41
+ var files_js_2 = require("./files.js");
42
+ Object.defineProperty(exports, "collectNonTypescriptFiles", { enumerable: true, get: function () { return files_js_2.collectNonTypescriptFiles; } });
43
+ Object.defineProperty(exports, "copyNonTypescriptFiles", { enumerable: true, get: function () { return files_js_2.copyNonTypescriptFiles; } });
44
+ /**
45
+ * Build Pipeline - единая точка входа для сборки
46
+ */
47
+ exports.BuildPipeline = {
48
+ /**
49
+ * Выполняет однократную сборку проекта
50
+ *
51
+ * @param contextOrOptions - Контекст сборки или опции для его создания
52
+ * @returns Результат сборки
53
+ */
54
+ run(contextOrOptions) {
55
+ const context = 'mode' in contextOrOptions && contextOrOptions.mode !== undefined
56
+ ? contextOrOptions
57
+ : (0, types_js_1.createBuildContext)(contextOrOptions);
58
+ logger_js_1.logger.info(`🔨 ${new Date().toLocaleTimeString()} Build started`);
59
+ // Компилируем TypeScript
60
+ const result = (0, compiler_js_1.compile)(context);
61
+ // Копируем non-TypeScript файлы
62
+ (0, files_js_1.copyNonTypescriptFiles)(context);
63
+ if (result.success) {
64
+ logger_js_1.logger.info(`✅ ${new Date().toLocaleTimeString()} Build finished (${result.duration}ms)`);
65
+ }
66
+ else {
67
+ logger_js_1.logger.error(`❌ ${new Date().toLocaleTimeString()} Build failed with errors`);
68
+ }
69
+ return result;
70
+ },
71
+ /**
72
+ * Запускает watch режим для инкрементальной сборки
73
+ *
74
+ * @param contextOrOptions - Контекст сборки или опции для его создания
75
+ * @param watchOptions - Опции watch режима
76
+ * @returns Контроллер для остановки watch
77
+ */
78
+ watch(contextOrOptions, watchOptions) {
79
+ const context = 'mode' in contextOrOptions && contextOrOptions.mode !== undefined
80
+ ? contextOrOptions
81
+ : (0, types_js_1.createBuildContext)({ ...contextOrOptions, mode: 'watch' });
82
+ logger_js_1.logger.info(`👀 ${new Date().toLocaleTimeString()} Watch mode started`);
83
+ // Копируем non-TS файлы один раз при старте watch
84
+ // (при пересборке копирование не нужно - только watcher отслеживает изменения)
85
+ (0, files_js_1.copyNonTypescriptFiles)(context);
86
+ // Запускаем TypeScript watch для инкрементальной компиляции
87
+ const tsWatcher = (0, compiler_js_1.createWatchProgram)(context, (result) => {
88
+ logger_js_1.logger.warning(`🔄 ${new Date().toLocaleTimeString()} Rebuild completed. Success: ${result.success}`);
89
+ // Вызываем пользовательский callback
90
+ watchOptions?.onRebuild?.(result);
91
+ });
92
+ // Запускаем chokidar watcher для non-TypeScript файлов
93
+ const nonTsWatcher = (0, files_js_1.watchNonTypescriptFiles)(context, watchOptions?.onNonTsFileChange);
94
+ return {
95
+ close: () => {
96
+ tsWatcher.close();
97
+ nonTsWatcher.close();
98
+ },
99
+ };
100
+ },
101
+ };
102
+ exports.default = exports.BuildPipeline;
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ /**
3
+ * Пост-обработка выходных файлов
4
+ *
5
+ * Отвечает за:
6
+ * - Трансформацию JS в XML/HTML форматы
7
+ * - Декодирование Unicode escape последовательностей
8
+ * - Добавление BOM
9
+ *
10
+ * @module build/output
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.transformOutput = transformOutput;
14
+ exports.decodeUnicodeEscapes = decodeUnicodeEscapes;
15
+ exports.stripControlChars = stripControlChars;
16
+ exports.indentString = indentString;
17
+ const xml_js_1 = require("../utils/xml.js");
18
+ /**
19
+ * Трансформирует выходной файл
20
+ *
21
+ * Применяет пост-обработку к сгенерированному JS коду:
22
+ * - Конвертация в XML для файлов с `/// @xml-init`
23
+ * - Конвертация в HTML для файлов с `/// @html`
24
+ * - Декодирование Unicode escape sequences
25
+ * - Добавление BOM (Byte Order Mark)
26
+ *
27
+ * @param fileName - Имя выходного файла
28
+ * @param code - Сгенерированный код
29
+ * @param options - Опции компиляции
30
+ */
31
+ function transformOutput(fileName, code, options) {
32
+ let resultFileName = fileName;
33
+ let resultCode = code;
34
+ // Конвертация в SPXML формат
35
+ // TODO: заменить на import стиль
36
+ if (resultCode.indexOf('/// @xml-init') !== -1) {
37
+ // Убираем запрещённые управляющие символы (кроме \t, \n, \r)
38
+ resultCode = stripControlChars(resultCode);
39
+ resultCode = indentString(resultCode, '\t\t');
40
+ const xmlObj = {
41
+ '?xml': { '@_version': '1.0', '@_encoding': 'UTF-8' },
42
+ 'SPXML-INLINE-FORM': {
43
+ 'OnInit': {
44
+ '@_PROPERTY': '1',
45
+ '@_EXPR': '\n' + resultCode + '\n\t',
46
+ },
47
+ },
48
+ };
49
+ resultCode = xml_js_1.xmlBuilder.build(xmlObj);
50
+ resultFileName = resultFileName.replace('.js', '.xml');
51
+ }
52
+ // Конвертация в ASP.NET HTML формат
53
+ // TODO: заменить на import стиль
54
+ if (resultCode.indexOf('/// @html') !== -1) {
55
+ resultCode = `<%\n${resultCode}\n%>`;
56
+ resultFileName = resultFileName.replace('.js', '.html');
57
+ }
58
+ // Декодирование Unicode escape последовательностей
59
+ if (options.retainNonAsciiCharacters !== true) {
60
+ resultCode = decodeUnicodeEscapes(resultCode);
61
+ }
62
+ // Добавление BOM для корректной кодировки
63
+ resultCode = '\uFEFF' + resultCode;
64
+ return {
65
+ fileName: resultFileName,
66
+ content: resultCode,
67
+ };
68
+ }
69
+ /**
70
+ * Декодирует Unicode escape последовательности в строке
71
+ *
72
+ * @example
73
+ * decodeUnicodeEscapes('\\u0041') // 'A'
74
+ */
75
+ function decodeUnicodeEscapes(code) {
76
+ return code.replace(/\\u[\dA-Fa-f]{4}/g, (match) => {
77
+ return String.fromCharCode(parseInt(match.substr(2), 16));
78
+ });
79
+ }
80
+ /**
81
+ * Удаляет запрещённые управляющие символы из строки.
82
+ * Сохраняет tab (\\t), newline (\\n), carriage return (\\r).
83
+ */
84
+ function stripControlChars(value) {
85
+ return value.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, '');
86
+ }
87
+ /**
88
+ * Добавляет отступ к каждой строке
89
+ */
90
+ function indentString(value, indent) {
91
+ return value.split('\n').map(line => indent + line).join('\n');
92
+ }
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ /**
3
+ * Реестр TypeScript трансформеров
4
+ *
5
+ * Единый источник трансформеров для single и watch режимов.
6
+ * Трансформеры разделены на before (до emit) и after (после emit).
7
+ *
8
+ * @module build/transformers
9
+ */
10
+ var __importDefault = (this && this.__importDefault) || function (mod) {
11
+ return (mod && mod.__esModule) ? mod : { "default": mod };
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.createBeforeTransformers = createBeforeTransformers;
15
+ exports.createAfterTransformers = createAfterTransformers;
16
+ exports.createTransformers = createTransformers;
17
+ // Before-трансформеры (работают с AST до генерации JS)
18
+ const namespaces_js_1 = require("../../transformers/namespaces.js");
19
+ const enumsToObjects_js_1 = require("../../transformers/enumsToObjects.js");
20
+ const arrayFunctional_js_1 = __importDefault(require("../../transformers/arrayFunctional.js"));
21
+ const arrayGeneral_js_1 = __importDefault(require("../../transformers/arrayGeneral.js"));
22
+ const remodule_js_1 = require("../../transformers/remodule.js");
23
+ const functions_js_1 = require("../../transformers/functions.js");
24
+ const string_js_1 = __importDefault(require("../../transformers/string.js"));
25
+ const math_js_1 = require("../../transformers/math.js");
26
+ const propSemantic_js_1 = __importDefault(require("../../transformers/propSemantic.js"));
27
+ const tocodelibrary_js_1 = require("../../transformers/tocodelibrary.js");
28
+ const funcSemantic_js_1 = require("../../transformers/funcSemantic.js");
29
+ const execObj_js_1 = require("../../transformers/execObj.js");
30
+ const dirname_js_1 = require("../../transformers/dirname.js");
31
+ const objectProperties_js_1 = require("../../transformers/objectProperties.js");
32
+ const globalCache_js_1 = require("../../transformers/globalCache.js");
33
+ const numericSeparator_js_1 = require("../../transformers/numericSeparator.js");
34
+ // After-трансформеры (замена Babel плагинов, работают после генерации JS)
35
+ const templateLiterals_js_1 = require("../../transformers/templateLiterals.js");
36
+ const shorthandProperties_js_1 = require("../../transformers/shorthandProperties.js");
37
+ const forOfToForIn_js_1 = require("../../transformers/forOfToForIn.js");
38
+ const spreadArray_js_1 = require("../../transformers/spreadArray.js");
39
+ const spreadObject_js_1 = require("../../transformers/spreadObject.js");
40
+ const destructuring_js_1 = require("../../transformers/destructuring.js");
41
+ const replaceDollar_js_1 = require("../../transformers/replaceDollar.js");
42
+ const blockScoping_js_1 = require("../../transformers/blockScoping.js");
43
+ const loopHoistVariables_js_1 = require("../../transformers/loopHoistVariables.js");
44
+ const precedence_js_1 = require("../../transformers/precedence.js");
45
+ const removeImportExport_js_1 = require("../../transformers/removeImportExport.js");
46
+ /**
47
+ * Создаёт набор before-трансформеров
48
+ *
49
+ * @param program - TypeScript program для type-aware трансформеров
50
+ * @param options - Опции компиляции btc
51
+ * @param executables - Массив для сбора информации об исполняемых объектах
52
+ */
53
+ function createBeforeTransformers(program, options, executables) {
54
+ const transformers = [];
55
+ // numericSeparator должен быть в before, т.к. printer сохраняет исходный текст литералов
56
+ transformers.push((0, numericSeparator_js_1.numericSeparatorTransformer)()); // 1_000_000 -> 1000000
57
+ // Базовые трансформации синтаксиса
58
+ transformers.push((0, enumsToObjects_js_1.enumsToObjectsTransformer)());
59
+ transformers.push((0, namespaces_js_1.namespacesTransformer)());
60
+ // Polyfill трансформации (опционально)
61
+ if (options.usePolyfill) {
62
+ transformers.push((0, arrayFunctional_js_1.default)(program), (0, arrayGeneral_js_1.default)(program), (0, string_js_1.default)(program), (0, math_js_1.mathTransformer)(), (0, globalCache_js_1.globalCacheTransformer)(program));
63
+ }
64
+ // Трансформации функций и объектов
65
+ transformers.push((0, functions_js_1.functionsTransformer)());
66
+ transformers.push((0, objectProperties_js_1.objectPropertiesTransformer)());
67
+ // Сбор информации об исполняемых объектах
68
+ transformers.push((0, execObj_js_1.execObjTransformer)(program, executables));
69
+ // Remodule трансформации (опционально)
70
+ if (options.useRemodule) {
71
+ transformers.push((0, dirname_js_1.dirnameTransformer)(), (0, funcSemantic_js_1.funcSemanticTransformer)(), (0, remodule_js_1.remoduleTransformer)(program), (0, tocodelibrary_js_1.tocodelibraryTransformer)(), (0, propSemantic_js_1.default)(program));
72
+ }
73
+ return transformers;
74
+ }
75
+ /**
76
+ * Создаёт набор after-трансформеров
77
+ *
78
+ * After-трансформеры выполняются после генерации JS кода.
79
+ * Заменяют функциональность Babel плагинов для понижения синтаксиса.
80
+ */
81
+ function createAfterTransformers() {
82
+ return [
83
+ (0, templateLiterals_js_1.templateLiteralsTransformer)(), // `hello ${x}` -> "hello " + x
84
+ (0, shorthandProperties_js_1.shorthandPropertiesTransformer)(), // { x } -> { x: x }
85
+ (0, forOfToForIn_js_1.forOfToForInTransformer)(), // for-of -> for-in
86
+ (0, spreadArray_js_1.spreadArrayTransformer)(), // [...arr] -> ArrayUnion(arr)
87
+ (0, spreadObject_js_1.spreadObjectTransformer)(), // {...obj} -> ObjectUnion({}, obj)
88
+ (0, destructuring_js_1.destructuringTransformer)(), // const { a } = obj -> const a = obj.a
89
+ (0, blockScoping_js_1.blockScopingTransformer)(), // let/const -> var (с shadowing)
90
+ (0, loopHoistVariables_js_1.loopHoistVariablesTransformer)(), // hoist loop vars before loop
91
+ (0, precedence_js_1.precedenceTransformer)(), // добавляет скобки для приоритета операций
92
+ (0, replaceDollar_js_1.replaceDollarTransformer)(), // $name -> _24_name
93
+ (0, removeImportExport_js_1.removeImportExportTransformer)(), // удаляет import/export
94
+ ];
95
+ }
96
+ /**
97
+ * Создаёт полный набор трансформеров для компиляции
98
+ *
99
+ * @param program - TypeScript program
100
+ * @param options - Опции компиляции btc
101
+ * @returns Объект с before, after трансформерами и массивом executables
102
+ */
103
+ function createTransformers(program, options) {
104
+ const executables = [];
105
+ return {
106
+ before: createBeforeTransformers(program, options, executables),
107
+ after: createAfterTransformers(),
108
+ executables,
109
+ };
110
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ /**
3
+ * Типы для Build Pipeline
4
+ * @module build/types
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.createBuildContext = createBuildContext;
8
+ /**
9
+ * Создаёт контекст сборки
10
+ */
11
+ function createBuildContext(opts) {
12
+ return {
13
+ mode: opts.mode ?? 'single',
14
+ tsConfig: opts.tsConfig,
15
+ options: opts.options,
16
+ files: opts.files ?? [],
17
+ cwd: opts.cwd ?? process.cwd(),
18
+ };
19
+ }