mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2025-12-11 18:42:56 +00:00
feat: zip publisher support browser (#2744)
This commit is contained in:
parent
b2abb67440
commit
7b85a35b24
@ -94,16 +94,26 @@ await CodeGenerator.init();
|
|||||||
4. 出码
|
4. 出码
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const result = await CodeGenerator.generateCode({
|
const project = await CodeGenerator.generateCode({
|
||||||
solution: 'icejs', // 出码方案 (目前内置有 icejs 和 rax )
|
solution: 'icejs', // 出码方案 (目前内置有 icejs 和 rax )
|
||||||
schema, // 编排搭建出来的 schema
|
schema, // 编排搭建出来的 schema
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(result); // 出码结果(默认是递归结构描述的,可以传 flattenResult: true 以生成扁平结构的结果)
|
console.log(project); // 出码结果(默认是递归结构描述的,可以传 flattenResult: true 以生成扁平结构的结果)
|
||||||
```
|
```
|
||||||
|
|
||||||
注:一般来说在浏览器中出码适合做即时预览功能。
|
注:一般来说在浏览器中出码适合做即时预览功能。
|
||||||
|
|
||||||
|
5. 下载 zip 包
|
||||||
|
|
||||||
|
```js
|
||||||
|
// 写入到 zip 包
|
||||||
|
await CodeGenerator.publishers.zip().publish({
|
||||||
|
project, // 上一步生成的 project
|
||||||
|
projectSlug: 'your-project-slug', // 项目标识 -- 对应下载 your-project-slug.zip 文件
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
### 5)自定义出码
|
### 5)自定义出码
|
||||||
|
|
||||||
前端框架灵活多变,默认内置的出码方案很难满足所有人的需求,好在此代码生成器支持非常灵活的插件机制 -- 欢迎参考 ./src/plugins/xxx 来编写您自己的出码插件,然后参考 ./src/solutions/xxx 将各种插件组合成一套适合您的业务场景的出码方案。
|
前端框架灵活多变,默认内置的出码方案很难满足所有人的需求,好在此代码生成器支持非常灵活的插件机制 -- 欢迎参考 ./src/plugins/xxx 来编写您自己的出码插件,然后参考 ./src/solutions/xxx 将各种插件组合成一套适合您的业务场景的出码方案。
|
||||||
|
|||||||
@ -80,6 +80,7 @@
|
|||||||
"change-case": "^3.1.0",
|
"change-case": "^3.1.0",
|
||||||
"commander": "^6.1.0",
|
"commander": "^6.1.0",
|
||||||
"debug": "^4.3.2",
|
"debug": "^4.3.2",
|
||||||
|
"file-saver": "^2.0.5",
|
||||||
"fp-ts": "^2.11.9",
|
"fp-ts": "^2.11.9",
|
||||||
"fs-extra": "9.x",
|
"fs-extra": "9.x",
|
||||||
"glob": "^7.2.0",
|
"glob": "^7.2.0",
|
||||||
@ -109,6 +110,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@iceworks/spec": "^1.4.2",
|
"@iceworks/spec": "^1.4.2",
|
||||||
"@types/babel__traverse": "^7.11.0",
|
"@types/babel__traverse": "^7.11.0",
|
||||||
|
"@types/file-saver": "^2.0.7",
|
||||||
"@types/jest": "^27.0.2",
|
"@types/jest": "^27.0.2",
|
||||||
"@types/lodash": "^4.14.162",
|
"@types/lodash": "^4.14.162",
|
||||||
"@types/node": "^14.14.20",
|
"@types/node": "^14.14.20",
|
||||||
|
|||||||
@ -2,9 +2,9 @@ import { ResultDir } from '@alilc/lowcode-types';
|
|||||||
import { PublisherFactory, IPublisher, IPublisherFactoryParams, PublisherError } from '../../types';
|
import { PublisherFactory, IPublisher, IPublisherFactoryParams, PublisherError } from '../../types';
|
||||||
import { getErrorMessage } from '../../utils/errors';
|
import { getErrorMessage } from '../../utils/errors';
|
||||||
import { isNodeProcess, writeZipToDisk, generateProjectZip } from './utils';
|
import { isNodeProcess, writeZipToDisk, generateProjectZip } from './utils';
|
||||||
|
import { saveAs } from 'file-saver';
|
||||||
|
|
||||||
// export type ZipBuffer = Buffer | Blob;
|
export type ZipBuffer = Buffer | Blob;
|
||||||
export type ZipBuffer = Buffer;
|
|
||||||
|
|
||||||
declare type ZipPublisherResponse = string | ZipBuffer;
|
declare type ZipPublisherResponse = string | ZipBuffer;
|
||||||
|
|
||||||
@ -44,10 +44,16 @@ export const createZipPublisher: PublisherFactory<ZipFactoryParams, ZipPublisher
|
|||||||
try {
|
try {
|
||||||
const zipContent = await generateProjectZip(projectToPublish);
|
const zipContent = await generateProjectZip(projectToPublish);
|
||||||
|
|
||||||
// If not output path is provided, zip is not written to disk
|
if (isNodeProcess()) {
|
||||||
const projectOutputPath = options.outputPath || outputPath;
|
// If not output path is provided on the node side, zip is not written to disk
|
||||||
if (projectOutputPath && isNodeProcess()) {
|
const projectOutputPath = options.outputPath || outputPath;
|
||||||
await writeZipToDisk(projectOutputPath, zipContent, zipName);
|
if (projectOutputPath) {
|
||||||
|
await writeZipToDisk(projectOutputPath, zipContent, zipName);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// the browser end does not require a path
|
||||||
|
// auto download zip files
|
||||||
|
saveAs(zipContent as Blob, `${zipName}.zip`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return { success: true, payload: zipContent };
|
return { success: true, payload: zipContent };
|
||||||
|
|||||||
@ -40,8 +40,7 @@ export const writeZipToDisk = (
|
|||||||
export const generateProjectZip = async (project: ResultDir): Promise<ZipBuffer> => {
|
export const generateProjectZip = async (project: ResultDir): Promise<ZipBuffer> => {
|
||||||
let zip = new JSZip();
|
let zip = new JSZip();
|
||||||
zip = writeFolderToZip(project, zip, true);
|
zip = writeFolderToZip(project, zip, true);
|
||||||
// const zipType = isNodeProcess() ? 'nodebuffer' : 'blob';
|
const zipType = isNodeProcess() ? 'nodebuffer' : 'blob';
|
||||||
const zipType = 'nodebuffer'; // 目前先只支持 node 调用
|
|
||||||
return zip.generateAsync({ type: zipType });
|
return zip.generateAsync({ type: zipType });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,14 @@
|
|||||||
import CodeGen from '../../../../src';
|
import CodeGen from '../../../../src';
|
||||||
|
import fileSaver from 'file-saver';
|
||||||
|
import * as utils from '../../../../src/publisher/zip/utils';
|
||||||
|
|
||||||
|
jest.mock('file-saver');
|
||||||
|
|
||||||
describe('public/publisher/zip/zip', () => {
|
describe('public/publisher/zip/zip', () => {
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
it('should works', async () => {
|
it('should works', async () => {
|
||||||
const zip = CodeGen.publishers.zip({
|
const zip = CodeGen.publishers.zip({
|
||||||
outputPath: 'demo-output',
|
outputPath: 'demo-output',
|
||||||
@ -19,15 +27,15 @@ describe('public/publisher/zip/zip', () => {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
expect(zip.getOutputPath()).toMatchInlineSnapshot(`"demo-output"`);
|
expect(zip.getOutputPath()).toMatchInlineSnapshot('"demo-output"');
|
||||||
|
|
||||||
expect(zip.getProject()).toMatchInlineSnapshot(`undefined`);
|
expect(zip.getProject()).toMatchInlineSnapshot('undefined');
|
||||||
zip.setProject(demoProject);
|
zip.setProject(demoProject);
|
||||||
expect(zip.getProject()).toBeTruthy();
|
expect(zip.getProject()).toBeTruthy();
|
||||||
|
|
||||||
expect(zip.getOutputPath()).toMatchInlineSnapshot(`"demo-output"`);
|
expect(zip.getOutputPath()).toMatchInlineSnapshot('"demo-output"');
|
||||||
expect(zip.setOutputPath('output')).toBe(undefined);
|
expect(zip.setOutputPath('output')).toBe(undefined);
|
||||||
expect(zip.getOutputPath()).toMatchInlineSnapshot(`"output"`);
|
expect(zip.getOutputPath()).toMatchInlineSnapshot('"output"');
|
||||||
|
|
||||||
const publishRes = await zip.publish({
|
const publishRes = await zip.publish({
|
||||||
project: demoProject,
|
project: demoProject,
|
||||||
@ -41,4 +49,39 @@ describe('public/publisher/zip/zip', () => {
|
|||||||
const zip = CodeGen.publishers.zip({});
|
const zip = CodeGen.publishers.zip({});
|
||||||
expect(zip.publish()).rejects.toBeTruthy();
|
expect(zip.publish()).rejects.toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should publish the project as a zip file in the browser', async () => {
|
||||||
|
const zipContent = 'zip content';
|
||||||
|
const zipName = 'example-project';
|
||||||
|
jest.spyOn(utils, 'isNodeProcess').mockReturnValue(false);
|
||||||
|
// new Zip 里面也有平台判断,所以这里 mock
|
||||||
|
jest.spyOn(utils, 'generateProjectZip').mockResolvedValue(zipContent as any);
|
||||||
|
const spy = jest.spyOn(fileSaver, 'saveAs');
|
||||||
|
|
||||||
|
const zip = CodeGen.publishers.zip({
|
||||||
|
projectSlug: zipName,
|
||||||
|
});
|
||||||
|
|
||||||
|
const demoProject = {
|
||||||
|
name: 'demo',
|
||||||
|
dirs: [],
|
||||||
|
files: [
|
||||||
|
{
|
||||||
|
name: 'package',
|
||||||
|
ext: 'json',
|
||||||
|
content: '{ "name": "demo", "version": "1.0.0" }',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
zip.setProject(demoProject);
|
||||||
|
const publishRes = await zip.publish({
|
||||||
|
project: demoProject,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(publishRes.success).toBeTruthy();
|
||||||
|
expect(spy).toBeCalledWith(zipContent, `${zipName}.zip`);
|
||||||
|
spy.mockReset();
|
||||||
|
spy.mockRestore();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user