@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,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Модуль push — загрузка dist на WSHCM сервер и reinit модулей
|
|
4
|
+
*
|
|
5
|
+
* Основные экспорты:
|
|
6
|
+
* - `processPush()` — one-shot push (создаёт сессию, выполняет push, закрывает)
|
|
7
|
+
* - `DeploySession` — persistent сессия для dev mode
|
|
8
|
+
* - Утилиты для конфигурации и сбора init-скриптов
|
|
9
|
+
*
|
|
10
|
+
* @module core/pushing
|
|
11
|
+
*/
|
|
12
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
15
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
16
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
17
|
+
}
|
|
18
|
+
Object.defineProperty(o, k2, desc);
|
|
19
|
+
}) : (function(o, m, k, k2) {
|
|
20
|
+
if (k2 === undefined) k2 = k;
|
|
21
|
+
o[k2] = m[k];
|
|
22
|
+
}));
|
|
23
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
24
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
25
|
+
}) : function(o, v) {
|
|
26
|
+
o["default"] = v;
|
|
27
|
+
});
|
|
28
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
29
|
+
var ownKeys = function(o) {
|
|
30
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
31
|
+
var ar = [];
|
|
32
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
33
|
+
return ar;
|
|
34
|
+
};
|
|
35
|
+
return ownKeys(o);
|
|
36
|
+
};
|
|
37
|
+
return function (mod) {
|
|
38
|
+
if (mod && mod.__esModule) return mod;
|
|
39
|
+
var result = {};
|
|
40
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
41
|
+
__setModuleDefault(result, mod);
|
|
42
|
+
return result;
|
|
43
|
+
};
|
|
44
|
+
})();
|
|
45
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
+
exports.findOnInit = exports.extractOnInitFromXml = exports.resolveXLocalPath = exports.collectStandaloneInitScripts = exports.collectComponentInitScripts = exports.reinitModules = exports.uploadDist = exports.parseBtConfigProperties = exports.resolvePushConnectionOptions = exports.DeploySession = void 0;
|
|
47
|
+
exports.processPush = processPush;
|
|
48
|
+
const path = __importStar(require("path"));
|
|
49
|
+
const fs = __importStar(require("fs"));
|
|
50
|
+
const logger_1 = require("../logger");
|
|
51
|
+
const config_1 = require("./config");
|
|
52
|
+
const session_1 = require("./session");
|
|
53
|
+
/**
|
|
54
|
+
* Выполняет one-shot push: загрузка dist + reinit модулей
|
|
55
|
+
*
|
|
56
|
+
* Создаёт DeploySession, выполняет push и закрывает сессию.
|
|
57
|
+
* Для persistent использования (dev mode) используйте DeploySession напрямую.
|
|
58
|
+
*
|
|
59
|
+
* @param cwd - директория проекта
|
|
60
|
+
* @param cliOptions - опции подключения из CLI (опциональные)
|
|
61
|
+
*/
|
|
62
|
+
async function processPush(cwd, cliOptions = {}) {
|
|
63
|
+
const options = (0, config_1.resolvePushConnectionOptions)(cwd, cliOptions);
|
|
64
|
+
logger_1.logger.info(`🚀 Pushing dist to WSHCM server...`);
|
|
65
|
+
logger_1.logger.info(`📡 Server: ${options.https ? 'https' : 'http'}://${options.host}:${options.port}`);
|
|
66
|
+
logger_1.logger.info(`👤 User: ${options.username}`);
|
|
67
|
+
const distPath = path.join(cwd, 'dist');
|
|
68
|
+
if (!fs.existsSync(distPath) || !fs.lstatSync(distPath).isDirectory()) {
|
|
69
|
+
throw new Error(`Папка dist не найдена по пути: ${distPath}`);
|
|
70
|
+
}
|
|
71
|
+
const session = new session_1.DeploySession(options);
|
|
72
|
+
try {
|
|
73
|
+
await session.initialize();
|
|
74
|
+
await session.push(distPath);
|
|
75
|
+
logger_1.logger.info('🎉 Push completed successfully!');
|
|
76
|
+
}
|
|
77
|
+
finally {
|
|
78
|
+
await session.close();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// Re-exports
|
|
82
|
+
var session_2 = require("./session");
|
|
83
|
+
Object.defineProperty(exports, "DeploySession", { enumerable: true, get: function () { return session_2.DeploySession; } });
|
|
84
|
+
var config_2 = require("./config");
|
|
85
|
+
Object.defineProperty(exports, "resolvePushConnectionOptions", { enumerable: true, get: function () { return config_2.resolvePushConnectionOptions; } });
|
|
86
|
+
Object.defineProperty(exports, "parseBtConfigProperties", { enumerable: true, get: function () { return config_2.parseBtConfigProperties; } });
|
|
87
|
+
var upload_1 = require("./upload");
|
|
88
|
+
Object.defineProperty(exports, "uploadDist", { enumerable: true, get: function () { return upload_1.uploadDist; } });
|
|
89
|
+
var reinit_1 = require("./reinit");
|
|
90
|
+
Object.defineProperty(exports, "reinitModules", { enumerable: true, get: function () { return reinit_1.reinitModules; } });
|
|
91
|
+
var init_scripts_1 = require("./init-scripts");
|
|
92
|
+
Object.defineProperty(exports, "collectComponentInitScripts", { enumerable: true, get: function () { return init_scripts_1.collectComponentInitScripts; } });
|
|
93
|
+
Object.defineProperty(exports, "collectStandaloneInitScripts", { enumerable: true, get: function () { return init_scripts_1.collectStandaloneInitScripts; } });
|
|
94
|
+
Object.defineProperty(exports, "resolveXLocalPath", { enumerable: true, get: function () { return init_scripts_1.resolveXLocalPath; } });
|
|
95
|
+
Object.defineProperty(exports, "extractOnInitFromXml", { enumerable: true, get: function () { return init_scripts_1.extractOnInitFromXml; } });
|
|
96
|
+
Object.defineProperty(exports, "findOnInit", { enumerable: true, get: function () { return init_scripts_1.findOnInit; } });
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Сбор init-скриптов для reinit модулей
|
|
4
|
+
*
|
|
5
|
+
* Чистые функции без сетевых вызовов — только работа с файловой системой.
|
|
6
|
+
*
|
|
7
|
+
* @module core/pushing/init-scripts
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
+
var ownKeys = function(o) {
|
|
27
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
+
var ar = [];
|
|
29
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
+
return ar;
|
|
31
|
+
};
|
|
32
|
+
return ownKeys(o);
|
|
33
|
+
};
|
|
34
|
+
return function (mod) {
|
|
35
|
+
if (mod && mod.__esModule) return mod;
|
|
36
|
+
var result = {};
|
|
37
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
+
__setModuleDefault(result, mod);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.collectComponentInitScripts = collectComponentInitScripts;
|
|
44
|
+
exports.collectStandaloneInitScripts = collectStandaloneInitScripts;
|
|
45
|
+
exports.resolveXLocalPath = resolveXLocalPath;
|
|
46
|
+
exports.extractOnInitFromXml = extractOnInitFromXml;
|
|
47
|
+
exports.findOnInit = findOnInit;
|
|
48
|
+
const path = __importStar(require("path"));
|
|
49
|
+
const fs = __importStar(require("fs"));
|
|
50
|
+
const xml_1 = require("../utils/xml");
|
|
51
|
+
const logger_1 = require("../logger");
|
|
52
|
+
/**
|
|
53
|
+
* Собирает init-скрипты из компонентов (директории в dist/components/)
|
|
54
|
+
*
|
|
55
|
+
* Для каждой поддиректории генерируется вызов `<componentName>.init()`.
|
|
56
|
+
*
|
|
57
|
+
* @param distPath - путь к папке dist
|
|
58
|
+
* @returns массив init-скриптов компонентов
|
|
59
|
+
*/
|
|
60
|
+
function collectComponentInitScripts(distPath) {
|
|
61
|
+
const componentsPath = path.join(distPath, 'components');
|
|
62
|
+
if (!fs.existsSync(componentsPath) || !fs.lstatSync(componentsPath).isDirectory()) {
|
|
63
|
+
return [];
|
|
64
|
+
}
|
|
65
|
+
const result = [];
|
|
66
|
+
const componentDirs = fs.readdirSync(componentsPath, { withFileTypes: true })
|
|
67
|
+
.filter(dirent => dirent.isDirectory())
|
|
68
|
+
.map(dirent => dirent.name);
|
|
69
|
+
for (const componentName of componentDirs) {
|
|
70
|
+
const initCode = `${componentName}.init()`;
|
|
71
|
+
result.push({ type: 'component', name: componentName, code: initCode });
|
|
72
|
+
}
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Собирает init-скрипты из standalone модулей (через api_ext.xml)
|
|
77
|
+
*
|
|
78
|
+
* Парсит `dist/source/api_ext.xml`, находит API-модули и извлекает
|
|
79
|
+
* OnInit EXPR из их init XML файлов.
|
|
80
|
+
*
|
|
81
|
+
* @param distPath - путь к папке dist
|
|
82
|
+
* @returns массив init-скриптов standalone модулей
|
|
83
|
+
*/
|
|
84
|
+
function collectStandaloneInitScripts(distPath) {
|
|
85
|
+
const apiExtPath = path.join(distPath, 'source', 'api_ext.xml');
|
|
86
|
+
if (!fs.existsSync(apiExtPath)) {
|
|
87
|
+
return [];
|
|
88
|
+
}
|
|
89
|
+
const result = [];
|
|
90
|
+
const xmlContent = fs.readFileSync(apiExtPath, 'utf-8');
|
|
91
|
+
const parsed = xml_1.xmlParser.parse(xmlContent);
|
|
92
|
+
const apis = parsed?.api_ext?.apis?.api;
|
|
93
|
+
if (!apis) {
|
|
94
|
+
return [];
|
|
95
|
+
}
|
|
96
|
+
// Нормализуем в массив (может быть один объект или массив)
|
|
97
|
+
const apiList = Array.isArray(apis) ? apis : [apis];
|
|
98
|
+
for (const api of apiList) {
|
|
99
|
+
const name = api.name || 'unknown';
|
|
100
|
+
const libs = api.libs?.lib;
|
|
101
|
+
if (!libs)
|
|
102
|
+
continue;
|
|
103
|
+
const libList = Array.isArray(libs) ? libs : [libs];
|
|
104
|
+
for (const lib of libList) {
|
|
105
|
+
const libPath = lib.path;
|
|
106
|
+
if (!libPath || typeof libPath !== 'string')
|
|
107
|
+
continue;
|
|
108
|
+
// Резолвим путь: x-local://wt/myapp/init.xml -> dist/wt/myapp/init.xml
|
|
109
|
+
const resolvedPath = resolveXLocalPath(distPath, libPath);
|
|
110
|
+
if (!resolvedPath || !fs.existsSync(resolvedPath)) {
|
|
111
|
+
logger_1.logger.warning(`⚠️ Init file not found: ${libPath} (resolved: ${resolvedPath})`);
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
const initCode = extractOnInitFromXml(resolvedPath);
|
|
115
|
+
if (initCode) {
|
|
116
|
+
result.push({ type: 'standalone', name, code: initCode });
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Резолвит x-local:// путь в локальный путь относительно dist
|
|
124
|
+
*
|
|
125
|
+
* @param distPath - путь к папке dist
|
|
126
|
+
* @param xLocalPath - путь вида "x-local://wt/myapp/init.xml"
|
|
127
|
+
* @returns локальный путь или null если формат некорректный
|
|
128
|
+
*/
|
|
129
|
+
function resolveXLocalPath(distPath, xLocalPath) {
|
|
130
|
+
const match = xLocalPath.match(/^x-local:\/\/(.+)$/);
|
|
131
|
+
if (!match)
|
|
132
|
+
return null;
|
|
133
|
+
return path.join(distPath, match[1]);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Извлекает содержимое OnInit EXPR из XML файла
|
|
137
|
+
*
|
|
138
|
+
* @param xmlPath - путь к XML файлу
|
|
139
|
+
* @returns код из OnInit EXPR атрибута или null
|
|
140
|
+
*/
|
|
141
|
+
function extractOnInitFromXml(xmlPath) {
|
|
142
|
+
const xmlContent = fs.readFileSync(xmlPath, 'utf-8');
|
|
143
|
+
const parsed = xml_1.xmlParser.parse(xmlContent);
|
|
144
|
+
// Ищем OnInit в любом месте структуры
|
|
145
|
+
const onInit = findOnInit(parsed);
|
|
146
|
+
if (!onInit)
|
|
147
|
+
return null;
|
|
148
|
+
const expr = onInit['@_EXPR'];
|
|
149
|
+
if (typeof expr === 'string') {
|
|
150
|
+
return expr.trim();
|
|
151
|
+
}
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Рекурсивно ищет элемент OnInit в parsed XML
|
|
156
|
+
*
|
|
157
|
+
* @param obj - объект для поиска
|
|
158
|
+
* @returns объект OnInit или null
|
|
159
|
+
*/
|
|
160
|
+
function findOnInit(obj) {
|
|
161
|
+
if (!obj || typeof obj !== 'object')
|
|
162
|
+
return null;
|
|
163
|
+
const record = obj;
|
|
164
|
+
if ('OnInit' in record && record['OnInit'] && typeof record['OnInit'] === 'object') {
|
|
165
|
+
return record['OnInit'];
|
|
166
|
+
}
|
|
167
|
+
for (const value of Object.values(record)) {
|
|
168
|
+
const found = findOnInit(value);
|
|
169
|
+
if (found)
|
|
170
|
+
return found;
|
|
171
|
+
}
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Debounced очередь для push-операций в dev mode
|
|
4
|
+
*
|
|
5
|
+
* @module pushing/queue
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.DebouncedPushQueue = void 0;
|
|
9
|
+
const logger_js_1 = require("../logger.js");
|
|
10
|
+
/**
|
|
11
|
+
* Простая debounced очередь для push-операций
|
|
12
|
+
*
|
|
13
|
+
* Гарантирует что:
|
|
14
|
+
* - Push не вызывается чаще чем раз в `delayMs` мс
|
|
15
|
+
* - Если push уже выполняется, новый запрос ставится в очередь
|
|
16
|
+
* - Одновременно выполняется только один push
|
|
17
|
+
*
|
|
18
|
+
* Использует DeploySession для переиспользования одного клиента
|
|
19
|
+
* и evaluator-а на всё время работы dev mode.
|
|
20
|
+
*/
|
|
21
|
+
class DebouncedPushQueue {
|
|
22
|
+
/** Таймер debounce */
|
|
23
|
+
timer = null;
|
|
24
|
+
/** Флаг: push сейчас выполняется */
|
|
25
|
+
running = false;
|
|
26
|
+
/** Флаг: требуется повторный push после текущего */
|
|
27
|
+
pendingAfterCurrent = false;
|
|
28
|
+
/** Задержка debounce в мс */
|
|
29
|
+
delayMs;
|
|
30
|
+
/** Deploy-сессия (persistent на всё время dev mode) */
|
|
31
|
+
session;
|
|
32
|
+
/** Путь к папке dist */
|
|
33
|
+
distPath;
|
|
34
|
+
/** Флаг: сессия инициализирована */
|
|
35
|
+
sessionInitialized = false;
|
|
36
|
+
/**
|
|
37
|
+
* @param session - DeploySession для push-операций
|
|
38
|
+
* @param distPath - путь к папке dist
|
|
39
|
+
* @param delayMs - задержка debounce в мс
|
|
40
|
+
*/
|
|
41
|
+
constructor(session, distPath, delayMs = 500) {
|
|
42
|
+
this.session = session;
|
|
43
|
+
this.distPath = distPath;
|
|
44
|
+
this.delayMs = delayMs;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Запланировать push с debounce.
|
|
48
|
+
* Если push уже идёт — будет выполнен повторно после завершения текущего.
|
|
49
|
+
*/
|
|
50
|
+
schedule() {
|
|
51
|
+
if (this.running) {
|
|
52
|
+
this.pendingAfterCurrent = true;
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (this.timer) {
|
|
56
|
+
clearTimeout(this.timer);
|
|
57
|
+
}
|
|
58
|
+
this.timer = setTimeout(() => this.execute(), this.delayMs);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Закрывает сессию
|
|
62
|
+
*/
|
|
63
|
+
async close() {
|
|
64
|
+
if (this.timer) {
|
|
65
|
+
clearTimeout(this.timer);
|
|
66
|
+
this.timer = null;
|
|
67
|
+
}
|
|
68
|
+
await this.session.close();
|
|
69
|
+
}
|
|
70
|
+
/** Выполнить push */
|
|
71
|
+
async execute() {
|
|
72
|
+
this.timer = null;
|
|
73
|
+
this.running = true;
|
|
74
|
+
this.pendingAfterCurrent = false;
|
|
75
|
+
try {
|
|
76
|
+
// Ленивая инициализация сессии при первом push
|
|
77
|
+
if (!this.sessionInitialized) {
|
|
78
|
+
await this.session.initialize();
|
|
79
|
+
this.sessionInitialized = true;
|
|
80
|
+
}
|
|
81
|
+
logger_js_1.logger.info('🚀 Auto-pushing dist to WSHCM server...');
|
|
82
|
+
await this.session.push(this.distPath);
|
|
83
|
+
logger_js_1.logger.info('🎉 Auto-push completed successfully!');
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
logger_js_1.logger.error(`❌ Auto-push failed: ${error.message}`);
|
|
87
|
+
}
|
|
88
|
+
this.running = false;
|
|
89
|
+
if (this.pendingAfterCurrent) {
|
|
90
|
+
this.pendingAfterCurrent = false;
|
|
91
|
+
this.schedule();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
exports.DebouncedPushQueue = DebouncedPushQueue;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Reinit модулей на WSHCM сервере
|
|
4
|
+
*
|
|
5
|
+
* Собирает init-скрипты из dist и выполняет их через evaluator.
|
|
6
|
+
*
|
|
7
|
+
* @module core/pushing/reinit
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.reinitModules = reinitModules;
|
|
11
|
+
const logger_1 = require("../logger");
|
|
12
|
+
const init_scripts_1 = require("./init-scripts");
|
|
13
|
+
/**
|
|
14
|
+
* Выполняет reinit модулей на сервере
|
|
15
|
+
*
|
|
16
|
+
* 1. Собирает init-скрипты из компонентов и standalone модулей
|
|
17
|
+
* 2. Сбрасывает кеш require (`bt.init_require()`)
|
|
18
|
+
* 3. Выполняет каждый init-скрипт
|
|
19
|
+
*
|
|
20
|
+
* Ошибки отдельных init-скриптов логируются, но не прерывают процесс.
|
|
21
|
+
* Lifecycle evaluator-а управляется вызывающим кодом.
|
|
22
|
+
*
|
|
23
|
+
* @param evaluator - инициализированный evaluator
|
|
24
|
+
* @param distPath - путь к папке dist
|
|
25
|
+
*/
|
|
26
|
+
async function reinitModules(evaluator, distPath) {
|
|
27
|
+
logger_1.logger.info('🔄 Collecting init scripts...');
|
|
28
|
+
const initScripts = [];
|
|
29
|
+
// 1. Компоненты (первыми, исключая bt-runtime)
|
|
30
|
+
const componentScripts = (0, init_scripts_1.collectComponentInitScripts)(distPath).filter((script) => script.name !== 'bt-runtime');
|
|
31
|
+
initScripts.push(...componentScripts);
|
|
32
|
+
// 2. Standalone модули из api_ext.xml
|
|
33
|
+
const standaloneScripts = (0, init_scripts_1.collectStandaloneInitScripts)(distPath);
|
|
34
|
+
initScripts.push(...standaloneScripts);
|
|
35
|
+
if (initScripts.length === 0) {
|
|
36
|
+
logger_1.logger.info('ℹ️ No init scripts found');
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
// Вывод найденных скриптов
|
|
40
|
+
logger_1.logger.info(`📜 Found ${initScripts.length} init script(s):`);
|
|
41
|
+
for (const script of initScripts) {
|
|
42
|
+
logger_1.logger.info(`\n${'─'.repeat(60)}`);
|
|
43
|
+
logger_1.logger.info(`📦 [${script.type}] ${script.name}`);
|
|
44
|
+
logger_1.logger.info(`${'─'.repeat(60)}`);
|
|
45
|
+
console.log(script.code);
|
|
46
|
+
}
|
|
47
|
+
logger_1.logger.info(`\n${'─'.repeat(60)}`);
|
|
48
|
+
// Сброс кеша require
|
|
49
|
+
await evaluator.evalCode("bt.init_require();\nreturn;");
|
|
50
|
+
// Выполнение init скриптов
|
|
51
|
+
for (const script of initScripts) {
|
|
52
|
+
logger_1.logger.info(`⚙️ Executing init for [${script.type}] ${script.name}...`);
|
|
53
|
+
try {
|
|
54
|
+
await evaluator.evalCode(script.code + "\nreturn;");
|
|
55
|
+
logger_1.logger.info(`✅ Successfully executed init for ${script.name}`);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
logger_1.logger.error(`❌ Error executing init for ${script.name}: ${error.message}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* DeploySession — persistent сессия для push-операций
|
|
4
|
+
*
|
|
5
|
+
* Управляет lifecycle одного WshcmClient + Evaluator.
|
|
6
|
+
* Используется в dev mode для переиспользования соединения между push-ами,
|
|
7
|
+
* а также в one-shot push через processPush().
|
|
8
|
+
*
|
|
9
|
+
* @module core/pushing/session
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.DeploySession = void 0;
|
|
13
|
+
const ws_client_1 = require("@boristype/ws-client");
|
|
14
|
+
const logger_1 = require("../logger");
|
|
15
|
+
const upload_1 = require("./upload");
|
|
16
|
+
const reinit_1 = require("./reinit");
|
|
17
|
+
/**
|
|
18
|
+
* Persistent сессия для push-операций на WSHCM сервер
|
|
19
|
+
*
|
|
20
|
+
* Держит один WshcmClient + один Evaluator на всё время жизни сессии.
|
|
21
|
+
* Поддерживает reconnect при network-ошибках (1 retry).
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* // One-shot
|
|
26
|
+
* const session = new DeploySession(connectionOptions);
|
|
27
|
+
* await session.initialize();
|
|
28
|
+
* await session.push(distPath);
|
|
29
|
+
* await session.close();
|
|
30
|
+
*
|
|
31
|
+
* // Dev mode (persistent)
|
|
32
|
+
* const session = new DeploySession(connectionOptions);
|
|
33
|
+
* await session.initialize();
|
|
34
|
+
* // ... при каждом изменении:
|
|
35
|
+
* await session.push(distPath);
|
|
36
|
+
* // ... при завершении:
|
|
37
|
+
* await session.close();
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
class DeploySession {
|
|
41
|
+
connectionOptions;
|
|
42
|
+
client = null;
|
|
43
|
+
evaluator = null;
|
|
44
|
+
initialized = false;
|
|
45
|
+
/**
|
|
46
|
+
* Создаёт новую deploy-сессию
|
|
47
|
+
* @param connectionOptions - опции подключения к серверу
|
|
48
|
+
*/
|
|
49
|
+
constructor(connectionOptions) {
|
|
50
|
+
this.connectionOptions = connectionOptions;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Инициализирует сессию: создаёт клиент, проверяет авторизацию,
|
|
54
|
+
* создаёт и инициализирует evaluator.
|
|
55
|
+
*
|
|
56
|
+
* Должен быть вызван перед первым push().
|
|
57
|
+
*/
|
|
58
|
+
async initialize() {
|
|
59
|
+
this.client = new ws_client_1.WshcmClient({
|
|
60
|
+
overHttps: this.connectionOptions.https,
|
|
61
|
+
host: this.connectionOptions.host,
|
|
62
|
+
port: this.connectionOptions.port,
|
|
63
|
+
username: this.connectionOptions.username,
|
|
64
|
+
password: this.connectionOptions.password,
|
|
65
|
+
});
|
|
66
|
+
await this.client.initialize();
|
|
67
|
+
this.evaluator = this.client.createEvaluator();
|
|
68
|
+
await this.evaluator.initialize();
|
|
69
|
+
this.initialized = true;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Выполняет push: загрузка dist + reinit модулей
|
|
73
|
+
*
|
|
74
|
+
* При network-ошибке пытается выполнить reconnect и повторный push (1 retry).
|
|
75
|
+
*
|
|
76
|
+
* @param distPath - путь к папке dist
|
|
77
|
+
*/
|
|
78
|
+
async push(distPath) {
|
|
79
|
+
if (!this.initialized || !this.evaluator) {
|
|
80
|
+
throw new Error('DeploySession is not initialized. Call initialize() first.');
|
|
81
|
+
}
|
|
82
|
+
try {
|
|
83
|
+
await this.executePush(distPath);
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
if (this.isNetworkError(error)) {
|
|
87
|
+
logger_1.logger.warning('⚠️ Network error during push, attempting reconnect...');
|
|
88
|
+
try {
|
|
89
|
+
await this.reconnect();
|
|
90
|
+
await this.executePush(distPath);
|
|
91
|
+
}
|
|
92
|
+
catch (retryError) {
|
|
93
|
+
throw new Error(`Push failed after reconnect: ${retryError.message}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
throw error;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Закрывает сессию: удаляет evaluator с сервера
|
|
103
|
+
*/
|
|
104
|
+
async close() {
|
|
105
|
+
if (this.evaluator) {
|
|
106
|
+
try {
|
|
107
|
+
await this.evaluator.close();
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
// Игнорируем ошибки при закрытии
|
|
111
|
+
}
|
|
112
|
+
this.evaluator = null;
|
|
113
|
+
}
|
|
114
|
+
this.client = null;
|
|
115
|
+
this.initialized = false;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Выполняет push без retry-логики
|
|
119
|
+
*/
|
|
120
|
+
async executePush(distPath) {
|
|
121
|
+
await (0, upload_1.uploadDist)(this.evaluator, distPath);
|
|
122
|
+
await (0, reinit_1.reinitModules)(this.evaluator, distPath);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Переподключается к серверу: закрывает текущий evaluator,
|
|
126
|
+
* создаёт новый и инициализирует его.
|
|
127
|
+
*/
|
|
128
|
+
async reconnect() {
|
|
129
|
+
// Закрываем старый evaluator (игнорируем ошибки)
|
|
130
|
+
if (this.evaluator) {
|
|
131
|
+
try {
|
|
132
|
+
await this.evaluator.close();
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
// Может быть уже недоступен
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// Пересоздаём клиент и evaluator
|
|
139
|
+
this.client = new ws_client_1.WshcmClient({
|
|
140
|
+
overHttps: this.connectionOptions.https,
|
|
141
|
+
host: this.connectionOptions.host,
|
|
142
|
+
port: this.connectionOptions.port,
|
|
143
|
+
username: this.connectionOptions.username,
|
|
144
|
+
password: this.connectionOptions.password,
|
|
145
|
+
});
|
|
146
|
+
await this.client.initialize();
|
|
147
|
+
this.evaluator = this.client.createEvaluator();
|
|
148
|
+
await this.evaluator.initialize();
|
|
149
|
+
logger_1.logger.info('🔄 Reconnected to WSHCM server');
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Определяет, является ли ошибка сетевой
|
|
153
|
+
*/
|
|
154
|
+
isNetworkError(error) {
|
|
155
|
+
if (error instanceof ws_client_1.WshcmException) {
|
|
156
|
+
const message = error.message.toLowerCase();
|
|
157
|
+
return message.includes('request failed') ||
|
|
158
|
+
message.includes('request timed out') ||
|
|
159
|
+
message.includes('econnrefused') ||
|
|
160
|
+
message.includes('econnreset') ||
|
|
161
|
+
message.includes('etimedout') ||
|
|
162
|
+
message.includes('socket hang up');
|
|
163
|
+
}
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
exports.DeploySession = DeploySession;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Загрузка dist на WSHCM сервер
|
|
4
|
+
*
|
|
5
|
+
* @module core/pushing/upload
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.uploadDist = uploadDist;
|
|
9
|
+
const ws_client_1 = require("@boristype/ws-client");
|
|
10
|
+
const logger_1 = require("../logger");
|
|
11
|
+
/**
|
|
12
|
+
* Загружает содержимое dist директории на WSHCM сервер
|
|
13
|
+
*
|
|
14
|
+
* Использует переданный evaluator для всех серверных операций.
|
|
15
|
+
* Lifecycle evaluator-а управляется вызывающим кодом.
|
|
16
|
+
*
|
|
17
|
+
* @param evaluator - инициализированный evaluator
|
|
18
|
+
* @param distPath - путь к папке dist
|
|
19
|
+
* @param onProgress - callback для отслеживания прогресса загрузки
|
|
20
|
+
* @returns массив URL загруженных файлов
|
|
21
|
+
*/
|
|
22
|
+
async function uploadDist(evaluator, distPath, onProgress) {
|
|
23
|
+
const uploader = new ws_client_1.WshcmUploader({
|
|
24
|
+
evaluator,
|
|
25
|
+
path: distPath + '/*',
|
|
26
|
+
destination: 'x-local://',
|
|
27
|
+
});
|
|
28
|
+
await uploader.prepare();
|
|
29
|
+
await uploader.upload(onProgress ?? ((uploaded, total) => {
|
|
30
|
+
logger_1.logger.info(`📦 Progress: ${(uploaded / total * 100).toFixed(2)}%`);
|
|
31
|
+
}));
|
|
32
|
+
const urls = await uploader.finish();
|
|
33
|
+
logger_1.logger.info(`✅ Uploaded ${urls.length} file(s)`);
|
|
34
|
+
return urls;
|
|
35
|
+
}
|