@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,222 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.default = arrayGeneralTransformer;
37
+ const ts = __importStar(require("typescript"));
38
+ const utils_1 = require("./utils");
39
+ function makeArrayPolyfillExpression(functionName) {
40
+ return (0, utils_1.markUntouchable)(ts.factory.createPropertyAccessExpression(ts.factory.createPropertyAccessExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('bt'), ts.factory.createIdentifier('polyfill')), ts.factory.createIdentifier('Array')), ts.factory.createIdentifier(functionName)));
41
+ }
42
+ function collectArgs(expression, node, count, restAsArray = false, visitor = undefined) {
43
+ const args = [expression];
44
+ if (count !== undefined) {
45
+ const positionalEnd = restAsArray ? count - 2 : count - 1;
46
+ for (let i = 0; i < positionalEnd; i++) {
47
+ args.push(node.arguments[i] || ts.factory.createIdentifier('undefined'));
48
+ }
49
+ if (restAsArray) {
50
+ const restArgs = node.arguments.slice(positionalEnd);
51
+ args.push(ts.factory.createArrayLiteralExpression(restArgs));
52
+ }
53
+ }
54
+ else {
55
+ args.push(...node.arguments);
56
+ }
57
+ if (visitor !== undefined) {
58
+ for (let i = 0; i < args.length; i++) {
59
+ args[i] = ts.visitNode(args[i], visitor);
60
+ }
61
+ }
62
+ return args;
63
+ }
64
+ function arrayGeneralTransformer(program) {
65
+ return (context) => (file) => {
66
+ const typeChecker = program.getTypeChecker();
67
+ function visit(node) {
68
+ // Check for method calls on arrays
69
+ if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression)) {
70
+ const expression = node.expression.expression;
71
+ const type = typeChecker.getTypeAtLocation(expression);
72
+ // Check if the type is an array or array-like
73
+ const isArrayType = typeChecker.typeToString(type).includes('[]') ||
74
+ ((type.flags & ts.TypeFlags.Object) !== 0 && typeChecker.getIndexTypeOfType(type, ts.IndexKind.Number) !== undefined);
75
+ if (isArrayType) {
76
+ if (node.expression.name.text === 'at') {
77
+ const args = collectArgs(expression, node, 2, false, visit);
78
+ return ts.factory.createCallExpression(makeArrayPolyfillExpression('at'), undefined, args);
79
+ }
80
+ if (node.expression.name.text === 'concat') {
81
+ const args = collectArgs(expression, node, undefined, false, visit);
82
+ return ts.factory.createCallExpression(ts.factory.createIdentifier('ArrayUnion'), undefined, args);
83
+ }
84
+ if (node.expression.name.text === 'copyWithin') {
85
+ const args = collectArgs(expression, node, 4, false, visit);
86
+ return ts.factory.createCallExpression(makeArrayPolyfillExpression('copyWithin'), undefined, args);
87
+ }
88
+ if (node.expression.name.text === 'entries') {
89
+ const args = collectArgs(expression, node, 1, false, visit);
90
+ return ts.factory.createCallExpression(makeArrayPolyfillExpression('entries'), undefined, args);
91
+ }
92
+ if (node.expression.name.text === 'fill') {
93
+ const args = collectArgs(expression, node, 4, false, visit);
94
+ return ts.factory.createCallExpression(makeArrayPolyfillExpression('fill'), undefined, args);
95
+ }
96
+ if (node.expression.name.text === 'flat') {
97
+ const args = collectArgs(expression, node, 2, false, visit);
98
+ return ts.factory.createCallExpression(makeArrayPolyfillExpression('flat'), undefined, args);
99
+ }
100
+ if (node.expression.name.text === 'includes') {
101
+ const args = collectArgs(expression, node, 3, false, visit);
102
+ return ts.factory.createCallExpression(makeArrayPolyfillExpression('includes'), undefined, args);
103
+ }
104
+ if (node.expression.name.text === 'indexOf') {
105
+ const args = collectArgs(expression, node, 3, false, visit);
106
+ return ts.factory.createCallExpression(makeArrayPolyfillExpression('indexOf'), undefined, args);
107
+ }
108
+ if (node.expression.name.text === 'join') {
109
+ const args = collectArgs(expression, node, 2, false, visit);
110
+ return ts.factory.createCallExpression(makeArrayPolyfillExpression('join'), undefined, args);
111
+ }
112
+ if (node.expression.name.text === 'keys') {
113
+ const args = collectArgs(expression, node, 1, false, visit);
114
+ return ts.factory.createCallExpression(makeArrayPolyfillExpression('keys'), undefined, args);
115
+ }
116
+ if (node.expression.name.text === 'lastIndexOf') {
117
+ const args = collectArgs(expression, node, 3, false, visit);
118
+ return ts.factory.createCallExpression(makeArrayPolyfillExpression('lastIndexOf'), undefined, args);
119
+ }
120
+ if (node.expression.name.text === 'pop') {
121
+ const args = collectArgs(expression, node, 1, false, visit);
122
+ return ts.factory.createCallExpression(makeArrayPolyfillExpression('pop'), undefined, args);
123
+ }
124
+ // if (node.expression.name.text === 'push') {
125
+ // const args = collectArgs(expression, node, 1);
126
+ // return ts.factory.createCallExpression(
127
+ // makeArrayPolyfillExpression('push'),
128
+ // undefined,
129
+ // args
130
+ // );
131
+ // }
132
+ if (node.expression.name.text === 'reverse') {
133
+ const args = collectArgs(expression, node, 1, false, visit);
134
+ return ts.factory.createCallExpression(makeArrayPolyfillExpression('reverse'), undefined, args);
135
+ }
136
+ if (node.expression.name.text === 'shift') {
137
+ const args = collectArgs(expression, node, 1, false, visit);
138
+ return ts.factory.createCallExpression(makeArrayPolyfillExpression('shift'), undefined, args);
139
+ }
140
+ if (node.expression.name.text === 'slice') {
141
+ const args = collectArgs(expression, node, 3, false, visit);
142
+ return ts.factory.createCallExpression(makeArrayPolyfillExpression('slice'), undefined, args);
143
+ }
144
+ if (node.expression.name.text === 'splice') {
145
+ const args = collectArgs(expression, node, 4, true, visit);
146
+ return ts.factory.createCallExpression(makeArrayPolyfillExpression('splice'), undefined, args);
147
+ }
148
+ // if (node.expression.name.text === 'sort') {
149
+ // const args = collectArgs(expression, node, 3);
150
+ // return ts.factory.createCallExpression(
151
+ // makeArrayPolyfillExpression('sort'),
152
+ // undefined,
153
+ // args
154
+ // );
155
+ // }
156
+ if (node.expression.name.text === 'toReversed') {
157
+ const args = collectArgs(expression, node, 1, false, visit);
158
+ return ts.factory.createCallExpression(makeArrayPolyfillExpression('toReversed'), undefined, args);
159
+ }
160
+ // if (node.expression.name.text === 'toSorted') {
161
+ // const args = collectArgs(expression, node, 3);
162
+ // return ts.factory.createCallExpression(
163
+ // makeArrayPolyfillExpression('toSorted'),
164
+ // undefined,
165
+ // args
166
+ // );
167
+ // }
168
+ if (node.expression.name.text === 'toSpliced') {
169
+ const args = collectArgs(expression, node, 4, true, visit);
170
+ return ts.factory.createCallExpression(makeArrayPolyfillExpression('toSpliced'), undefined, args);
171
+ }
172
+ if (node.expression.name.text === 'unshift') {
173
+ const args = collectArgs(expression, node, 2, true, visit);
174
+ return ts.factory.createCallExpression(makeArrayPolyfillExpression('unshift'), undefined, args);
175
+ }
176
+ if (node.expression.name.text === 'values') {
177
+ const args = collectArgs(expression, node, 1, false, visit);
178
+ return ts.factory.createCallExpression(makeArrayPolyfillExpression('values'), undefined, args);
179
+ }
180
+ if (node.expression.name.text === 'with') {
181
+ const args = collectArgs(expression, node, 3, false, visit);
182
+ return ts.factory.createCallExpression(makeArrayPolyfillExpression('_with'), undefined, args);
183
+ }
184
+ }
185
+ }
186
+ // Check for .length property access
187
+ if (ts.isPropertyAccessExpression(node) && node.name.text === 'length') {
188
+ const expression = node.expression;
189
+ const type = typeChecker.getTypeAtLocation(expression);
190
+ // Check if the type is an array or array-like
191
+ const isArrayType = typeChecker.typeToString(type).includes('[]') ||
192
+ ((type.flags & ts.TypeFlags.Object) !== 0 && typeChecker.getIndexTypeOfType(type, ts.IndexKind.Number) !== undefined);
193
+ if (isArrayType) {
194
+ // Replace arr.length with ArrayCount(arr)
195
+ return ts.factory.createCallExpression(ts.factory.createIdentifier('ArrayCount'), undefined, [expression]);
196
+ }
197
+ }
198
+ // Check for Array.isArray and Array.from calls
199
+ if (ts.isCallExpression(node)) {
200
+ const expression = node.expression;
201
+ if (ts.isPropertyAccessExpression(expression) &&
202
+ expression.name.text === 'isArray' &&
203
+ ts.isIdentifier(expression.expression) &&
204
+ expression.expression.text === 'Array') {
205
+ // Replace Array.isArray(value) with IsArray(value)
206
+ return ts.factory.createCallExpression(ts.factory.createIdentifier('IsArray'), undefined, node.arguments);
207
+ }
208
+ if (ts.isPropertyAccessExpression(expression) &&
209
+ expression.name.text === 'from' &&
210
+ ts.isIdentifier(expression.expression) &&
211
+ expression.expression.text === 'Array') {
212
+ // Replace Array.from(value) with ArraySelectAll(value)
213
+ return ts.factory.createCallExpression(ts.factory.createIdentifier('ArraySelectAll'), undefined, node.arguments);
214
+ }
215
+ }
216
+ // Recursively visit child nodes
217
+ return ts.visitEachChild(node, visit, context);
218
+ }
219
+ const transformedFile = ts.visitNode(file, visit);
220
+ return ts.factory.updateSourceFile(transformedFile, transformedFile.statements);
221
+ };
222
+ }
@@ -0,0 +1,212 @@
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.blockScopingTransformer = blockScopingTransformer;
7
+ const typescript_1 = __importDefault(require("typescript"));
8
+ /**
9
+ * Трансформер для преобразования let/const в var.
10
+ *
11
+ * Обрабатывает:
12
+ * 1. Простая замена let/const → var
13
+ * 2. Shadowing detection — переименование при конфликтах имён
14
+ *
15
+ * НЕ обрабатывает (MVP):
16
+ * - Замыкания в циклах (IIFE wrapper)
17
+ * - TDZ (Temporal Dead Zone) — TypeScript проверяет
18
+ * - Const violations — TypeScript проверяет
19
+ *
20
+ * @example
21
+ * // Вход:
22
+ * let x = 1;
23
+ * const y = 2;
24
+ * {
25
+ * let x = 3; // shadowing
26
+ * }
27
+ *
28
+ * // Выход:
29
+ * var x = 1;
30
+ * var y = 2;
31
+ * {
32
+ * var x_1 = 3; // переименовано
33
+ * }
34
+ *
35
+ * @returns TypeScript transformer factory
36
+ */
37
+ function blockScopingTransformer() {
38
+ return (context) => {
39
+ return (sourceFile) => {
40
+ // Счётчик для генерации уникальных имён
41
+ let uidCounter = 0;
42
+ const generateUid = (name) => `${name}_${++uidCounter}`;
43
+ const scopeStack = [];
44
+ // Текущие переименования для данного scope
45
+ const pushScope = () => scopeStack.push(new Map());
46
+ const popScope = () => scopeStack.pop();
47
+ /**
48
+ * Получить текущее имя переменной с учётом переименований
49
+ */
50
+ const resolveName = (name) => {
51
+ // Ищем снизу вверх (от внутреннего scope к внешнему)
52
+ for (let i = scopeStack.length - 1; i >= 0; i--) {
53
+ const renamed = scopeStack[i].get(name);
54
+ if (renamed !== undefined) {
55
+ return renamed;
56
+ }
57
+ }
58
+ return name;
59
+ };
60
+ /**
61
+ * Проверить, есть ли переменная в родительских scopes (для shadowing detection)
62
+ */
63
+ const hasInParentScopes = (name) => {
64
+ for (let i = scopeStack.length - 2; i >= 0; i--) {
65
+ if (scopeStack[i].has(name)) {
66
+ return true;
67
+ }
68
+ }
69
+ return false;
70
+ };
71
+ /**
72
+ * Зарегистрировать переменную в текущем scope
73
+ * Возвращает новое имя если было переименование, иначе оригинальное
74
+ */
75
+ const registerVariable = (name) => {
76
+ const currentScope = scopeStack[scopeStack.length - 1];
77
+ if (!currentScope)
78
+ return name;
79
+ // Проверяем shadowing
80
+ if (hasInParentScopes(name)) {
81
+ const newName = generateUid(name);
82
+ currentScope.set(name, newName);
83
+ return newName;
84
+ }
85
+ // Нет shadowing — регистрируем с оригинальным именем
86
+ currentScope.set(name, name);
87
+ return name;
88
+ };
89
+ /**
90
+ * Проверяем, является ли узел началом нового block scope
91
+ */
92
+ const isBlockScopeNode = (node) => {
93
+ return typescript_1.default.isBlock(node) ||
94
+ typescript_1.default.isForStatement(node) ||
95
+ typescript_1.default.isForInStatement(node) ||
96
+ typescript_1.default.isForOfStatement(node) ||
97
+ typescript_1.default.isCaseClause(node) ||
98
+ typescript_1.default.isDefaultClause(node);
99
+ };
100
+ /**
101
+ * Проверяем, является ли узел function scope (var hoisting boundary)
102
+ */
103
+ const isFunctionScopeNode = (node) => {
104
+ return typescript_1.default.isFunctionDeclaration(node) ||
105
+ typescript_1.default.isFunctionExpression(node) ||
106
+ typescript_1.default.isArrowFunction(node) ||
107
+ typescript_1.default.isMethodDeclaration(node) ||
108
+ typescript_1.default.isSourceFile(node);
109
+ };
110
+ /**
111
+ * Обрабатываем VariableDeclarationList
112
+ */
113
+ const transformVariableDeclarationList = (node) => {
114
+ const isLet = (node.flags & typescript_1.default.NodeFlags.Let) !== 0;
115
+ const isConst = (node.flags & typescript_1.default.NodeFlags.Const) !== 0;
116
+ if (!isLet && !isConst) {
117
+ // Уже var — просто обходим дочерние узлы
118
+ return typescript_1.default.factory.updateVariableDeclarationList(node, node.declarations.map(decl => typescript_1.default.visitNode(decl, visitor)));
119
+ }
120
+ // Преобразуем let/const → var
121
+ const newDeclarations = node.declarations.map(decl => {
122
+ if (typescript_1.default.isIdentifier(decl.name)) {
123
+ const originalName = decl.name.text;
124
+ const newName = registerVariable(originalName);
125
+ // Рекурсивно обрабатываем initializer
126
+ const newInitializer = decl.initializer
127
+ ? typescript_1.default.visitNode(decl.initializer, visitor)
128
+ : undefined;
129
+ if (newName !== originalName) {
130
+ // Переименовываем
131
+ return typescript_1.default.factory.createVariableDeclaration(typescript_1.default.factory.createIdentifier(newName), undefined, undefined, newInitializer);
132
+ }
133
+ else {
134
+ return typescript_1.default.factory.createVariableDeclaration(decl.name, undefined, undefined, newInitializer);
135
+ }
136
+ }
137
+ // TODO: BindingPattern (деструктуризация) — пока просто обходим
138
+ return typescript_1.default.visitNode(decl, visitor);
139
+ });
140
+ // Создаём var declaration
141
+ return typescript_1.default.factory.createVariableDeclarationList(newDeclarations, typescript_1.default.NodeFlags.None // var
142
+ );
143
+ };
144
+ /**
145
+ * Основной visitor
146
+ */
147
+ const visitor = (node) => {
148
+ // Начало function scope — полностью новый контекст для var
149
+ if (isFunctionScopeNode(node) && !typescript_1.default.isSourceFile(node)) {
150
+ pushScope();
151
+ const result = typescript_1.default.visitEachChild(node, visitor, context);
152
+ popScope();
153
+ return result;
154
+ }
155
+ // Начало block scope
156
+ if (isBlockScopeNode(node)) {
157
+ pushScope();
158
+ const result = typescript_1.default.visitEachChild(node, visitor, context);
159
+ popScope();
160
+ return result;
161
+ }
162
+ // Обрабатываем VariableDeclarationList
163
+ if (typescript_1.default.isVariableDeclarationList(node)) {
164
+ return transformVariableDeclarationList(node);
165
+ }
166
+ // Переименовываем использования переменных
167
+ if (typescript_1.default.isIdentifier(node)) {
168
+ const parent = node.parent;
169
+ // Пропускаем случаи где identifier — не ссылка на переменную:
170
+ // - объявления (обрабатываются в transformVariableDeclarationList)
171
+ // - property access: obj.prop
172
+ // - property name в объектном литерале: { prop: value }
173
+ // - parameter names (обрабатываются отдельно)
174
+ if (parent) {
175
+ // obj.prop — prop не переменная
176
+ if (typescript_1.default.isPropertyAccessExpression(parent) && parent.name === node) {
177
+ return node;
178
+ }
179
+ // { prop: value } — prop не переменная
180
+ if (typescript_1.default.isPropertyAssignment(parent) && parent.name === node) {
181
+ return node;
182
+ }
183
+ // function foo() — foo обрабатывается отдельно
184
+ if (typescript_1.default.isFunctionDeclaration(parent) && parent.name === node) {
185
+ return node;
186
+ }
187
+ // let x = ... — x обрабатывается в transformVariableDeclarationList
188
+ if (typescript_1.default.isVariableDeclaration(parent) && parent.name === node) {
189
+ return node;
190
+ }
191
+ // (param) => ... — param не let/const
192
+ if (typescript_1.default.isParameter(parent) && parent.name === node) {
193
+ return node;
194
+ }
195
+ }
196
+ // Проверяем, нужно ли переименовать
197
+ const originalName = node.text;
198
+ const resolvedName = resolveName(originalName);
199
+ if (resolvedName !== originalName) {
200
+ return typescript_1.default.factory.createIdentifier(resolvedName);
201
+ }
202
+ }
203
+ return typescript_1.default.visitEachChild(node, visitor, context);
204
+ };
205
+ // Инициализируем глобальный scope
206
+ pushScope();
207
+ const result = typescript_1.default.visitNode(sourceFile, visitor);
208
+ popScope();
209
+ return result;
210
+ };
211
+ };
212
+ }
@@ -0,0 +1,133 @@
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.destructuringTransformer = destructuringTransformer;
7
+ const typescript_1 = __importDefault(require("typescript"));
8
+ /**
9
+ * Трансформер для преобразования деструктуризации объектов и массивов.
10
+ *
11
+ * @example
12
+ * // Вход (объект):
13
+ * const { a, b, ...rest } = obj;
14
+ *
15
+ * // Выход:
16
+ * const a = obj.a;
17
+ * const b = obj.b;
18
+ * const rest = bt.object_rest(obj, ["a", "b"]);
19
+ *
20
+ * @example
21
+ * // Вход (массив):
22
+ * const [x, y, ...rest] = arr;
23
+ *
24
+ * // Выход:
25
+ * const _arr = ArrayDirect(arr);
26
+ * const x = _arr[0];
27
+ * const y = _arr[1];
28
+ * const rest = bt.array_rest(_arr, 2);
29
+ *
30
+ * @returns TypeScript transformer factory
31
+ */
32
+ function destructuringTransformer() {
33
+ return (context) => {
34
+ let uidCounter = 0;
35
+ /**
36
+ * Генерирует уникальный идентификатор
37
+ */
38
+ const generateUid = (prefix) => {
39
+ return typescript_1.default.factory.createIdentifier(`_${prefix}${uidCounter++}`);
40
+ };
41
+ return (sourceFile) => {
42
+ const visitor = (node) => {
43
+ // Обрабатываем объявления переменных
44
+ if (typescript_1.default.isVariableStatement(node)) {
45
+ const declarations = node.declarationList.declarations;
46
+ const newStatements = [];
47
+ let hasDestructuring = false;
48
+ for (const declarator of declarations) {
49
+ // Обрабатываем деструктуризацию объекта
50
+ if (typescript_1.default.isObjectBindingPattern(declarator.name) && declarator.initializer) {
51
+ hasDestructuring = true;
52
+ const init = typescript_1.default.visitNode(declarator.initializer, visitor);
53
+ const excludedKeys = [];
54
+ for (const element of declarator.name.elements) {
55
+ if (typescript_1.default.isBindingElement(element)) {
56
+ if (element.dotDotDotToken) {
57
+ // Rest element: ...rest
58
+ const restName = element.name;
59
+ const restCall = typescript_1.default.factory.createCallExpression(typescript_1.default.factory.createPropertyAccessExpression(typescript_1.default.factory.createIdentifier('bt'), 'object_rest'), undefined, [
60
+ init,
61
+ typescript_1.default.factory.createArrayLiteralExpression(excludedKeys.map(k => typescript_1.default.factory.createStringLiteral(k)))
62
+ ]);
63
+ newStatements.push(createVarStatement(restName.text, restCall));
64
+ }
65
+ else {
66
+ // Regular property: { a } or { a: b }
67
+ const propertyName = element.propertyName
68
+ ? element.propertyName.text
69
+ : element.name.text;
70
+ const variableName = element.name.text;
71
+ excludedKeys.push(propertyName);
72
+ const memberAccess = typescript_1.default.factory.createPropertyAccessExpression(init, propertyName);
73
+ newStatements.push(createVarStatement(variableName, memberAccess));
74
+ }
75
+ }
76
+ }
77
+ }
78
+ // Обрабатываем деструктуризацию массива
79
+ else if (typescript_1.default.isArrayBindingPattern(declarator.name) && declarator.initializer) {
80
+ hasDestructuring = true;
81
+ const init = typescript_1.default.visitNode(declarator.initializer, visitor);
82
+ // Создаём вспомогательную переменную: var _arr = ArrayDirect(init)
83
+ const auxVar = generateUid('arr');
84
+ const auxCall = typescript_1.default.factory.createCallExpression(typescript_1.default.factory.createIdentifier('ArrayDirect'), undefined, [init]);
85
+ newStatements.push(createVarStatement(auxVar.text, auxCall));
86
+ // Обрабатываем элементы массива
87
+ let index = 0;
88
+ for (const element of declarator.name.elements) {
89
+ if (typescript_1.default.isOmittedExpression(element)) {
90
+ // Пропущенный элемент [, , x]
91
+ index++;
92
+ continue;
93
+ }
94
+ if (typescript_1.default.isBindingElement(element)) {
95
+ if (element.dotDotDotToken) {
96
+ // Rest element: ...rest
97
+ const restName = element.name;
98
+ const restCall = typescript_1.default.factory.createCallExpression(typescript_1.default.factory.createPropertyAccessExpression(typescript_1.default.factory.createIdentifier('bt'), 'array_rest'), undefined, [auxVar, typescript_1.default.factory.createNumericLiteral(index)]);
99
+ newStatements.push(createVarStatement(restName.text, restCall));
100
+ }
101
+ else {
102
+ // Regular element: [a, b]
103
+ const variableName = element.name.text;
104
+ const elementAccess = typescript_1.default.factory.createElementAccessExpression(auxVar, typescript_1.default.factory.createNumericLiteral(index));
105
+ newStatements.push(createVarStatement(variableName, elementAccess));
106
+ index++;
107
+ }
108
+ }
109
+ }
110
+ }
111
+ // Обычные объявления - оставляем как есть
112
+ else {
113
+ const visitedDeclarator = typescript_1.default.visitNode(declarator, visitor);
114
+ newStatements.push(typescript_1.default.factory.createVariableStatement(undefined, typescript_1.default.factory.createVariableDeclarationList([visitedDeclarator], typescript_1.default.NodeFlags.None)));
115
+ }
116
+ }
117
+ if (hasDestructuring) {
118
+ return newStatements;
119
+ }
120
+ }
121
+ return typescript_1.default.visitEachChild(node, visitor, context);
122
+ };
123
+ return typescript_1.default.visitNode(sourceFile, visitor);
124
+ };
125
+ };
126
+ }
127
+ /**
128
+ * Создаёт var statement: var name = initializer;
129
+ */
130
+ function createVarStatement(name, initializer) {
131
+ return typescript_1.default.factory.createVariableStatement(undefined, typescript_1.default.factory.createVariableDeclarationList([typescript_1.default.factory.createVariableDeclaration(name, undefined, undefined, initializer)], typescript_1.default.NodeFlags.None // var
132
+ ));
133
+ }
@@ -0,0 +1,79 @@
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.dirnameTransformer = dirnameTransformer;
7
+ const typescript_1 = __importDefault(require("typescript"));
8
+ const utils_1 = require("./utils");
9
+ function dirnameTransformer() {
10
+ return (context) => (sourceFile) => {
11
+ const factory = context.factory;
12
+ const isExecObj = (0, utils_1.isExecutableObject)(sourceFile);
13
+ const execObjKey = isExecObj ? (0, utils_1.getExecutableObjectKey)(sourceFile) : undefined;
14
+ // console.log(`dirnameTransformer: isExecObj=${isExecObj}, execObjKey=${execObjKey}`);
15
+ let hasAbsoluteUrlCalls = true;
16
+ // Рекурсивная функция для обхода и трансформации дерева
17
+ const visitor = (node) => {
18
+ // Проверяем, является ли узел вызовом функции AbsoluteUrl
19
+ if (typescript_1.default.isCallExpression(node) &&
20
+ typescript_1.default.isIdentifier(node.expression) &&
21
+ node.expression.text === 'AbsoluteUrl') {
22
+ hasAbsoluteUrlCalls = true;
23
+ // Заменяем на __AbsoluteUrl
24
+ const args = node.arguments;
25
+ const newArgs = [];
26
+ if (args.length >= 1) {
27
+ newArgs.push(args[0]); // url
28
+ }
29
+ if (args.length >= 2) {
30
+ newArgs.push(args[1]); // baseUrl
31
+ }
32
+ else {
33
+ // Если baseUrl не указан, добавляем undefined
34
+ newArgs.push(factory.createIdentifier('undefined'));
35
+ }
36
+ return factory.updateCallExpression(node, factory.createIdentifier('__AbsoluteUrl'), node.typeArguments, newArgs);
37
+ }
38
+ return typescript_1.default.visitEachChild(node, visitor, context);
39
+ };
40
+ // Обходим файл
41
+ const transformedSourceFile = typescript_1.default.visitNode(sourceFile, visitor);
42
+ // Если были вызовы AbsoluteUrl, добавляем функцию __AbsoluteUrl
43
+ if (hasAbsoluteUrlCalls) {
44
+ let functionBody;
45
+ if (isExecObj && execObjKey !== undefined) {
46
+ // Для executable object: если baseUrl === undefined, используем UrlAppendPath(UrlParent(bt.getFileUrl(KEY)), url)
47
+ functionBody = factory.createReturnStatement(factory.createConditionalExpression(factory.createBinaryExpression(factory.createIdentifier('baseUrl'), factory.createToken(typescript_1.default.SyntaxKind.EqualsEqualsEqualsToken), factory.createIdentifier('undefined')), factory.createToken(typescript_1.default.SyntaxKind.QuestionToken), factory.createCallExpression(factory.createIdentifier('UrlAppendPath'), undefined, [
48
+ factory.createCallExpression(factory.createIdentifier('UrlParent'), undefined, [
49
+ (0, utils_1.markUntouchable)(factory.createCallExpression(factory.createPropertyAccessExpression(factory.createIdentifier('bt'), 'getFileUrl'), undefined, [factory.createStringLiteral(execObjKey)]))
50
+ ]),
51
+ factory.createIdentifier('url')
52
+ ]), factory.createToken(typescript_1.default.SyntaxKind.ColonToken), factory.createCallExpression(factory.createIdentifier('AbsoluteUrl'), undefined, [
53
+ factory.createIdentifier('url'),
54
+ factory.createIdentifier('baseUrl')
55
+ ])));
56
+ }
57
+ else {
58
+ // Для обычных файлов
59
+ functionBody = factory.createReturnStatement(factory.createConditionalExpression(factory.createBinaryExpression(factory.createIdentifier('baseUrl'), factory.createToken(typescript_1.default.SyntaxKind.EqualsEqualsEqualsToken), factory.createIdentifier('undefined')), factory.createToken(typescript_1.default.SyntaxKind.QuestionToken), factory.createCallExpression(factory.createIdentifier('AbsoluteUrl'), undefined, [factory.createIdentifier('url')]), factory.createToken(typescript_1.default.SyntaxKind.ColonToken), factory.createCallExpression(factory.createIdentifier('AbsoluteUrl'), undefined, [
60
+ factory.createIdentifier('url'),
61
+ factory.createIdentifier('baseUrl')
62
+ ])));
63
+ }
64
+ // Создаем функцию __AbsoluteUrl
65
+ const absoluteUrlFunction = factory.createFunctionDeclaration(undefined, // modifiers
66
+ undefined, // asteriskToken
67
+ '__AbsoluteUrl', undefined, // typeParameters
68
+ [
69
+ factory.createParameterDeclaration(undefined, undefined, 'url', undefined, undefined, undefined),
70
+ factory.createParameterDeclaration(undefined, undefined, 'baseUrl', factory.createToken(typescript_1.default.SyntaxKind.QuestionToken), undefined, undefined)
71
+ ], undefined, // type
72
+ factory.createBlock([functionBody], true));
73
+ // Добавляем функцию в начало файла
74
+ const statements = [absoluteUrlFunction, ...transformedSourceFile.statements];
75
+ return (0, utils_1.preserveSymbolsFrom)(factory.updateSourceFile(transformedSourceFile, statements), sourceFile);
76
+ }
77
+ return (0, utils_1.preserveSymbolsFrom)(transformedSourceFile, sourceFile);
78
+ };
79
+ }