mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2025-12-14 13:03:07 +00:00
122 lines
3.2 KiB
TypeScript
122 lines
3.2 KiB
TypeScript
import spawn from 'cross-spawn-promise';
|
|
import { ensureDir, ensureFile, writeFile } from 'fs-extra';
|
|
import { join } from 'path';
|
|
import semver from 'semver';
|
|
import uuid from 'short-uuid';
|
|
import { debug, IComponentMaterial, OtterError } from '../otter-core';
|
|
import { IMaterializeOptions } from '../types';
|
|
import BaseAccesser from './BaseAccesser';
|
|
import LocalAccesser from './LocalAccesser';
|
|
|
|
const log = debug.extend('mat');
|
|
|
|
/**
|
|
* 在线接入
|
|
* @class OnlineAccesser
|
|
* @extends {BaseAccesser}
|
|
*/
|
|
class OnlineAccesser extends BaseAccesser {
|
|
/**
|
|
* 临时目录
|
|
*
|
|
* @private
|
|
* @type {string}
|
|
* @memberof OnlineAccesser
|
|
*/
|
|
private tempDir: string = '';
|
|
|
|
public async access(): Promise<IComponentMaterial> {
|
|
// 创建临时目录
|
|
this.tempDir = await this.createTempDir();
|
|
// 创建组件包
|
|
const { name, version } = this.getPkgNameAndVersion(this.options.entry);
|
|
await this.createFakePackage({
|
|
pkgName: name,
|
|
pkgVersion: version,
|
|
});
|
|
// 将问题转化为本地物料化场景
|
|
const options: IMaterializeOptions = {
|
|
cwd: this.tempDir,
|
|
entry: join(this.tempDir, 'node_modules', name),
|
|
accesser: 'local',
|
|
isExportedAsMultiple: this.options.isExportedAsMultiple,
|
|
};
|
|
const localAccesser = new LocalAccesser(options);
|
|
return localAccesser.access();
|
|
}
|
|
|
|
/**
|
|
* 创建组件包
|
|
*
|
|
* @private
|
|
* @param {{
|
|
* pkgName: string;
|
|
* pkgVersion: string;
|
|
* }} params
|
|
* @returns {Promise<void>}
|
|
* @memberof OnlineAccesser
|
|
*/
|
|
private async createFakePackage(params: {
|
|
pkgName: string;
|
|
pkgVersion: string;
|
|
}): Promise<void> {
|
|
// 创建临时组件包
|
|
const tempDir = this.tempDir;
|
|
const pkgJsonFilePath = join(tempDir, 'package.json');
|
|
await ensureFile(pkgJsonFilePath);
|
|
await writeFile(
|
|
pkgJsonFilePath,
|
|
JSON.stringify({
|
|
name: params.pkgName,
|
|
version: params.pkgVersion,
|
|
dependencies: {
|
|
[params.pkgName]: params.pkgVersion,
|
|
},
|
|
}),
|
|
);
|
|
// 安装依赖
|
|
const npmClient = this.options.npmClient || 'tnpm';
|
|
await spawn(npmClient, ['i'], { stdio: 'inherit', cwd: tempDir } as any);
|
|
}
|
|
|
|
/**
|
|
* 创建临时目录
|
|
*
|
|
* @private
|
|
* @returns {Promise<string>} 返回临时文件夹路径
|
|
* @memberof LocalGenerator
|
|
*/
|
|
private async createTempDir(): Promise<string> {
|
|
const tempDirName = uuid.generate();
|
|
const tempDir = join(__dirname, '../../node_modules/.temp/', tempDirName);
|
|
await ensureDir(tempDir);
|
|
log('create temp dir successfully', tempDir);
|
|
return tempDir;
|
|
}
|
|
|
|
/**
|
|
* 分离物料组件名称和版本号
|
|
*
|
|
* @private
|
|
* @param {string} pkgNameWithVersion
|
|
* @returns {{ [key: string]: any }}
|
|
* @memberof OnlineAccesser
|
|
*/
|
|
private getPkgNameAndVersion(
|
|
pkgNameWithVersion: string,
|
|
): { [key: string]: any } {
|
|
const matches = pkgNameWithVersion.match(/(@\d+\.\d+\.\d+)$/);
|
|
if (!matches) {
|
|
throw new OtterError(`Illegal semver version: ${pkgNameWithVersion}`);
|
|
}
|
|
const semverObj = semver.coerce(matches[0]);
|
|
const name = pkgNameWithVersion.replace(matches[0], '');
|
|
return {
|
|
version: semverObj && semverObj.version,
|
|
name,
|
|
};
|
|
}
|
|
}
|
|
|
|
export default OnlineAccesser;
|