@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,620 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.remoduleTransformer = remoduleTransformer;
7
+ // src/transformers/remodule.ts
8
+ const typescript_1 = __importDefault(require("typescript"));
9
+ const utils_1 = require("./utils");
10
+ function remoduleTransformer(program) {
11
+ const typeChecker = program.getTypeChecker();
12
+ return (context) => {
13
+ return (sourceFile) => {
14
+ const factory = context.factory;
15
+ let currentScope = null;
16
+ let scopeIdCounter = 0;
17
+ const scopeToId = new WeakMap();
18
+ const variableUsages = new Map(); // "scopeId:varName" -> usage info
19
+ function getUsageKey(scopeId, varName) {
20
+ return `${scopeId}:${varName}`;
21
+ }
22
+ // Проверяет, является ли импорт только типом (type, interface, etc.)
23
+ function isTypeOnlyImport(node) {
24
+ let symbol = typeChecker.getSymbolAtLocation(node);
25
+ if (!symbol) {
26
+ return false;
27
+ }
28
+ // Получаем алиасированный символ (если это импорт)
29
+ if (symbol.flags & typescript_1.default.SymbolFlags.Alias) {
30
+ symbol = typeChecker.getAliasedSymbol(symbol);
31
+ }
32
+ // Если у символа нет деклараций, считаем что это не тип
33
+ if (!symbol.declarations || symbol.declarations.length === 0) {
34
+ return false;
35
+ }
36
+ // Проверяем все декларации символа
37
+ return symbol.declarations.every(decl => {
38
+ return typescript_1.default.isTypeAliasDeclaration(decl) ||
39
+ typescript_1.default.isInterfaceDeclaration(decl) ||
40
+ typescript_1.default.isTypeParameterDeclaration(decl);
41
+ });
42
+ }
43
+ // Добавляем var __module_env = {}; в начало файла
44
+ const moduleEnvDecl = factory.createVariableStatement(undefined, factory.createVariableDeclarationList([factory.createVariableDeclaration('__module_env', undefined, undefined, factory.createObjectLiteralExpression([], false))], typescript_1.default.NodeFlags.None));
45
+ function createScope(envName) {
46
+ const scope = {
47
+ parent: currentScope,
48
+ declarations: new Set(),
49
+ envName
50
+ };
51
+ scopeToId.set(scope, `scope_${scopeIdCounter++}`);
52
+ return scope;
53
+ }
54
+ function getScopeId(scope) {
55
+ return scopeToId.get(scope) || 'unknown';
56
+ }
57
+ function addDeclaration(name, isFunction = false) {
58
+ if (currentScope) {
59
+ currentScope.declarations.add(name);
60
+ const scopeId = getScopeId(currentScope);
61
+ const key = getUsageKey(scopeId, name);
62
+ // Инициализируем информацию об использовании только если еще не было
63
+ if (!variableUsages.has(key)) {
64
+ variableUsages.set(key, {
65
+ declaredInScope: scopeId,
66
+ usedInScopes: new Set(),
67
+ isFunction
68
+ });
69
+ }
70
+ }
71
+ }
72
+ function recordUsage(name) {
73
+ if (currentScope) {
74
+ // Находим, где объявлена эта переменная
75
+ let scope = currentScope;
76
+ while (scope) {
77
+ if (scope.declarations.has(name)) {
78
+ const declScopeId = getScopeId(scope);
79
+ const key = getUsageKey(declScopeId, name);
80
+ const usage = variableUsages.get(key);
81
+ if (usage) {
82
+ const currentScopeId = getScopeId(currentScope);
83
+ usage.usedInScopes.add(currentScopeId);
84
+ }
85
+ return;
86
+ }
87
+ scope = scope.parent;
88
+ }
89
+ }
90
+ }
91
+ function isUsedInDifferentScope(varName) {
92
+ // Находим, где объявлена эта переменная
93
+ let scope = currentScope;
94
+ while (scope) {
95
+ if (scope.declarations.has(varName)) {
96
+ const declScopeId = getScopeId(scope);
97
+ const key = getUsageKey(declScopeId, varName);
98
+ const usage = variableUsages.get(key);
99
+ if (!usage)
100
+ return false;
101
+ // Проверяем, используется ли переменная в scope'е, отличном от того где объявлена
102
+ for (const scopeId of usage.usedInScopes) {
103
+ if (scopeId !== usage.declaredInScope) {
104
+ return true;
105
+ }
106
+ }
107
+ return false;
108
+ }
109
+ scope = scope.parent;
110
+ }
111
+ return false;
112
+ }
113
+ function findDeclaration(name) {
114
+ let scope = currentScope;
115
+ let depth = 0;
116
+ while (scope) {
117
+ if (scope.declarations.has(name)) {
118
+ // Строим путь к переменной
119
+ if (depth === 0) {
120
+ return { envPath: `__env.${name}`, found: true };
121
+ }
122
+ let path = '__env';
123
+ for (let i = 0; i < depth; i++) {
124
+ path += '.__parent';
125
+ }
126
+ path += '.' + name;
127
+ return { envPath: path, found: true };
128
+ }
129
+ scope = scope.parent;
130
+ depth++;
131
+ }
132
+ return { envPath: name, found: false };
133
+ }
134
+ function parseEnvPath(envPath) {
135
+ const parts = envPath.split('.');
136
+ let expr = factory.createIdentifier(parts[0]);
137
+ for (let i = 1; i < parts.length; i++) {
138
+ expr = factory.createPropertyAccessExpression(expr, parts[i]);
139
+ }
140
+ return expr;
141
+ }
142
+ function createFunctionDescriptor(funcName, parentEnvName, isExported = false) {
143
+ const envName = `${funcName}__env`;
144
+ const descName = `${funcName}__desc`;
145
+ const statements = [];
146
+ // var funcName__env = { __parent: parentEnv };
147
+ statements.push(factory.createVariableStatement(undefined, factory.createVariableDeclarationList([factory.createVariableDeclaration(envName, undefined, undefined, factory.createObjectLiteralExpression([
148
+ factory.createPropertyAssignment('__parent', factory.createIdentifier(parentEnvName))
149
+ ], false))], typescript_1.default.NodeFlags.None)));
150
+ // var funcName__desc = { "@descriptor": "function", "obj": undefined, "env": funcName__env, "callable": funcName };
151
+ statements.push(factory.createVariableStatement(undefined, factory.createVariableDeclarationList([factory.createVariableDeclaration(descName, undefined, undefined, factory.createObjectLiteralExpression([
152
+ factory.createPropertyAssignment(factory.createStringLiteral('@descriptor'), factory.createStringLiteral('function')),
153
+ factory.createPropertyAssignment(factory.createStringLiteral('obj'), factory.createIdentifier('undefined')),
154
+ factory.createPropertyAssignment(factory.createStringLiteral('env'), factory.createIdentifier(envName)),
155
+ factory.createPropertyAssignment(factory.createStringLiteral('callable'), factory.createIdentifier(funcName))
156
+ ], true))], typescript_1.default.NodeFlags.None)));
157
+ // parentEnv.funcName = funcName__desc
158
+ statements.push(factory.createExpressionStatement(factory.createAssignment(factory.createPropertyAccessExpression((0, utils_1.markUntouchable)(factory.createIdentifier(parentEnvName)), funcName), factory.createIdentifier(descName))));
159
+ // Если экспортируется, добавляем __module.exports.funcName = funcName__desc
160
+ if (isExported) {
161
+ const moduleExportPropertyAccessExpression = factory.createPropertyAccessExpression(factory.createIdentifier('__module'), 'exports');
162
+ statements.push(factory.createExpressionStatement(factory.createAssignment(factory.createPropertyAccessExpression((0, utils_1.markUntouchable)(moduleExportPropertyAccessExpression), funcName), factory.createIdentifier(descName))));
163
+ }
164
+ return statements;
165
+ }
166
+ function createVariableEnvAssignment(varName, parentEnvName) {
167
+ // parentEnv.varName = varName
168
+ return factory.createExpressionStatement(factory.createAssignment(factory.createPropertyAccessExpression(factory.createIdentifier(parentEnvName), varName), factory.createIdentifier(varName)));
169
+ }
170
+ // Сначала собираем все декларации в области видимости
171
+ function collectDeclarations(statements) {
172
+ for (const stmt of statements) {
173
+ if (typescript_1.default.isFunctionDeclaration(stmt) && stmt.name) {
174
+ addDeclaration(stmt.name.text, true); // функция
175
+ }
176
+ else if (typescript_1.default.isVariableStatement(stmt)) {
177
+ for (const decl of stmt.declarationList.declarations) {
178
+ if (typescript_1.default.isIdentifier(decl.name)) {
179
+ addDeclaration(decl.name.text, false); // переменная
180
+ }
181
+ }
182
+ }
183
+ }
184
+ }
185
+ // Первый проход: собираем информацию об использовании переменных
186
+ function analyzeUsages(node) {
187
+ if (typescript_1.default.isFunctionDeclaration(node) && node.name) {
188
+ const savedScope = currentScope;
189
+ currentScope = createScope('__env');
190
+ if (node.body) {
191
+ collectDeclarations(node.body.statements);
192
+ for (const stmt of node.body.statements) {
193
+ analyzeUsages(stmt);
194
+ }
195
+ // Также анализируем тело функции для использования переменных
196
+ analyzeUsagesInExpression(node.body);
197
+ }
198
+ currentScope = savedScope;
199
+ return;
200
+ }
201
+ if (typescript_1.default.isVariableStatement(node)) {
202
+ // Проверяем initializer для использования переменных
203
+ for (const decl of node.declarationList.declarations) {
204
+ if (decl.initializer) {
205
+ analyzeUsagesInExpression(decl.initializer);
206
+ }
207
+ }
208
+ return;
209
+ }
210
+ typescript_1.default.forEachChild(node, analyzeUsages);
211
+ }
212
+ function analyzeUsagesInExpression(node) {
213
+ if (typescript_1.default.isIdentifier(node) && node.parent) {
214
+ // Не считаем декларации и property names
215
+ if (!typescript_1.default.isVariableDeclaration(node.parent) &&
216
+ !typescript_1.default.isFunctionDeclaration(node.parent) &&
217
+ !typescript_1.default.isParameter(node.parent) &&
218
+ !(typescript_1.default.isPropertyAccessExpression(node.parent) && node.parent.name === node) &&
219
+ !(typescript_1.default.isPropertyAssignment(node.parent) && node.parent.name === node) &&
220
+ !(typescript_1.default.isBindingElement(node.parent) && node.parent.name === node)) {
221
+ recordUsage(node.text);
222
+ }
223
+ }
224
+ typescript_1.default.forEachChild(node, analyzeUsagesInExpression);
225
+ }
226
+ function transformFunctionBody(body, funcName) {
227
+ if (!body)
228
+ return { body, envAssignments: [] };
229
+ const savedScope = currentScope;
230
+ currentScope = createScope('__env');
231
+ // Собираем все декларации в теле функции
232
+ collectDeclarations(body.statements);
233
+ const envAssignments = [];
234
+ const visitor = (node) => {
235
+ // Заменяем this на __this
236
+ if (node.kind === typescript_1.default.SyntaxKind.ThisKeyword) {
237
+ return (0, utils_1.setParentNodes)(factory.createIdentifier('__this'), node.parent);
238
+ }
239
+ // Обрабатываем идентификаторы (доступ к переменным)
240
+ if (typescript_1.default.isIdentifier(node) && node.parent && currentScope) {
241
+ // Не трогаем: объявления переменных, имена функций при декларации, property access справа, параметры
242
+ // Для PropertyAssignment проверяем, что это имя свойства (name), а не значение (initializer)
243
+ if ((typescript_1.default.isVariableDeclaration(node.parent) && node.parent.name === node) ||
244
+ typescript_1.default.isFunctionDeclaration(node.parent) ||
245
+ typescript_1.default.isParameter(node.parent) ||
246
+ (typescript_1.default.isPropertyAccessExpression(node.parent) && node.parent.name === node) ||
247
+ (typescript_1.default.isPropertyAssignment(node.parent) && node.parent.name === node && node !== node.parent.initializer) ||
248
+ (typescript_1.default.isBindingElement(node.parent) && node.parent.name === node)) {
249
+ return node;
250
+ }
251
+ const { envPath, found } = findDeclaration(node.text);
252
+ if (found) {
253
+ // Находим usage для этой переменной
254
+ let scope = currentScope;
255
+ let usage;
256
+ while (scope) {
257
+ if (scope.declarations.has(node.text)) {
258
+ const declScopeId = getScopeId(scope);
259
+ const key = getUsageKey(declScopeId, node.text);
260
+ usage = variableUsages.get(key);
261
+ break;
262
+ }
263
+ scope = scope.parent;
264
+ }
265
+ // Заменяем если:
266
+ // 1. Переменная используется в другом scope
267
+ // 2. Это функция (всегда используем дескриптор)
268
+ if (usage && (isUsedInDifferentScope(node.text) || usage.isFunction)) {
269
+ // console.log(envPath);
270
+ const newEnvPath = (0, utils_1.setParentNodes)(parseEnvPath(envPath), node.parent);
271
+ (0, utils_1.markUntouchable)(newEnvPath.expression);
272
+ // console.log(printAstNode((newEnvPath as ts.PropertyAccessExpression).expression));
273
+ // console.log(newEnvPath.parent);
274
+ return newEnvPath;
275
+ }
276
+ }
277
+ }
278
+ return typescript_1.default.visitEachChild(node, visitor, context);
279
+ };
280
+ const transformedStatements = [];
281
+ for (const stmt of body.statements) {
282
+ // Обрабатываем объявления переменных
283
+ if (typescript_1.default.isVariableStatement(stmt)) {
284
+ const declarations = [];
285
+ for (const decl of stmt.declarationList.declarations) {
286
+ if (typescript_1.default.isIdentifier(decl.name)) {
287
+ const varName = decl.name.text;
288
+ if (isUsedInDifferentScope(varName)) {
289
+ // Переменная используется в другом scope - создаем присваивание в env
290
+ const initializer = decl.initializer
291
+ ? typescript_1.default.visitNode(decl.initializer, visitor)
292
+ : factory.createIdentifier('undefined');
293
+ transformedStatements.push(factory.createExpressionStatement(factory.createAssignment(factory.createPropertyAccessExpression((0, utils_1.markUntouchable)(factory.createIdentifier('__env')), varName), initializer)));
294
+ }
295
+ else {
296
+ // Переменная не используется в других scope - оставляем обычное объявление
297
+ declarations.push(factory.createVariableDeclaration(decl.name, decl.exclamationToken, decl.type, decl.initializer ? typescript_1.default.visitNode(decl.initializer, visitor) : undefined));
298
+ }
299
+ }
300
+ }
301
+ // Если остались обычные декларации, добавляем их
302
+ if (declarations.length > 0) {
303
+ transformedStatements.push(factory.createVariableStatement(stmt.modifiers, factory.createVariableDeclarationList(declarations, stmt.declarationList.flags)));
304
+ }
305
+ }
306
+ // Обрабатываем вложенные функции
307
+ else if (typescript_1.default.isFunctionDeclaration(stmt) && stmt.name) {
308
+ const nestedFuncName = stmt.name.text;
309
+ // Трансформируем тело вложенной функции
310
+ const { body: transformedBody, envAssignments: nestedEnvAssignments } = transformFunctionBody(stmt.body, nestedFuncName);
311
+ // Создаем функцию
312
+ const funcDecl = factory.createFunctionDeclaration(undefined, stmt.asteriskToken, nestedFuncName, stmt.typeParameters, stmt.parameters, stmt.type, transformedBody);
313
+ transformedStatements.push(funcDecl);
314
+ // Добавляем env assignments для переменных внутри вложенной функции
315
+ transformedStatements.push(...nestedEnvAssignments);
316
+ // Создаем дескриптор для вложенной функции
317
+ const descriptorStatements = createFunctionDescriptor(nestedFuncName, '__env');
318
+ transformedStatements.push(...descriptorStatements);
319
+ }
320
+ else {
321
+ transformedStatements.push(typescript_1.default.visitEachChild(stmt, visitor, context));
322
+ }
323
+ }
324
+ currentScope = savedScope;
325
+ return {
326
+ body: factory.createBlock(transformedStatements, true),
327
+ envAssignments
328
+ };
329
+ }
330
+ function visitTopLevel(node) {
331
+ // Импорты уже обработаны в НУЛЕВОМ ПРОХОДЕ, пропускаем их здесь
332
+ if (typescript_1.default.isImportDeclaration(node)) {
333
+ return node;
334
+ }
335
+ // Обрабатываем export { ... }
336
+ if (typescript_1.default.isExportDeclaration(node)) {
337
+ if (!node.exportClause || !typescript_1.default.isNamedExports(node.exportClause)) {
338
+ // export * from '...' - пока не обрабатываем
339
+ return node;
340
+ }
341
+ const result = [];
342
+ for (const element of node.exportClause.elements) {
343
+ const localName = element.propertyName ? element.propertyName.text : element.name.text;
344
+ const exportedName = element.name.text;
345
+ // Находим, где объявлена переменная
346
+ const { envPath, found } = findDeclaration(localName);
347
+ let sourceExpr;
348
+ if (found) {
349
+ // Проверяем, нужно ли использовать env path
350
+ let scope = currentScope;
351
+ let usage;
352
+ while (scope) {
353
+ if (scope.declarations.has(localName)) {
354
+ const declScopeId = getScopeId(scope);
355
+ const key = getUsageKey(declScopeId, localName);
356
+ usage = variableUsages.get(key);
357
+ break;
358
+ }
359
+ scope = scope.parent;
360
+ }
361
+ if (usage && (usage.isFunction || isUsedInDifferentScope(localName))) {
362
+ const topLevelPath = envPath.replace('__env', '__module_env');
363
+ sourceExpr = parseEnvPath(topLevelPath);
364
+ }
365
+ else {
366
+ sourceExpr = factory.createIdentifier(localName);
367
+ }
368
+ }
369
+ else {
370
+ sourceExpr = factory.createIdentifier(localName);
371
+ }
372
+ // __module.exports.exportedName = sourceExpr
373
+ const moduleExportPropertyAccessExpression = factory.createPropertyAccessExpression(factory.createIdentifier('__module'), 'exports');
374
+ result.push(factory.createExpressionStatement(factory.createAssignment(factory.createPropertyAccessExpression((0, utils_1.markUntouchable)(moduleExportPropertyAccessExpression), exportedName), sourceExpr)));
375
+ }
376
+ // Добавляем оригинальное export {} в конец для TypeScript declarations
377
+ result.push(node);
378
+ return result;
379
+ }
380
+ // Обрабатываем export default
381
+ if (typescript_1.default.isExportAssignment(node)) {
382
+ // export default expression
383
+ const topLevelVisitor = (n) => {
384
+ if (typescript_1.default.isIdentifier(n) && n.parent && currentScope) {
385
+ if (typescript_1.default.isVariableDeclaration(n.parent) ||
386
+ typescript_1.default.isFunctionDeclaration(n.parent) ||
387
+ typescript_1.default.isParameter(n.parent) ||
388
+ (typescript_1.default.isPropertyAccessExpression(n.parent) && n.parent.name === n) ||
389
+ (typescript_1.default.isPropertyAssignment(n.parent) && n.parent.name === n && n !== n.parent.initializer) ||
390
+ (typescript_1.default.isBindingElement(n.parent) && n.parent.name === n)) {
391
+ return n;
392
+ }
393
+ const { envPath, found } = findDeclaration(n.text);
394
+ if (found) {
395
+ let scope = currentScope;
396
+ let usage;
397
+ while (scope) {
398
+ if (scope.declarations.has(n.text)) {
399
+ const declScopeId = getScopeId(scope);
400
+ const key = getUsageKey(declScopeId, n.text);
401
+ usage = variableUsages.get(key);
402
+ break;
403
+ }
404
+ scope = scope.parent;
405
+ }
406
+ if (usage && (usage.isFunction || isUsedInDifferentScope(n.text))) {
407
+ const topLevelPath = envPath.replace('__env', '__module_env');
408
+ const newEnvPath = (0, utils_1.setParentNodes)(parseEnvPath(topLevelPath), n.parent);
409
+ (0, utils_1.markUntouchable)(newEnvPath.expression);
410
+ return newEnvPath;
411
+ }
412
+ }
413
+ }
414
+ return typescript_1.default.visitEachChild(n, topLevelVisitor, context);
415
+ };
416
+ const transformedExpression = typescript_1.default.visitNode(node.expression, topLevelVisitor);
417
+ // __module.exports.__default = expression
418
+ const moduleExportPropertyAccessExpression = factory.createPropertyAccessExpression(factory.createIdentifier('__module'), 'exports');
419
+ const exportAssignment = factory.createExpressionStatement(factory.createAssignment(factory.createPropertyAccessExpression((0, utils_1.markUntouchable)(moduleExportPropertyAccessExpression), '__default'), transformedExpression));
420
+ // Возвращаем и присваивание и оригинальный export default для TypeScript
421
+ return [exportAssignment, node];
422
+ }
423
+ // Visitor для замены идентификаторов на top-level
424
+ const topLevelVisitor = (node) => {
425
+ // Обрабатываем идентификаторы (доступ к переменным)
426
+ if (typescript_1.default.isIdentifier(node) && node.parent && currentScope) {
427
+ // Не трогаем: объявления переменных, имена функций при декларации, property access справа, параметры
428
+ // Для PropertyAssignment проверяем, что это имя свойства (name), а не значение (initializer)
429
+ if ((typescript_1.default.isVariableDeclaration(node.parent) && node.parent.name === node) ||
430
+ typescript_1.default.isFunctionDeclaration(node.parent) ||
431
+ typescript_1.default.isParameter(node.parent) ||
432
+ (typescript_1.default.isPropertyAccessExpression(node.parent) && node.parent.name === node) ||
433
+ (typescript_1.default.isPropertyAssignment(node.parent) && node.parent.name === node && node !== node.parent.initializer) ||
434
+ (typescript_1.default.isBindingElement(node.parent) && node.parent.name === node)) {
435
+ return node;
436
+ }
437
+ const { envPath, found } = findDeclaration(node.text);
438
+ if (found) {
439
+ // Находим usage для этой переменной
440
+ let scope = currentScope;
441
+ let usage;
442
+ while (scope) {
443
+ if (scope.declarations.has(node.text)) {
444
+ const declScopeId = getScopeId(scope);
445
+ const key = getUsageKey(declScopeId, node.text);
446
+ usage = variableUsages.get(key);
447
+ break;
448
+ }
449
+ scope = scope.parent;
450
+ }
451
+ // На top-level заменяем если это функция (используем дескриптор)
452
+ // или если переменная используется в другом scope
453
+ if (usage && (usage.isFunction || isUsedInDifferentScope(node.text))) {
454
+ // Для top-level используем __module_env вместо __env
455
+ const topLevelPath = envPath.replace('__env', '__module_env');
456
+ const newEnvPath = (0, utils_1.setParentNodes)(parseEnvPath(topLevelPath), node.parent);
457
+ (0, utils_1.markUntouchable)(newEnvPath.expression);
458
+ // console.log(printAstNode((newEnvPath as ts.PropertyAccessExpression).expression));
459
+ // console.log(newEnvPath.parent);
460
+ return newEnvPath;
461
+ // return setParentNodes(parseEnvPath(topLevelPath), node.parent);
462
+ }
463
+ }
464
+ }
465
+ return typescript_1.default.visitEachChild(node, topLevelVisitor, context);
466
+ };
467
+ // Обрабатываем top-level функции
468
+ if (typescript_1.default.isFunctionDeclaration(node) && node.name) {
469
+ const funcName = node.name.text;
470
+ const isExported = node.modifiers?.some(mod => mod.kind === typescript_1.default.SyntaxKind.ExportKeyword) || false;
471
+ // Добавляем в module scope
472
+ if (!currentScope) {
473
+ currentScope = createScope('__module_env');
474
+ }
475
+ addDeclaration(funcName);
476
+ // Трансформируем тело функции
477
+ const { body: transformedBody, envAssignments } = transformFunctionBody(node.body, funcName);
478
+ // Создаем функцию сохраняя export модификатор
479
+ const funcDecl = factory.createFunctionDeclaration(node.modifiers, // сохраняем модификаторы включая export
480
+ node.asteriskToken, funcName, node.typeParameters, node.parameters, node.type, transformedBody);
481
+ const result = [funcDecl];
482
+ // Добавляем env assignments для переменных внутри функции
483
+ result.push(...envAssignments);
484
+ // Создаем дескриптор (с флагом isExported)
485
+ const descriptorStatements = createFunctionDescriptor(funcName, '__module_env', isExported);
486
+ result.push(...descriptorStatements);
487
+ return result;
488
+ }
489
+ // Обрабатываем top-level переменные
490
+ if (typescript_1.default.isVariableStatement(node)) {
491
+ if (!currentScope) {
492
+ currentScope = createScope('__module_env');
493
+ }
494
+ const isExported = node.modifiers?.some(mod => mod.kind === typescript_1.default.SyntaxKind.ExportKeyword) || false;
495
+ const result = [];
496
+ const declarations = [];
497
+ for (const decl of node.declarationList.declarations) {
498
+ if (typescript_1.default.isIdentifier(decl.name)) {
499
+ const varName = decl.name.text;
500
+ addDeclaration(varName);
501
+ if (isUsedInDifferentScope(varName)) {
502
+ // Переменная используется в другом scope - не создаем обычное объявление
503
+ // вместо этого сразу записываем в env
504
+ const initializer = decl.initializer
505
+ ? typescript_1.default.visitNode(decl.initializer, topLevelVisitor)
506
+ : factory.createIdentifier('undefined');
507
+ result.push(factory.createExpressionStatement(factory.createAssignment(factory.createPropertyAccessExpression((0, utils_1.markUntouchable)(factory.createIdentifier('__module_env')), varName), initializer)));
508
+ }
509
+ else {
510
+ // Переменная не используется в других scope - оставляем обычное объявление
511
+ const visitedDecl = factory.createVariableDeclaration(decl.name, decl.exclamationToken, decl.type, decl.initializer ? typescript_1.default.visitNode(decl.initializer, topLevelVisitor) : undefined);
512
+ declarations.push(visitedDecl);
513
+ }
514
+ // Если экспортируется, добавляем __module.exports.varName = varName или __module_env.varName
515
+ if (isExported) {
516
+ const moduleExportPropertyAccessExpression = factory.createPropertyAccessExpression(factory.createIdentifier('__module'), 'exports');
517
+ // Если переменная захвачена в __module_env, берем ее оттуда
518
+ const sourceExpr = isUsedInDifferentScope(varName)
519
+ ? factory.createPropertyAccessExpression(factory.createIdentifier('__module_env'), varName)
520
+ : factory.createIdentifier(varName);
521
+ result.push(factory.createExpressionStatement(factory.createAssignment(factory.createPropertyAccessExpression((0, utils_1.markUntouchable)(moduleExportPropertyAccessExpression), varName), sourceExpr)));
522
+ }
523
+ }
524
+ }
525
+ // Если остались обычные декларации, добавляем их первыми (сохраняя export модификатор)
526
+ if (declarations.length > 0) {
527
+ result.unshift(factory.createVariableStatement(node.modifiers, // сохраняем модификаторы включая export
528
+ factory.createVariableDeclarationList(declarations, node.declarationList.flags)));
529
+ }
530
+ return result.length > 0 ? result : node;
531
+ }
532
+ // Для всех остальных top-level statements применяем visitor
533
+ return typescript_1.default.visitEachChild(node, topLevelVisitor, context);
534
+ }
535
+ // НУЛЕВОЙ ПРОХОД: Трансформируем импорты в переменные
536
+ function transformImports(statements) {
537
+ const result = [];
538
+ for (const statement of statements) {
539
+ if (typescript_1.default.isImportDeclaration(statement)) {
540
+ const moduleSpecifier = statement.moduleSpecifier;
541
+ if (!typescript_1.default.isStringLiteral(moduleSpecifier)) {
542
+ result.push(statement);
543
+ continue;
544
+ }
545
+ const modulePath = moduleSpecifier.text;
546
+ // Генерируем имя переменной для модуля
547
+ const moduleVarName = `__module_${modulePath.replace(/[^a-zA-Z0-9]/g, '_')}`;
548
+ // var moduleVarName = bt.require(modulePath, UrlParent(AbsoluteUrl("dummy")))
549
+ const requireCall = (factory.createCallExpression((0, utils_1.markUntouchable)(factory.createPropertyAccessExpression(factory.createIdentifier('bt'), factory.createIdentifier('require'))), undefined, [
550
+ factory.createStringLiteral(modulePath),
551
+ factory.createCallExpression(factory.createIdentifier('UrlParent'), undefined, [
552
+ factory.createCallExpression(factory.createIdentifier('__AbsoluteUrl'), undefined, [factory.createStringLiteral('dummy')])
553
+ ])
554
+ ]));
555
+ result.push(factory.createVariableStatement(undefined, factory.createVariableDeclarationList([factory.createVariableDeclaration(moduleVarName, undefined, undefined, requireCall)], typescript_1.default.NodeFlags.None)));
556
+ // Обрабатываем import clause
557
+ if (statement.importClause) {
558
+ // import X from "Y" -> var X = moduleY.__default
559
+ if (statement.importClause.name) {
560
+ const importName = statement.importClause.name.text;
561
+ // Пропускаем импорты типов
562
+ if (!isTypeOnlyImport(statement.importClause.name)) {
563
+ result.push(factory.createVariableStatement(undefined, factory.createVariableDeclarationList([factory.createVariableDeclaration(importName, undefined, undefined, factory.createPropertyAccessExpression(factory.createIdentifier(moduleVarName), '__default'))], typescript_1.default.NodeFlags.None)));
564
+ }
565
+ }
566
+ // import { a, b as c } from "Y"
567
+ if (statement.importClause.namedBindings && typescript_1.default.isNamedImports(statement.importClause.namedBindings)) {
568
+ for (const element of statement.importClause.namedBindings.elements) {
569
+ const importedName = element.propertyName ? element.propertyName.text : element.name.text;
570
+ const localName = element.name.text;
571
+ // Пропускаем импорты типов
572
+ if (!isTypeOnlyImport(element.name)) {
573
+ result.push(factory.createVariableStatement(undefined, factory.createVariableDeclarationList([factory.createVariableDeclaration(localName, undefined, undefined, factory.createPropertyAccessExpression(factory.createIdentifier(moduleVarName), importedName))], typescript_1.default.NodeFlags.None)));
574
+ }
575
+ }
576
+ }
577
+ // import * as ns from "Y"
578
+ if (statement.importClause.namedBindings && typescript_1.default.isNamespaceImport(statement.importClause.namedBindings)) {
579
+ const namespaceName = statement.importClause.namedBindings.name.text;
580
+ result.push(factory.createVariableStatement(undefined, factory.createVariableDeclarationList([factory.createVariableDeclaration(namespaceName, undefined, undefined, factory.createIdentifier(moduleVarName))], typescript_1.default.NodeFlags.None)));
581
+ }
582
+ }
583
+ }
584
+ else {
585
+ result.push(statement);
586
+ }
587
+ }
588
+ return result.map(stmt => (0, utils_1.setParentNodes)(stmt));
589
+ }
590
+ // Трансформируем импорты перед анализом
591
+ const statementsWithTransformedImports = transformImports(sourceFile.statements);
592
+ // ПЕРВЫЙ ПРОХОД: Собираем все top-level декларации и анализируем использование
593
+ currentScope = createScope('__module_env');
594
+ collectDeclarations(statementsWithTransformedImports);
595
+ for (const statement of statementsWithTransformedImports) {
596
+ analyzeUsages(statement);
597
+ }
598
+ // ВТОРОЙ ПРОХОД: Трансформируем
599
+ // Сбрасываем счетчик scope ID и создаем новый module scope
600
+ scopeIdCounter = 0;
601
+ currentScope = createScope('__module_env');
602
+ collectDeclarations(statementsWithTransformedImports);
603
+ // Трансформируем все statements
604
+ const transformedStatements = [];
605
+ for (const statement of statementsWithTransformedImports) {
606
+ const result = visitTopLevel(statement);
607
+ if (Array.isArray(result)) {
608
+ transformedStatements.push(...result);
609
+ }
610
+ else if (result) {
611
+ transformedStatements.push(result);
612
+ }
613
+ }
614
+ const newStatements = [moduleEnvDecl, ...transformedStatements];
615
+ newStatements.forEach(stmt => (0, utils_1.setParentNodes)(stmt, sourceFile));
616
+ // Возвращаем файл с __module_env в начале и трансформированными statements
617
+ return (0, utils_1.preserveSymbolsFrom)(factory.updateSourceFile(sourceFile, [moduleEnvDecl, ...transformedStatements]), sourceFile);
618
+ };
619
+ };
620
+ }