mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2025-12-13 12:13:10 +00:00
commit
41753de24a
28
.eslintrc.js
28
.eslintrc.js
@ -15,7 +15,6 @@ module.exports = {
|
||||
'no-prototype-builtins': 1,
|
||||
'no-useless-constructor': 1,
|
||||
'no-empty-function': 1,
|
||||
'@typescript-eslint/member-ordering': 0,
|
||||
'lines-between-class-members': 0,
|
||||
'no-await-in-loop': 0,
|
||||
'no-plusplus': 0,
|
||||
@ -35,23 +34,24 @@ module.exports = {
|
||||
'@typescript-eslint/indent': 0,
|
||||
'import/no-cycle': 0,
|
||||
'@typescript-eslint/no-shadow': 0,
|
||||
"@typescript-eslint/method-signature-style": 0,
|
||||
"@typescript-eslint/consistent-type-assertions": 0,
|
||||
"@typescript-eslint/no-useless-constructor": 0,
|
||||
'@typescript-eslint/method-signature-style': 0,
|
||||
'@typescript-eslint/consistent-type-assertions': 0,
|
||||
'@typescript-eslint/no-useless-constructor': 0,
|
||||
'@typescript-eslint/dot-notation': 0, // for lint performance
|
||||
'@typescript-eslint/restrict-plus-operands': 0, // for lint performance
|
||||
'no-unexpected-multiline': 1,
|
||||
'no-multiple-empty-lines': ['error', { "max": 1 }],
|
||||
'no-multiple-empty-lines': ['error', { max: 1 }],
|
||||
'lines-around-comment': ['error', {
|
||||
"beforeBlockComment": true,
|
||||
"afterBlockComment": false,
|
||||
"afterLineComment": false,
|
||||
"allowBlockStart": true,
|
||||
beforeBlockComment: true,
|
||||
afterBlockComment: false,
|
||||
afterLineComment: false,
|
||||
allowBlockStart: true,
|
||||
}],
|
||||
"no-unused-vars": ['error', { "destructuredArrayIgnorePattern": "^_" }],
|
||||
"@typescript-eslint/member-ordering": [
|
||||
"error",
|
||||
{ "default": ["signature", "field", "constructor", "method"] }
|
||||
'comma-dangle': ['error', 'always-multiline'],
|
||||
'@typescript-eslint/member-ordering': [
|
||||
'error',
|
||||
{ default: ['signature', 'field', 'constructor', 'method'] }
|
||||
],
|
||||
}
|
||||
'no-unused-vars': ['error', { "destructuredArrayIgnorePattern": "^_" }]
|
||||
},
|
||||
};
|
||||
@ -71,7 +71,7 @@
|
||||
},
|
||||
"lifeCycles": {
|
||||
"componentDidMount": {
|
||||
"type": "JSExpression",
|
||||
"type": "JSFunction",
|
||||
"value": "function() { console.log('componentDidMount'); }"
|
||||
}
|
||||
},
|
||||
@ -91,7 +91,7 @@
|
||||
"isSync": true
|
||||
},
|
||||
"dataHandler": {
|
||||
"type": "JSExpression",
|
||||
"type": "JSFunction",
|
||||
"value": "function (response) {\nif (!response.data.success){\n throw new Error(response.data.message);\n }\n return response.data.data;\n}"
|
||||
}
|
||||
},
|
||||
@ -105,13 +105,13 @@
|
||||
"isSync": true
|
||||
},
|
||||
"dataHandler": {
|
||||
"type": "JSExpression",
|
||||
"type": "JSFunction",
|
||||
"value": "function (response) {\nif (!response.data.success){\n throw new Error(response.data.message);\n }\n return response.data.data.result;\n}"
|
||||
}
|
||||
}
|
||||
],
|
||||
"dataHandler": {
|
||||
"type": "JSExpression",
|
||||
"type": "JSFunction",
|
||||
"value": "function (dataMap) {\n console.info(\"All datasources loaded:\", dataMap);\n}"
|
||||
}
|
||||
},
|
||||
|
||||
@ -71,7 +71,7 @@
|
||||
},
|
||||
lifeCycles: {
|
||||
componentDidMount: {
|
||||
type: 'JSExpression',
|
||||
type: 'JSFunction',
|
||||
value: "function() { console.log('componentDidMount'); }",
|
||||
},
|
||||
},
|
||||
@ -91,7 +91,7 @@
|
||||
isSync: true,
|
||||
},
|
||||
dataHandler: {
|
||||
type: 'JSExpression',
|
||||
type: 'JSFunction',
|
||||
value: 'function (response) {\nif (!response.data.success){\n throw new Error(response.data.message);\n }\n return response.data.data;\n}',
|
||||
},
|
||||
},
|
||||
@ -105,13 +105,13 @@
|
||||
isSync: true,
|
||||
},
|
||||
dataHandler: {
|
||||
type: 'JSExpression',
|
||||
type: 'JSFunction',
|
||||
value: 'function (response) {\nif (!response.data.success){\n throw new Error(response.data.message);\n }\n return response.data.data.result;\n}',
|
||||
},
|
||||
},
|
||||
],
|
||||
dataHandler: {
|
||||
type: 'JSExpression',
|
||||
type: 'JSFunction',
|
||||
value: 'function (dataMap) {\n console.info("All datasources loaded:", dataMap);\n}',
|
||||
},
|
||||
},
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@alilc/lowcode-code-generator",
|
||||
"version": "1.0.7",
|
||||
"version": "1.0.8",
|
||||
"description": "出码引擎 for LowCode Engine",
|
||||
"license": "MIT",
|
||||
"main": "lib/index.js",
|
||||
|
||||
@ -8,5 +8,26 @@ export const CONTAINER_TYPE = {
|
||||
|
||||
export const SUPPORT_SCHEMA_VERSION_LIST = ['0.0.1', '1.0.0'];
|
||||
|
||||
// built-in slot names which have been handled in ProjectBuilder
|
||||
export const BUILTIN_SLOT_NAMES = [
|
||||
'pages',
|
||||
'components',
|
||||
'router',
|
||||
'entry',
|
||||
'appConfig',
|
||||
'buildConfig',
|
||||
'constants',
|
||||
'utils',
|
||||
'i18n',
|
||||
'globalStyle',
|
||||
'htmlEntry',
|
||||
'packageJSON',
|
||||
'demo',
|
||||
];
|
||||
|
||||
export const isBuiltinSlotName = function (name: string) {
|
||||
return BUILTIN_SLOT_NAMES.includes(name);
|
||||
};
|
||||
|
||||
export * from './file';
|
||||
export * from './generator';
|
||||
|
||||
@ -62,10 +62,9 @@ export function createModuleBuilder(
|
||||
|
||||
if (options.postProcessors.length > 0) {
|
||||
files = files.map((file) => {
|
||||
let { content } = file;
|
||||
const type = file.ext;
|
||||
let { content, ext: type, name } = file;
|
||||
options.postProcessors.forEach((processer) => {
|
||||
content = processer(content, type);
|
||||
content = processer(content, type, name);
|
||||
});
|
||||
|
||||
return createResultFile(file.name, type, content);
|
||||
|
||||
@ -16,6 +16,7 @@ import { createResultDir, addDirectory, addFile } from '../utils/resultHelper';
|
||||
import { createModuleBuilder } from './ModuleBuilder';
|
||||
import { ProjectPreProcessor, ProjectPostProcessor, IContextData } from '../types/core';
|
||||
import { CodeGeneratorError } from '../types/error';
|
||||
import { isBuiltinSlotName } from '../const';
|
||||
|
||||
interface IModuleInfo {
|
||||
moduleName?: string;
|
||||
@ -24,22 +25,31 @@ interface IModuleInfo {
|
||||
}
|
||||
|
||||
export interface ProjectBuilderInitOptions {
|
||||
|
||||
/** 项目模板 */
|
||||
template: IProjectTemplate;
|
||||
|
||||
/** 项目插件 */
|
||||
plugins: IProjectPlugins;
|
||||
|
||||
/** 模块后置处理器 */
|
||||
postProcessors: PostProcessor[];
|
||||
|
||||
/** Schema 解析器 */
|
||||
schemaParser?: ISchemaParser;
|
||||
|
||||
/** 项目级别的前置处理器 */
|
||||
projectPreProcessors?: ProjectPreProcessor[];
|
||||
|
||||
/** 项目级别的后置处理器 */
|
||||
projectPostProcessors?: ProjectPostProcessor[];
|
||||
|
||||
/** 是否处于严格模式 */
|
||||
inStrictMode?: boolean;
|
||||
|
||||
/** 一些额外的上下文数据 */
|
||||
extraContextData?: Record<string, unknown>;
|
||||
|
||||
/**
|
||||
* Hook which is used to customize original options, we can reorder/add/remove plugins/processors
|
||||
* of the existing solution.
|
||||
@ -126,6 +136,7 @@ export class ProjectBuilder implements IProjectBuilder {
|
||||
const builders = this.createModuleBuilders({
|
||||
extraContextData: {
|
||||
projectRemark: parseResult?.project?.projectRemark,
|
||||
template: this.template,
|
||||
},
|
||||
});
|
||||
// Generator Code module
|
||||
@ -263,7 +274,8 @@ export class ProjectBuilder implements IProjectBuilder {
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: 更多 slots 的处理??是不是可以考虑把 template 中所有的 slots 都处理下?
|
||||
// handle extra slots
|
||||
await this.generateExtraSlots(builders, parseResult, buildResult);
|
||||
|
||||
// Post Process
|
||||
const isSingleComponent = parseResult?.project?.projectRemark?.isSingleComponent;
|
||||
@ -320,6 +332,22 @@ export class ProjectBuilder implements IProjectBuilder {
|
||||
|
||||
return builders;
|
||||
}
|
||||
|
||||
private async generateExtraSlots(
|
||||
builders: Record<string, IModuleBuilder>,
|
||||
parseResult: IParseResult,
|
||||
buildResult: IModuleInfo[],
|
||||
) {
|
||||
for (const slotName in this.template.slots) {
|
||||
if (!isBuiltinSlotName(slotName)) {
|
||||
const { files } = await builders[slotName].generateModule(parseResult);
|
||||
buildResult.push({
|
||||
path: this.template.slots[slotName].path,
|
||||
files,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function createProjectBuilder(initOptions: ProjectBuilderInitOptions): IProjectBuilder {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* 低代码引擎的出码模块,负责将编排产出的 Schema 转换成实际可执行的代码。
|
||||
* 注意:为了保持 API 的稳定性, 这里所有导出的 API 均要显式命名方式导出
|
||||
* 注意:为了保持 API 的稳定性,这里所有导出的 API 均要显式命名方式导出
|
||||
* (即用 export { xxx } from 'xx' 的方式,不要直接 export * from 'xxx')
|
||||
* 而且所有导出的 API 务必在 tests/public 中编写单元测试
|
||||
*/
|
||||
@ -51,6 +51,7 @@ export default {
|
||||
},
|
||||
plugins: {
|
||||
common: {
|
||||
|
||||
/**
|
||||
* 处理 ES Module
|
||||
* @deprecated please use esModule
|
||||
|
||||
@ -443,6 +443,7 @@ function buildPackageImport(
|
||||
export interface PluginConfig {
|
||||
fileType?: string; // 导出的文件类型
|
||||
useAliasName?: boolean; // 是否使用 componentName 重命名组件 identifier
|
||||
filter?: (deps: IDependency[]) => IDependency[]; // 支持过滤能力
|
||||
}
|
||||
|
||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?: PluginConfig) => {
|
||||
@ -460,7 +461,8 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?: Plu
|
||||
const ir = next.ir as IWithDependency;
|
||||
|
||||
if (ir && ir.deps && ir.deps.length > 0) {
|
||||
const packs = groupDepsByPack(ir.deps);
|
||||
const deps = cfg.filter ? cfg.filter(ir.deps) : ir.deps;
|
||||
const packs = groupDepsByPack(deps);
|
||||
|
||||
Object.keys(packs).forEach((pkg) => {
|
||||
const chunks = buildPackageImport(pkg, packs[pkg], cfg.fileType, cfg.useAliasName);
|
||||
|
||||
@ -13,6 +13,7 @@ import {
|
||||
IContainerInfo,
|
||||
} from '../../../types';
|
||||
import { debug } from '../../../utils/debug';
|
||||
import { isJSExpressionFn } from '../../../utils/common';
|
||||
|
||||
export interface PluginConfig {
|
||||
fileType: string;
|
||||
@ -49,6 +50,7 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
|
||||
// 过滤掉非法数据(有些场景下会误传入空字符串或 null)
|
||||
if (
|
||||
!isJSFunction(lifeCycles[lifeCycleName]) &&
|
||||
!isJSExpressionFn(lifeCycles[lifeCycleName]) &&
|
||||
!isJSExpression(lifeCycles[lifeCycleName])
|
||||
) {
|
||||
return;
|
||||
|
||||
@ -75,8 +75,7 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
|
||||
|
||||
// 注意:这里其实隐含了一个假设:schema 中的 componentName 应该是一个有效的 JS 标识符,而且是大写字母打头的
|
||||
// FIXME: 为了快速修复临时加的逻辑,需要用 pre-process 的方式替代处理。
|
||||
const mapComponentNameToAliasOrKeepIt = (componentName: string) =>
|
||||
componentsNameAliasMap.get(componentName) || componentName;
|
||||
const mapComponentNameToAliasOrKeepIt = (componentName: string) => componentsNameAliasMap.get(componentName) || componentName;
|
||||
|
||||
// 然后过滤掉所有的别名 chunks
|
||||
next.chunks = next.chunks.filter((chunk) => !isImportAliasDefineChunk(chunk));
|
||||
|
||||
@ -26,7 +26,7 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
||||
|
||||
// 将模块名转换成 PascalCase 的格式,并添加特定后缀,防止命名冲突
|
||||
const componentClassName = ensureValidClassName(
|
||||
`${changeCase.pascalCase(ir.moduleName)}$$Page`,
|
||||
`${changeCase.pascalCase(ir.moduleName)}$$${ir.containerType}`,
|
||||
);
|
||||
|
||||
next.chunks.push({
|
||||
@ -43,6 +43,18 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
||||
],
|
||||
});
|
||||
|
||||
if (ir.containerType === 'Component') {
|
||||
next.chunks.push({
|
||||
type: ChunkType.STRING,
|
||||
fileType: FileType.JSX,
|
||||
name: CLASS_DEFINE_CHUNK_NAME.InsVar,
|
||||
content: `static displayName = '${changeCase.pascalCase(ir.moduleName)}';`,
|
||||
linkAfter: [
|
||||
CLASS_DEFINE_CHUNK_NAME.Start,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
next.chunks.push({
|
||||
type: ChunkType.STRING,
|
||||
fileType: FileType.JSX,
|
||||
|
||||
@ -13,12 +13,12 @@ import {
|
||||
} from '../../../types';
|
||||
|
||||
export interface PluginConfig {
|
||||
fileType: string;
|
||||
fileType?: string;
|
||||
implementType: 'inConstructor' | 'insMember' | 'hooks';
|
||||
}
|
||||
|
||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
||||
const cfg: PluginConfig = {
|
||||
const cfg: PluginConfig & { fileType: string } = {
|
||||
fileType: FileType.JSX,
|
||||
implementType: 'inConstructor',
|
||||
...config,
|
||||
|
||||
@ -29,6 +29,7 @@ import { generateCompositeType } from '../../../utils/compositeType';
|
||||
import { parseExpressionConvertThis2Context } from '../../../utils/expressionParser';
|
||||
import { isValidContainerType } from '../../../utils/schema';
|
||||
import { REACT_CHUNK_NAME } from './const';
|
||||
import { isJSExpressionFn } from '../../../utils/common';
|
||||
|
||||
export interface PluginConfig {
|
||||
fileType?: string;
|
||||
@ -37,6 +38,7 @@ export interface PluginConfig {
|
||||
* 数据源配置
|
||||
*/
|
||||
datasourceConfig?: {
|
||||
|
||||
/** 数据源引擎的版本 */
|
||||
engineVersion?: string;
|
||||
|
||||
@ -188,15 +190,15 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
|
||||
export default pluginFactory;
|
||||
|
||||
function wrapAsFunction(value: IPublicTypeCompositeValue, scope: IScope): IPublicTypeCompositeValue {
|
||||
if (isJSExpression(value) || isJSFunction(value)) {
|
||||
if (isJSExpression(value) || isJSFunction(value) || isJSExpressionFn(value)) {
|
||||
return {
|
||||
type: 'JSExpression',
|
||||
value: `function(){ return ((${value.value}))}`,
|
||||
value: `function(){ return ((${value.value}))}.bind(this)`,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'JSExpression',
|
||||
value: `function(){return((${generateCompositeType(value, scope)}))}`,
|
||||
value: `function(){return((${generateCompositeType(value, scope)}))}.bind(this)`,
|
||||
};
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ import {
|
||||
FileType,
|
||||
ICodeStruct,
|
||||
} from '../../../types';
|
||||
import { getSlotRelativePath } from '../../../utils/pathHelper';
|
||||
|
||||
export interface PluginConfig {
|
||||
fileType: string;
|
||||
@ -31,9 +32,8 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
|
||||
type: ChunkType.STRING,
|
||||
fileType: cfg.fileType,
|
||||
name: COMMON_CHUNK_NAME.InternalDepsImport,
|
||||
// TODO: 下面这个路径有没有更好的方式来获取?而非写死
|
||||
content: `
|
||||
import * as __$$i18n from '../../i18n';
|
||||
import * as __$$i18n from '${getSlotRelativePath({ contextData: next.contextData, from: 'components', to: 'i18n' })}';
|
||||
`,
|
||||
linkAfter: [COMMON_CHUNK_NAME.ExternalDepsImport],
|
||||
});
|
||||
|
||||
@ -11,15 +11,18 @@ import {
|
||||
FileType,
|
||||
ICodeStruct,
|
||||
IContainerInfo,
|
||||
IProjectTemplate,
|
||||
} from '../../../types';
|
||||
import { getSlotRelativePath } from '../../../utils/pathHelper';
|
||||
|
||||
export interface PluginConfig {
|
||||
fileType: string;
|
||||
fileType?: string;
|
||||
|
||||
/** prefer using class property to define utils */
|
||||
preferClassProperty?: boolean;
|
||||
}
|
||||
|
||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
||||
const cfg: PluginConfig = {
|
||||
const cfg: PluginConfig & { fileType: string } = {
|
||||
fileType: FileType.JSX,
|
||||
...config,
|
||||
};
|
||||
@ -33,37 +36,35 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
|
||||
next.contextData.useRefApi = true;
|
||||
const useRef = !!ir.analyzeResult?.isUsingRef;
|
||||
|
||||
// const isSingleComponent = next.contextData?.projectRemark?.isSingleComponent;
|
||||
// const template = next.contextData?.template;
|
||||
|
||||
// function getRelativeUtilsPath(template: IProjectTemplate, isSingleComponent: boolean) {
|
||||
// let relativeUtilsPath = '../../utils';
|
||||
// const utilsPath = template.slots.utils.path;
|
||||
// if (ir.containerType === 'Component') {
|
||||
// // TODO: isSingleComponent
|
||||
// relativeUtilsPath = getRelativePath(template.slots.components.path.join('/'), utilsPath.join('/'));
|
||||
// }
|
||||
// return relativeUtilsPath;
|
||||
// }
|
||||
|
||||
next.chunks.push({
|
||||
type: ChunkType.STRING,
|
||||
fileType: cfg.fileType,
|
||||
name: COMMON_CHUNK_NAME.InternalDepsImport,
|
||||
// TODO: 下面这个路径有没有更好的方式来获取?而非写死
|
||||
content: `
|
||||
import utils${useRef ? ', { RefsManager }' : ''} from '../../utils';
|
||||
import utils${useRef ? ', { RefsManager }' : ''} from '${getSlotRelativePath({ contextData: next.contextData, from: 'components', to: 'utils' })}';
|
||||
`,
|
||||
linkAfter: [COMMON_CHUNK_NAME.ExternalDepsImport],
|
||||
});
|
||||
|
||||
next.chunks.push({
|
||||
type: ChunkType.STRING,
|
||||
fileType: cfg.fileType,
|
||||
name: CLASS_DEFINE_CHUNK_NAME.ConstructorContent,
|
||||
content: 'this.utils = utils;',
|
||||
linkAfter: [CLASS_DEFINE_CHUNK_NAME.ConstructorStart],
|
||||
});
|
||||
if (cfg.preferClassProperty) {
|
||||
// mode: class property
|
||||
next.chunks.push({
|
||||
type: ChunkType.STRING,
|
||||
fileType: cfg.fileType,
|
||||
name: CLASS_DEFINE_CHUNK_NAME.InsVar,
|
||||
content: 'utils = utils;',
|
||||
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.InsVar]],
|
||||
});
|
||||
} else {
|
||||
// mode: assign in constructor
|
||||
next.chunks.push({
|
||||
type: ChunkType.STRING,
|
||||
fileType: cfg.fileType,
|
||||
name: CLASS_DEFINE_CHUNK_NAME.ConstructorContent,
|
||||
content: 'this.utils = utils;',
|
||||
linkAfter: [CLASS_DEFINE_CHUNK_NAME.ConstructorStart],
|
||||
});
|
||||
}
|
||||
|
||||
if (useRef) {
|
||||
next.chunks.push({
|
||||
|
||||
@ -13,6 +13,7 @@ import {
|
||||
IContainerInfo,
|
||||
} from '../../../types';
|
||||
import { isJSFunction, isJSExpression } from '@alilc/lowcode-types';
|
||||
import { isJSExpressionFn } from '../../../utils/common';
|
||||
|
||||
export interface PluginConfig {
|
||||
fileType: string;
|
||||
@ -41,6 +42,7 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
|
||||
// 过滤掉非法数据(有些场景下会误传入空字符串或 null)
|
||||
if (
|
||||
!isJSFunction(lifeCycles[lifeCycleName]) &&
|
||||
!isJSExpressionFn(lifeCycles[lifeCycleName]) &&
|
||||
!isJSExpression(lifeCycles[lifeCycleName])
|
||||
) {
|
||||
return null;
|
||||
|
||||
@ -22,6 +22,8 @@ const factory: PostProcessorFactory<ProcessorConfig> = (config?: ProcessorConfig
|
||||
let parser: prettier.BuiltInParserName | any;
|
||||
if (fileType === 'js' || fileType === 'jsx') {
|
||||
parser = 'babel';
|
||||
} else if (fileType === 'json') {
|
||||
parser = 'json-stringify';
|
||||
} else if (PARSERS.indexOf(fileType) >= 0) {
|
||||
parser = fileType;
|
||||
} else if (cfg.customFileTypeParser[fileType]) {
|
||||
|
||||
@ -1,20 +1,15 @@
|
||||
import {
|
||||
IPublicTypeJSONArray,
|
||||
IPublicTypeJSONObject,
|
||||
IPublicTypeCompositeArray,
|
||||
IPublicTypeCompositeObject,
|
||||
ResultDir,
|
||||
IPublicTypeCompositeObject, IPublicTypeJSExpression,
|
||||
IPublicTypeJSFunction, IPublicTypeJSONArray,
|
||||
IPublicTypeJSONObject, IPublicTypeJSSlot, IPublicTypeNodeDataType,
|
||||
IPublicTypeProjectSchema, ResultDir,
|
||||
ResultFile,
|
||||
IPublicTypeNodeDataType,
|
||||
IPublicTypeProjectSchema,
|
||||
IPublicTypeJSExpression,
|
||||
IPublicTypeJSFunction,
|
||||
IPublicTypeJSSlot,
|
||||
} from '@alilc/lowcode-types';
|
||||
|
||||
import { IParseResult } from './intermediate';
|
||||
import { IScopeBindings } from '../utils/ScopeBindings';
|
||||
import type { ProjectBuilderInitOptions } from '../generator/ProjectBuilder';
|
||||
import { IScopeBindings } from '../utils/ScopeBindings';
|
||||
import { IParseResult } from './intermediate';
|
||||
|
||||
export enum FileType {
|
||||
CSS = 'css',
|
||||
@ -22,8 +17,10 @@ export enum FileType {
|
||||
LESS = 'less',
|
||||
HTML = 'html',
|
||||
JS = 'js',
|
||||
MJS = 'mjs',
|
||||
JSX = 'jsx',
|
||||
TS = 'ts',
|
||||
MTS = 'mts',
|
||||
TSX = 'tsx',
|
||||
JSON = 'json',
|
||||
MD = 'md',
|
||||
@ -67,16 +64,16 @@ export interface ICodeStruct extends IBaseCodeStruct {
|
||||
/** 上下文数据,用来在插件之间共享一些数据 */
|
||||
export interface IContextData extends IProjectBuilderOptions {
|
||||
|
||||
/**
|
||||
* 是否使用了 Ref 的 API (this.$/this.$$)
|
||||
* */
|
||||
useRefApi?: boolean;
|
||||
|
||||
/**
|
||||
* 其他自定义数据
|
||||
* (三方自定义插件也可以在此放一些数据,建议起个长一点的名称,用自己的插件名做前缀,以防冲突)
|
||||
*/
|
||||
[key: string]: any;
|
||||
|
||||
/**
|
||||
* 是否使用了 Ref 的 API (this.$/this.$$)
|
||||
* */
|
||||
useRefApi?: boolean;
|
||||
}
|
||||
|
||||
export type BuilderComponentPlugin = (initStruct: ICodeStruct) => Promise<ICodeStruct>;
|
||||
@ -168,6 +165,7 @@ export interface IProjectBuilderOptions {
|
||||
* - expr: 求值的表达式
|
||||
*/
|
||||
evalErrorsHandler?: string;
|
||||
|
||||
/**
|
||||
* Hook which is used to customize original options, we can reorder/add/remove plugins/processors
|
||||
* of the existing solution.
|
||||
@ -180,7 +178,8 @@ export interface IProjectBuilder {
|
||||
}
|
||||
|
||||
/** 项目级别的前置处理器 */
|
||||
export type ProjectPreProcessor = (schema: IPublicTypeProjectSchema) => Promise<IPublicTypeProjectSchema> | IPublicTypeProjectSchema;
|
||||
export type ProjectPreProcessor = (schema: IPublicTypeProjectSchema) =>
|
||||
Promise<IPublicTypeProjectSchema> | IPublicTypeProjectSchema;
|
||||
|
||||
export interface ProjectPostProcessorOptions {
|
||||
parseResult?: IParseResult;
|
||||
@ -199,7 +198,7 @@ export type ProjectPostProcessor = (
|
||||
export type PostProcessorFactory<T> = (config?: T) => PostProcessor;
|
||||
|
||||
/** 模块级别的后置处理器 */
|
||||
export type PostProcessor = (content: string, fileType: string) => string;
|
||||
export type PostProcessor = (content: string, fileType: string, name?: string) => string;
|
||||
|
||||
// TODO: temp interface, need modify
|
||||
export interface IPluginOptions {
|
||||
|
||||
@ -35,4 +35,4 @@ export interface IDependency {
|
||||
main?: string; // 包导出组件入口文件路径 /lib/input
|
||||
dependencyType?: DependencyType; // 依赖类型 内/外
|
||||
componentName?: string; // 导入后名称
|
||||
}
|
||||
}
|
||||
@ -42,6 +42,7 @@ export interface IRouterInfo extends IWithDependency {
|
||||
* project's remarks
|
||||
*/
|
||||
export interface ProjectRemark {
|
||||
|
||||
/** if current project only contain one container which type is `Component` */
|
||||
isSingleComponent?: boolean;
|
||||
}
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import type { IPublicTypeJSExpression, IPublicTypeJSFunction } from '@alilc/lowcode-types';
|
||||
import changeCase from 'change-case';
|
||||
import short from 'short-uuid';
|
||||
import { DependencyType, IDependency, IExternalDependency, IInternalDependency } from '../types';
|
||||
|
||||
// Doc: https://www.npmjs.com/package/change-case
|
||||
|
||||
@ -39,3 +41,19 @@ export function getStaticExprValue<T>(expr: string): T {
|
||||
// eslint-disable-next-line no-new-func
|
||||
return Function(`"use strict";return (${expr})`)();
|
||||
}
|
||||
|
||||
export function isJSExpressionFn(data: any): data is IPublicTypeJSFunction {
|
||||
return data?.type === 'JSExpression' && data?.extType === 'function';
|
||||
}
|
||||
|
||||
export function isInternalDependency(
|
||||
dependency: IDependency,
|
||||
): dependency is IInternalDependency {
|
||||
return dependency.dependencyType === DependencyType.Internal;
|
||||
}
|
||||
|
||||
export function isExternalDependency(
|
||||
dependency: IDependency,
|
||||
): dependency is IExternalDependency {
|
||||
return dependency.dependencyType === DependencyType.External;
|
||||
}
|
||||
@ -16,6 +16,7 @@ import { generateExpression, generateFunction } from './jsExpression';
|
||||
import { generateJsSlot } from './jsSlot';
|
||||
import { executeFunctionStack } from './aopHelper';
|
||||
import { parseExpressionGetKeywords } from './expressionParser';
|
||||
import { isJSExpressionFn } from './common';
|
||||
|
||||
interface ILegaoVariable {
|
||||
type: 'variable';
|
||||
@ -159,7 +160,7 @@ function generateUnknownType(
|
||||
return generateExpression(value, scope);
|
||||
}
|
||||
|
||||
if (isJSFunction(value)) {
|
||||
if (isJSFunction(value) || isJSExpressionFn(value)) {
|
||||
if (options.handlers?.function) {
|
||||
return executeFunctionStack(value, scope, options.handlers.function, genFunction, options);
|
||||
}
|
||||
|
||||
@ -2,14 +2,18 @@ import changeCase from 'change-case';
|
||||
import type { IProjectInfo } from '../types/intermediate';
|
||||
|
||||
export interface DataSourceDependenciesConfig {
|
||||
|
||||
/** 数据源引擎的版本 */
|
||||
engineVersion?: string;
|
||||
|
||||
/** 数据源引擎的包名 */
|
||||
enginePackage?: string;
|
||||
|
||||
/** 数据源 handlers 的版本 */
|
||||
handlersVersion?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
|
||||
/** 数据源 handlers 的包名 */
|
||||
handlersPackages?: {
|
||||
[key: string]: string;
|
||||
|
||||
@ -12,6 +12,7 @@ import * as version from './version';
|
||||
import * as scope from './Scope';
|
||||
import * as expressionParser from './expressionParser';
|
||||
import * as dataSource from './dataSource';
|
||||
import * as pathHelper from './pathHelper';
|
||||
|
||||
export {
|
||||
common,
|
||||
@ -27,4 +28,5 @@ export {
|
||||
scope,
|
||||
expressionParser,
|
||||
dataSource,
|
||||
pathHelper,
|
||||
};
|
||||
|
||||
@ -5,6 +5,7 @@ import * as t from '@babel/types';
|
||||
import { IPublicTypeJSExpression, IPublicTypeJSFunction, isJSExpression, isJSFunction } from '@alilc/lowcode-types';
|
||||
import { CodeGeneratorError, IScope } from '../types';
|
||||
import { transformExpressionLocalRef, ParseError } from './expressionParser';
|
||||
import { isJSExpressionFn } from './common';
|
||||
|
||||
function parseFunction(content: string): t.FunctionExpression | null {
|
||||
try {
|
||||
@ -78,8 +79,13 @@ function getBodyStatements(content: string) {
|
||||
throw new Error('Can not find Function Statement');
|
||||
}
|
||||
|
||||
export function isJsCode(value: unknown): boolean {
|
||||
return isJSExpression(value) || isJSFunction(value);
|
||||
/**
|
||||
* 是否是广义上的 JSFunction
|
||||
* @param value
|
||||
* @returns
|
||||
*/
|
||||
export function isBroadJSFunction(value: unknown): boolean {
|
||||
return isJSExpressionFn(value) || isJSFunction(value);
|
||||
}
|
||||
|
||||
export function generateExpression(value: any, scope: IScope): string {
|
||||
@ -96,6 +102,10 @@ export function generateExpression(value: any, scope: IScope): string {
|
||||
throw new CodeGeneratorError('Not a JSExpression');
|
||||
}
|
||||
|
||||
function getFunctionSource(cfg: IPublicTypeJSFunction): string {
|
||||
return cfg.source || cfg.value || cfg.compiled;
|
||||
}
|
||||
|
||||
export function generateFunction(
|
||||
value: any,
|
||||
config: {
|
||||
@ -112,21 +122,26 @@ export function generateFunction(
|
||||
isBindExpr: false,
|
||||
},
|
||||
) {
|
||||
if (isJsCode(value)) {
|
||||
if (isBroadJSFunction(value)) {
|
||||
const functionCfg = value as IPublicTypeJSFunction;
|
||||
const functionSource = getFunctionSource(functionCfg);
|
||||
if (config.isMember) {
|
||||
return transformFuncExpr2MethodMember(config.name || '', functionCfg.value);
|
||||
return transformFuncExpr2MethodMember(config.name || '', functionSource);
|
||||
}
|
||||
if (config.isBlock) {
|
||||
return getBodyStatements(functionCfg.value);
|
||||
return getBodyStatements(functionSource);
|
||||
}
|
||||
if (config.isArrow) {
|
||||
return getArrowFunction(functionCfg.value);
|
||||
return getArrowFunction(functionSource);
|
||||
}
|
||||
if (config.isBindExpr) {
|
||||
return `(${functionCfg.value}).bind(this)`;
|
||||
return `(${functionSource}).bind(this)`;
|
||||
}
|
||||
return functionCfg.value;
|
||||
return functionSource;
|
||||
}
|
||||
|
||||
if (isJSExpression(value)) {
|
||||
return value.value;
|
||||
}
|
||||
|
||||
throw new CodeGeneratorError('Not a JSFunction or JSExpression');
|
||||
|
||||
@ -126,7 +126,7 @@ function generateAttrs(
|
||||
if (props) {
|
||||
if (!Array.isArray(props)) {
|
||||
Object.keys(props).forEach((propName: string) => {
|
||||
pieces = pieces.concat(generateAttr(propName, props[propName], scope, config));
|
||||
pieces = pieces.concat(generateAttr(propName, props[propName] as IPublicTypeCompositeValue, scope, config));
|
||||
});
|
||||
} else {
|
||||
props.forEach((prop) => {
|
||||
|
||||
41
modules/code-generator/src/utils/pathHelper.ts
Normal file
41
modules/code-generator/src/utils/pathHelper.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import { IContextData } from '../types';
|
||||
|
||||
function relativePath(from: string[], to: string[]): string[] {
|
||||
const length = Math.min(from.length, to.length);
|
||||
let samePartsLength = length;
|
||||
for (let i = 0; i < length; i++) {
|
||||
if (from[i] !== to[i]) {
|
||||
samePartsLength = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (samePartsLength === 0) {
|
||||
return to;
|
||||
}
|
||||
let outputParts = [];
|
||||
for (let i = samePartsLength; i < from.length; i++) {
|
||||
outputParts.push('..');
|
||||
}
|
||||
outputParts = [...outputParts, ...to.slice(samePartsLength)];
|
||||
if (outputParts[0] !== '..') {
|
||||
outputParts.unshift('.');
|
||||
}
|
||||
return outputParts;
|
||||
}
|
||||
|
||||
export function getSlotRelativePath(options: {
|
||||
contextData: IContextData;
|
||||
from: string;
|
||||
to: string;
|
||||
}) {
|
||||
const { contextData, from, to } = options;
|
||||
const isSingleComponent = contextData?.extraContextData?.projectRemark?.isSingleComponent;
|
||||
const template = contextData?.extraContextData?.template;
|
||||
let toPath = template.slots[to].path;
|
||||
toPath = [...toPath, template.slots[to].fileName!];
|
||||
let fromPath = template.slots[from].path;
|
||||
if (!isSingleComponent && ['components', 'pages'].indexOf(from) !== -1) {
|
||||
fromPath = [...fromPath, 'pageName'];
|
||||
}
|
||||
return relativePath(fromPath, toPath).join('/');
|
||||
}
|
||||
@ -13,6 +13,7 @@ import {
|
||||
isJSFunction,
|
||||
} from '@alilc/lowcode-types';
|
||||
import { CodeGeneratorError } from '../types/error';
|
||||
import { isJSExpressionFn } from './common';
|
||||
|
||||
export function isContainerSchema(x: any): x is IPublicTypeContainerSchema {
|
||||
return (
|
||||
@ -100,7 +101,7 @@ export function handleSubNodes<T>(
|
||||
});
|
||||
} else {
|
||||
Object.values(child.props).forEach((value) => {
|
||||
const childRes = handleCompositeValueInProps(value);
|
||||
const childRes = handleCompositeValueInProps(value as IPublicTypeCompositeValue);
|
||||
childrenRes.push(...childRes);
|
||||
});
|
||||
}
|
||||
@ -128,6 +129,7 @@ export function handleSubNodes<T>(
|
||||
// IPublicTypeCompositeObject
|
||||
if (
|
||||
!isJSExpression(value) &&
|
||||
!isJSExpressionFn(value) &&
|
||||
!isJSFunction(value) &&
|
||||
typeof value === 'object' &&
|
||||
value !== null
|
||||
|
||||
@ -253,7 +253,6 @@ class Home$$Page extends Component {
|
||||
if (!response.success) {
|
||||
throw new Error(response.message);
|
||||
}
|
||||
|
||||
return response.data;
|
||||
},
|
||||
isInit: true,
|
||||
@ -280,7 +279,6 @@ class Home$$Page extends Component {
|
||||
if (!response.success) {
|
||||
throw new Error(response.message);
|
||||
}
|
||||
|
||||
return response.data.result;
|
||||
},
|
||||
isInit: true,
|
||||
|
||||
@ -31,9 +31,16 @@
|
||||
"eslint": "eslint --cache --ext .js,.jsx ./",
|
||||
"stylelint": "stylelint ./**/*.scss"
|
||||
},
|
||||
"ideMode": { "name": "ice-react" },
|
||||
"iceworks": { "type": "react", "adapter": "adapter-react-v3" },
|
||||
"engines": { "node": ">=8.0.0" },
|
||||
"ideMode": {
|
||||
"name": "ice-react"
|
||||
},
|
||||
"iceworks": {
|
||||
"type": "react",
|
||||
"adapter": "adapter-react-v3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://gitlab.xxx.com/msd/leak-scan/tree/master"
|
||||
|
||||
@ -71,10 +71,10 @@ class Test$$Page extends React.Component {
|
||||
type: 'urlParams',
|
||||
isInit: function () {
|
||||
return undefined;
|
||||
},
|
||||
}.bind(_this),
|
||||
options: function () {
|
||||
return undefined;
|
||||
},
|
||||
}.bind(_this),
|
||||
},
|
||||
{
|
||||
id: 'user',
|
||||
@ -85,17 +85,16 @@ class Test$$Page extends React.Component {
|
||||
uri: 'https://shs.xxx.com/mock/1458/demo/user',
|
||||
isSync: true,
|
||||
};
|
||||
},
|
||||
}.bind(_this),
|
||||
dataHandler: function (response) {
|
||||
if (!response.data.success) {
|
||||
throw new Error(response.data.message);
|
||||
}
|
||||
|
||||
return response.data.data;
|
||||
},
|
||||
isInit: function () {
|
||||
return undefined;
|
||||
},
|
||||
}.bind(_this),
|
||||
},
|
||||
{
|
||||
id: 'orders',
|
||||
@ -106,17 +105,16 @@ class Test$$Page extends React.Component {
|
||||
uri: 'https://shs.xxx.com/mock/1458/demo/orders',
|
||||
isSync: true,
|
||||
};
|
||||
},
|
||||
}.bind(_this),
|
||||
dataHandler: function (response) {
|
||||
if (!response.data.success) {
|
||||
throw new Error(response.data.message);
|
||||
}
|
||||
|
||||
return response.data.data.result;
|
||||
},
|
||||
isInit: function () {
|
||||
return undefined;
|
||||
},
|
||||
}.bind(_this),
|
||||
},
|
||||
],
|
||||
dataHandler: function (dataMap) {
|
||||
|
||||
@ -71,7 +71,7 @@
|
||||
},
|
||||
"lifeCycles": {
|
||||
"componentDidMount": {
|
||||
"type": "JSExpression",
|
||||
"type": "JSFunction",
|
||||
"value": "function() { console.log('componentDidMount'); }"
|
||||
}
|
||||
},
|
||||
|
||||
@ -34,9 +34,16 @@
|
||||
"eslint": "eslint --cache --ext .js,.jsx ./",
|
||||
"stylelint": "stylelint ./**/*.scss"
|
||||
},
|
||||
"ideMode": { "name": "ice-react" },
|
||||
"iceworks": { "type": "react", "adapter": "adapter-react-v3" },
|
||||
"engines": { "node": ">=8.0.0" },
|
||||
"ideMode": {
|
||||
"name": "ice-react"
|
||||
},
|
||||
"iceworks": {
|
||||
"type": "react",
|
||||
"adapter": "adapter-react-v3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://gitlab.xxx.com/msd/leak-scan/tree/master"
|
||||
|
||||
@ -67,10 +67,10 @@ class Aaaa$$Page extends React.Component {
|
||||
return {
|
||||
uri: '',
|
||||
};
|
||||
},
|
||||
}.bind(_this),
|
||||
isInit: function () {
|
||||
return undefined;
|
||||
},
|
||||
}.bind(_this),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@ -29,9 +29,16 @@
|
||||
"eslint": "eslint --cache --ext .js,.jsx ./",
|
||||
"stylelint": "stylelint ./**/*.scss"
|
||||
},
|
||||
"ideMode": { "name": "ice-react" },
|
||||
"iceworks": { "type": "react", "adapter": "adapter-react-v3" },
|
||||
"engines": { "node": ">=8.0.0" },
|
||||
"ideMode": {
|
||||
"name": "ice-react"
|
||||
},
|
||||
"iceworks": {
|
||||
"type": "react",
|
||||
"adapter": "adapter-react-v3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://gitlab.xxx.com/msd/leak-scan/tree/master"
|
||||
|
||||
@ -71,7 +71,7 @@
|
||||
},
|
||||
"lifeCycles": {
|
||||
"componentDidMount": {
|
||||
"type": "JSExpression",
|
||||
"type": "JSFunction",
|
||||
"value": "function() { console.log('componentDidMount'); }"
|
||||
}
|
||||
},
|
||||
|
||||
@ -29,9 +29,16 @@
|
||||
"eslint": "eslint --cache --ext .js,.jsx ./",
|
||||
"stylelint": "stylelint ./**/*.scss"
|
||||
},
|
||||
"ideMode": { "name": "ice-react" },
|
||||
"iceworks": { "type": "react", "adapter": "adapter-react-v3" },
|
||||
"engines": { "node": ">=8.0.0" },
|
||||
"ideMode": {
|
||||
"name": "ice-react"
|
||||
},
|
||||
"iceworks": {
|
||||
"type": "react",
|
||||
"adapter": "adapter-react-v3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://gitlab.xxx.com/msd/leak-scan/tree/master"
|
||||
|
||||
@ -31,9 +31,16 @@
|
||||
"eslint": "eslint --cache --ext .js,.jsx ./",
|
||||
"stylelint": "stylelint ./**/*.scss"
|
||||
},
|
||||
"ideMode": { "name": "ice-react" },
|
||||
"iceworks": { "type": "react", "adapter": "adapter-react-v3" },
|
||||
"engines": { "node": ">=8.0.0" },
|
||||
"ideMode": {
|
||||
"name": "ice-react"
|
||||
},
|
||||
"iceworks": {
|
||||
"type": "react",
|
||||
"adapter": "adapter-react-v3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://gitlab.xxx.com/msd/leak-scan/tree/master"
|
||||
|
||||
@ -76,7 +76,7 @@ class Test$$Page extends React.Component {
|
||||
type: 'fetch',
|
||||
isInit: function () {
|
||||
return true;
|
||||
},
|
||||
}.bind(_this),
|
||||
options: function () {
|
||||
return {
|
||||
params: {},
|
||||
@ -86,7 +86,7 @@ class Test$$Page extends React.Component {
|
||||
headers: {},
|
||||
uri: 'https://mocks.xxx.com/mock/jjpin/user/list',
|
||||
};
|
||||
},
|
||||
}.bind(_this),
|
||||
id: 'users',
|
||||
},
|
||||
],
|
||||
|
||||
@ -32,9 +32,16 @@
|
||||
"eslint": "eslint --cache --ext .js,.jsx ./",
|
||||
"stylelint": "stylelint ./**/*.scss"
|
||||
},
|
||||
"ideMode": { "name": "ice-react" },
|
||||
"iceworks": { "type": "react", "adapter": "adapter-react-v3" },
|
||||
"engines": { "node": ">=8.0.0" },
|
||||
"ideMode": {
|
||||
"name": "ice-react"
|
||||
},
|
||||
"iceworks": {
|
||||
"type": "react",
|
||||
"adapter": "adapter-react-v3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://gitlab.xxx.com/msd/leak-scan/tree/master"
|
||||
|
||||
@ -31,9 +31,16 @@
|
||||
"eslint": "eslint --cache --ext .js,.jsx ./",
|
||||
"stylelint": "stylelint ./**/*.scss"
|
||||
},
|
||||
"ideMode": { "name": "ice-react" },
|
||||
"iceworks": { "type": "react", "adapter": "adapter-react-v3" },
|
||||
"engines": { "node": ">=8.0.0" },
|
||||
"ideMode": {
|
||||
"name": "ice-react"
|
||||
},
|
||||
"iceworks": {
|
||||
"type": "react",
|
||||
"adapter": "adapter-react-v3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://gitlab.xxx.com/msd/leak-scan/tree/master"
|
||||
|
||||
@ -71,10 +71,10 @@ class Test$$Page extends React.Component {
|
||||
type: 'urlParams',
|
||||
isInit: function () {
|
||||
return undefined;
|
||||
},
|
||||
}.bind(_this),
|
||||
options: function () {
|
||||
return undefined;
|
||||
},
|
||||
}.bind(_this),
|
||||
},
|
||||
{
|
||||
id: 'user',
|
||||
@ -85,17 +85,16 @@ class Test$$Page extends React.Component {
|
||||
uri: 'https://shs.xxx.com/mock/1458/demo/user',
|
||||
isSync: true,
|
||||
};
|
||||
},
|
||||
}.bind(_this),
|
||||
dataHandler: function (response) {
|
||||
if (!response.data.success) {
|
||||
throw new Error(response.data.message);
|
||||
}
|
||||
|
||||
return response.data.data;
|
||||
},
|
||||
isInit: function () {
|
||||
return undefined;
|
||||
},
|
||||
}.bind(_this),
|
||||
},
|
||||
{
|
||||
id: 'orders',
|
||||
@ -106,17 +105,16 @@ class Test$$Page extends React.Component {
|
||||
uri: 'https://shs.xxx.com/mock/1458/demo/orders',
|
||||
isSync: true,
|
||||
};
|
||||
},
|
||||
}.bind(_this),
|
||||
dataHandler: function (response) {
|
||||
if (!response.data.success) {
|
||||
throw new Error(response.data.message);
|
||||
}
|
||||
|
||||
return response.data.data.result;
|
||||
},
|
||||
isInit: function () {
|
||||
return undefined;
|
||||
},
|
||||
}.bind(_this),
|
||||
},
|
||||
],
|
||||
dataHandler: function (dataMap) {
|
||||
|
||||
@ -71,7 +71,7 @@
|
||||
},
|
||||
lifeCycles: {
|
||||
componentDidMount: {
|
||||
type: 'JSExpression',
|
||||
type: 'JSFunction',
|
||||
value: "function() { console.log('componentDidMount'); }",
|
||||
},
|
||||
},
|
||||
@ -91,7 +91,7 @@
|
||||
isSync: true,
|
||||
},
|
||||
dataHandler: {
|
||||
type: 'JSExpression',
|
||||
type: 'JSFunction',
|
||||
value: 'function (response) {\nif (!response.data.success){\n throw new Error(response.data.message);\n }\n return response.data.data;\n}',
|
||||
},
|
||||
},
|
||||
@ -105,13 +105,13 @@
|
||||
isSync: true,
|
||||
},
|
||||
dataHandler: {
|
||||
type: 'JSExpression',
|
||||
type: 'JSFunction',
|
||||
value: 'function (response) {\nif (!response.data.success){\n throw new Error(response.data.message);\n }\n return response.data.data.result;\n}',
|
||||
},
|
||||
},
|
||||
],
|
||||
dataHandler: {
|
||||
type: 'JSExpression',
|
||||
type: 'JSFunction',
|
||||
value: 'function (dataMap) {\n console.info("All datasources loaded:", dataMap);\n}',
|
||||
},
|
||||
},
|
||||
|
||||
@ -31,9 +31,16 @@
|
||||
"eslint": "eslint --cache --ext .js,.jsx ./",
|
||||
"stylelint": "stylelint ./**/*.scss"
|
||||
},
|
||||
"ideMode": { "name": "ice-react" },
|
||||
"iceworks": { "type": "react", "adapter": "adapter-react-v3" },
|
||||
"engines": { "node": ">=8.0.0" },
|
||||
"ideMode": {
|
||||
"name": "ice-react"
|
||||
},
|
||||
"iceworks": {
|
||||
"type": "react",
|
||||
"adapter": "adapter-react-v3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://gitlab.xxx.com/msd/leak-scan/tree/master"
|
||||
|
||||
@ -151,6 +151,7 @@ class Test$$Page extends React.Component {
|
||||
|
||||
onOkModifyDialogThird() {
|
||||
//第三步 修改 对话框 确定
|
||||
|
||||
this.setState({
|
||||
currentStep: 0,
|
||||
isModifyDialogVisible: false,
|
||||
@ -159,6 +160,7 @@ class Test$$Page extends React.Component {
|
||||
|
||||
onCancelModifyDialogThird() {
|
||||
//第三步 修改 对话框 取消
|
||||
|
||||
this.setState({
|
||||
isModifyDialogVisible: false,
|
||||
});
|
||||
|
||||
@ -30,9 +30,16 @@
|
||||
"eslint": "eslint --cache --ext .js,.jsx ./",
|
||||
"stylelint": "stylelint ./**/*.scss"
|
||||
},
|
||||
"ideMode": { "name": "ice-react" },
|
||||
"iceworks": { "type": "react", "adapter": "adapter-react-v3" },
|
||||
"engines": { "node": ">=8.0.0" },
|
||||
"ideMode": {
|
||||
"name": "ice-react"
|
||||
},
|
||||
"iceworks": {
|
||||
"type": "react",
|
||||
"adapter": "adapter-react-v3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://gitlab.xxx.com/msd/leak-scan/tree/master"
|
||||
|
||||
@ -63,10 +63,10 @@ class Example$$Page extends React.Component {
|
||||
return {
|
||||
uri: 'https://api.example.com/user/list',
|
||||
};
|
||||
},
|
||||
}.bind(_this),
|
||||
isInit: function () {
|
||||
return undefined;
|
||||
},
|
||||
}.bind(_this),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@ -30,9 +30,16 @@
|
||||
"eslint": "eslint --cache --ext .js,.jsx ./",
|
||||
"stylelint": "stylelint ./**/*.scss"
|
||||
},
|
||||
"ideMode": { "name": "ice-react" },
|
||||
"iceworks": { "type": "react", "adapter": "adapter-react-v3" },
|
||||
"engines": { "node": ">=8.0.0" },
|
||||
"ideMode": {
|
||||
"name": "ice-react"
|
||||
},
|
||||
"iceworks": {
|
||||
"type": "react",
|
||||
"adapter": "adapter-react-v3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://gitlab.xxx.com/msd/leak-scan/tree/master"
|
||||
|
||||
@ -59,14 +59,14 @@ class $$Page extends React.Component {
|
||||
id: 'todos',
|
||||
isInit: function () {
|
||||
return true;
|
||||
},
|
||||
}.bind(_this),
|
||||
type: 'jsonp',
|
||||
options: function () {
|
||||
return {
|
||||
method: 'GET',
|
||||
uri: 'https://a0ee9135-6a7f-4c0f-a215-f0f247ad907d.mock.pstmn.io',
|
||||
};
|
||||
},
|
||||
}.bind(_this),
|
||||
dataHandler: function dataHandler(data) {
|
||||
return data.data;
|
||||
},
|
||||
|
||||
@ -32,9 +32,16 @@
|
||||
"eslint": "eslint --cache --ext .js,.jsx ./",
|
||||
"stylelint": "stylelint ./**/*.scss"
|
||||
},
|
||||
"ideMode": { "name": "ice-react" },
|
||||
"iceworks": { "type": "react", "adapter": "adapter-react-v3" },
|
||||
"engines": { "node": ">=8.0.0" },
|
||||
"ideMode": {
|
||||
"name": "ice-react"
|
||||
},
|
||||
"iceworks": {
|
||||
"type": "react",
|
||||
"adapter": "adapter-react-v3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://gitlab.xxx.com/msd/leak-scan/tree/master"
|
||||
|
||||
@ -65,7 +65,6 @@ class Test$$Page extends React.Component {
|
||||
};
|
||||
|
||||
this.__jp__init();
|
||||
|
||||
this.statusDesc = {
|
||||
0: '失败',
|
||||
1: '成功',
|
||||
@ -163,7 +162,6 @@ class Test$$Page extends React.Component {
|
||||
if (!item) {
|
||||
return '暂无结果';
|
||||
}
|
||||
|
||||
const { channel, plat, version, status } = item;
|
||||
return [channel, plat, version, status].join('-');
|
||||
}
|
||||
|
||||
@ -32,9 +32,16 @@
|
||||
"eslint": "eslint --cache --ext .js,.jsx ./",
|
||||
"stylelint": "stylelint ./**/*.scss"
|
||||
},
|
||||
"ideMode": { "name": "ice-react" },
|
||||
"iceworks": { "type": "react", "adapter": "adapter-react-v3" },
|
||||
"engines": { "node": ">=8.0.0" },
|
||||
"ideMode": {
|
||||
"name": "ice-react"
|
||||
},
|
||||
"iceworks": {
|
||||
"type": "react",
|
||||
"adapter": "adapter-react-v3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://gitlab.xxx.com/msd/leak-scan/tree/master"
|
||||
|
||||
@ -67,7 +67,6 @@ class Test$$Page extends React.Component {
|
||||
};
|
||||
|
||||
this.__jp__init();
|
||||
|
||||
this.statusDesc = {
|
||||
0: '失败',
|
||||
1: '成功',
|
||||
@ -202,12 +201,10 @@ class Test$$Page extends React.Component {
|
||||
|
||||
componentDidMount() {
|
||||
this.$ds.resolve('PROJECTS');
|
||||
|
||||
if (this.userTimeout) {
|
||||
clearTimeout(this.userTimeout);
|
||||
this.userTimeout = null;
|
||||
}
|
||||
|
||||
if (this.projectTimeout) {
|
||||
clearTimeout(this.projectTimeout);
|
||||
this.projectTimeout = null;
|
||||
|
||||
@ -25,9 +25,16 @@
|
||||
"eslint": "eslint --cache --ext .js,.jsx ./",
|
||||
"stylelint": "stylelint ./**/*.scss"
|
||||
},
|
||||
"ideMode": { "name": "ice-react" },
|
||||
"iceworks": { "type": "react", "adapter": "adapter-react-v3" },
|
||||
"engines": { "node": ">=8.0.0" },
|
||||
"ideMode": {
|
||||
"name": "ice-react"
|
||||
},
|
||||
"iceworks": {
|
||||
"type": "react",
|
||||
"adapter": "adapter-react-v3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://gitlab.xxx.com/msd/leak-scan/tree/master"
|
||||
|
||||
@ -19,7 +19,12 @@ export function App() {
|
||||
`;
|
||||
|
||||
exports[`postprocessor/prettier should works for json file 1`] = `
|
||||
"{ \\"components\\": [\\"Button\\", \\"Block\\"] }
|
||||
"{
|
||||
\\"components\\": [
|
||||
\\"Button\\",
|
||||
\\"Block\\"
|
||||
]
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user