@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.
- package/LICENSE +21 -0
- package/README.md +66 -0
- package/build/builder/config.js +88 -0
- package/build/cli/commands/artifact.js +14 -0
- package/build/cli/commands/build.js +25 -0
- package/build/cli/commands/dev.js +190 -0
- package/build/cli/commands/index.js +18 -0
- package/build/cli/commands/init.js +15 -0
- package/build/cli/commands/link.js +18 -0
- package/build/cli/commands/push.js +28 -0
- package/build/cli/index.js +14 -0
- package/build/cli/types.js +2 -0
- package/build/core/artifacting/context.js +54 -0
- package/build/core/artifacting/index.js +37 -0
- package/build/core/artifacting/stages/index.js +10 -0
- package/build/core/artifacting/stages/main-archive.js +72 -0
- package/build/core/artifacting/stages/validate.js +70 -0
- package/build/core/artifacting/types.js +6 -0
- package/build/core/artifacting/utils/index.js +10 -0
- package/build/core/artifacting/utils/zip.js +94 -0
- package/build/core/babel.js +96 -0
- package/build/core/btconfig.types.js +6 -0
- package/build/core/build.js +280 -0
- package/build/core/building/compile-mode.js +146 -0
- package/build/core/building/compiler.js +281 -0
- package/build/core/building/coordinator.js +71 -0
- package/build/core/building/files.js +290 -0
- package/build/core/building/index.js +102 -0
- package/build/core/building/output.js +92 -0
- package/build/core/building/transformers.js +110 -0
- package/build/core/building/types.js +19 -0
- package/build/core/config.js +157 -0
- package/build/core/dependencies.js +223 -0
- package/build/core/linking/cache.js +260 -0
- package/build/core/linking/context.js +149 -0
- package/build/core/linking/dependencies.js +240 -0
- package/build/core/linking/executables.js +61 -0
- package/build/core/linking/generators/api-ext.js +57 -0
- package/build/core/linking/generators/component.js +83 -0
- package/build/core/linking/generators/filemap.js +53 -0
- package/build/core/linking/generators/index.js +21 -0
- package/build/core/linking/generators/init-xml.js +37 -0
- package/build/core/linking/generators/package-json.js +50 -0
- package/build/core/linking/index.js +213 -0
- package/build/core/linking/linkers/component.js +175 -0
- package/build/core/linking/linkers/index.js +69 -0
- package/build/core/linking/linkers/standalone.js +144 -0
- package/build/core/linking/linkers/system.js +86 -0
- package/build/core/linking/parsers.js +278 -0
- package/build/core/linking/types.js +6 -0
- package/build/core/linking/utils/copy.js +101 -0
- package/build/core/linking/utils/index.js +26 -0
- package/build/core/linking/utils/node-modules.js +226 -0
- package/build/core/linking/utils/package-type.js +101 -0
- package/build/core/linking/utils/url.js +73 -0
- package/build/core/linking/utils/write.js +91 -0
- package/build/core/logger.js +10 -0
- package/build/core/pushing/config.js +90 -0
- package/build/core/pushing/index.js +96 -0
- package/build/core/pushing/init-scripts.js +173 -0
- package/build/core/pushing/queue.js +95 -0
- package/build/core/pushing/reinit.js +61 -0
- package/build/core/pushing/session.js +167 -0
- package/build/core/pushing/types.js +6 -0
- package/build/core/pushing/upload.js +35 -0
- package/build/core/tsconfig.js +78 -0
- package/build/core/utils/index.js +17 -0
- package/build/core/utils/logger.js +46 -0
- package/build/core/utils/properties.js +81 -0
- package/build/core/utils/xml.js +44 -0
- package/build/core/utils.js +59 -0
- package/build/index.js +76 -0
- package/build/plugins/destructuring.js +83 -0
- package/build/plugins/forOfToForIn.js +14 -0
- package/build/plugins/loopHoistVariables.js +160 -0
- package/build/plugins/precedence.js +172 -0
- package/build/plugins/removeImportExport.js +42 -0
- package/build/plugins/replaceDollar.js +16 -0
- package/build/plugins/spreadArray.js +42 -0
- package/build/plugins/spreadObject.js +91 -0
- package/build/transformers/arrayFunctional.js +467 -0
- package/build/transformers/arrayGeneral.js +222 -0
- package/build/transformers/blockScoping.js +212 -0
- package/build/transformers/destructuring.js +133 -0
- package/build/transformers/dirname.js +79 -0
- package/build/transformers/enumsToObjects.js +25 -0
- package/build/transformers/execObj.js +220 -0
- package/build/transformers/forOfToForIn.js +45 -0
- package/build/transformers/funcSemantic.js +113 -0
- package/build/transformers/functions.js +270 -0
- package/build/transformers/globalCache.js +34 -0
- package/build/transformers/loopHoistVariables.js +352 -0
- package/build/transformers/math.js +39 -0
- package/build/transformers/namespaces.js +22 -0
- package/build/transformers/numericSeparator.js +46 -0
- package/build/transformers/objectProperties.js +54 -0
- package/build/transformers/precedence.js +192 -0
- package/build/transformers/propSemantic.js +467 -0
- package/build/transformers/remodule.js +620 -0
- package/build/transformers/removeImportExport.js +135 -0
- package/build/transformers/replaceDollar.js +46 -0
- package/build/transformers/shorthandProperties.js +34 -0
- package/build/transformers/spreadArray.js +68 -0
- package/build/transformers/spreadObject.js +134 -0
- package/build/transformers/string.js +138 -0
- package/build/transformers/templateLiterals.js +104 -0
- package/build/transformers/tocodelibrary.js +178 -0
- package/build/transformers/utils.js +202 -0
- package/build/wshcm/client.js +193 -0
- package/build/wshcm/evaluator.js +111 -0
- package/build/wshcm/exceptions.js +25 -0
- package/build/wshcm/index.js +20 -0
- package/build/wshcm/soap-utils.js +228 -0
- package/build/wshcm/types.js +2 -0
- package/build/wshcm/uploader.js +320 -0
- 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
|
+
}
|