From 764e841336eff8a869ee0edc4bcecc774764a66b Mon Sep 17 00:00:00 2001 From: 1ncounter <1ncounter.100@gmail.com> Date: Wed, 10 Apr 2024 17:32:38 +0800 Subject: [PATCH] chore: lint fixed --- .gitignore | 2 +- .npmrc | 1 + eslint.config.js | 29 +- package.json | 3 +- packages/designer/package.json | 4 + .../bem-tools/border-container.tsx | 6 +- .../src/builtin-simulator/bem-tools/index.tsx | 2 +- .../builtin-simulator/bem-tools/manager.ts | 2 +- .../designer/src/builtin-simulator/host.ts | 12 +- .../live-editing/live-editing.ts | 4 +- .../builtin-simulator/node-selector/index.tsx | 20 +- packages/designer/src/component-actions.ts | 2 +- packages/designer/src/component-meta.ts | 8 +- packages/designer/src/context-menu-actions.ts | 2 +- packages/designer/src/designer/designer.ts | 10 +- .../src/designer/setting/setting-field.ts | 6 +- .../src/designer/setting/setting-top-entry.ts | 2 +- .../designer/src/designer/setting/utils.ts | 6 +- .../designer/src/document/document-model.ts | 6 +- packages/designer/src/document/history.ts | 8 +- .../src/document/node/node-children.ts | 16 +- packages/designer/src/document/node/node.ts | 18 +- .../designer/src/document/node/props/prop.ts | 2 +- .../designer/src/document/node/props/props.ts | 8 +- .../document/node/props/value-to-source.ts | 14 +- .../designer/src/plugin/plugin-context.ts | 8 +- packages/designer/src/project/project.ts | 36 +- packages/designer/src/types/index.ts | 2 +- packages/designer/src/utils/misc.ts | 4 +- .../editor-core/__tests__/command.spec.ts | 0 packages/editor-core/package.json | 4 + packages/editor-core/src/di/setter.ts | 2 +- packages/editor-core/src/editor.ts | 6 +- packages/editor-core/src/event-bus.ts | 2 +- packages/editor-core/src/hotkey.ts | 4 +- .../editor-core/src/intl/global-locale.ts | 4 +- packages/editor-core/src/utils/control.ts | 2 +- packages/editor-core/src/utils/preference.ts | 2 +- .../editor-core/src/widgets/tip/help-tips.tsx | 2 +- .../editor-core/src/widgets/title/index.tsx | 2 +- packages/editor-core/vitest.config.ts | 5 + packages/editor-skeleton/package.json | 4 + .../src/components/settings/settings-pane.tsx | 84 +-- .../settings/settings-primary-pane.tsx | 46 +- .../src/components/settings/utils.ts | 6 +- packages/editor-skeleton/src/icons/arrow.tsx | 2 +- packages/editor-skeleton/src/icons/exit.tsx | 2 +- packages/editor-skeleton/src/layouts/index.ts | 2 +- .../src/layouts/sub-top-area.tsx | 2 +- packages/editor-skeleton/src/skeleton.ts | 39 +- .../src/transducers/addon-combine.ts | 30 +- .../src/transducers/parse-func.ts | 2 +- packages/editor-skeleton/src/widget/index.ts | 2 +- packages/engine/package.json | 4 + packages/engine/src/engine-core.ts | 114 ++-- packages/engine/src/index.ts | 1 + .../src/inner-plugins/builtin-hotkey.ts | 2 +- .../src/inner-plugins/default-context-menu.ts | 4 +- .../src/inner-plugins/setter-registry.ts | 10 +- packages/engine/src/module.d.ts | 2 +- packages/engine/src/modules/classes.ts | 1 - packages/engine/src/modules/designer-types.ts | 2 +- packages/engine/src/modules/lowcode-types.ts | 2 +- .../engine/src/modules/shell-model-factory.ts | 2 +- packages/engine/src/shell/api/common.tsx | 2 +- packages/engine/src/shell/api/hotkey.ts | 17 +- packages/engine/src/shell/api/logger.ts | 2 +- packages/engine/src/shell/api/material.ts | 2 +- packages/engine/src/shell/api/plugins.ts | 4 +- packages/engine/src/shell/api/project.ts | 12 +- packages/engine/src/shell/api/skeleton.ts | 8 +- .../src/shell/components/context-menu.tsx | 2 +- .../engine/src/shell/model/active-tracker.ts | 2 +- packages/engine/src/shell/model/clipboard.ts | 8 +- .../engine/src/shell/model/component-meta.ts | 12 +- packages/engine/src/shell/model/detecting.ts | 2 +- .../engine/src/shell/model/document-model.ts | 18 +- .../engine/src/shell/model/drag-object.ts | 2 +- packages/engine/src/shell/model/dragon.ts | 6 +- .../engine/src/shell/model/locate-event.ts | 2 +- .../src/shell/model/modal-nodes-manager.ts | 4 +- packages/engine/src/shell/model/node.ts | 38 +- packages/engine/src/shell/model/prop.ts | 2 +- packages/engine/src/shell/model/props.ts | 2 +- packages/engine/src/shell/model/resource.ts | 2 +- .../src/shell/model/setting-top-entry.ts | 2 +- .../src/shell/model/simulator-render.ts | 2 +- .../engine/src/shell/model/skeleton-item.ts | 2 +- packages/engine/src/shell/symbols.ts | 2 +- .../src/workspace/context/base-context.ts | 2 +- .../src/workspace/layouts/workbench.tsx | 6 +- .../engine/src/workspace/resource-type.ts | 2 +- packages/engine/src/workspace/resource.ts | 2 +- .../src/workspace/view/resource-view.tsx | 2 +- .../engine/src/workspace/view/window-view.tsx | 2 +- packages/engine/src/workspace/window.ts | 2 +- packages/engine/src/workspace/workspace.ts | 2 +- packages/engine/vitest.config.ts | 9 +- packages/plugin-command/src/index.ts | 2 +- .../src/controllers/pane-controller.ts | 2 +- .../src/controllers/tree-master.ts | 2 +- .../plugin-outline-pane/src/helper/consts.ts | 2 +- .../plugin-outline-pane/src/ric-shim.d.ts | 2 +- .../plugin-outline-pane/src/views/pane.tsx | 4 +- .../src/views/tree-branches.tsx | 22 +- .../src/views/tree-node.tsx | 32 +- .../src/views/tree-title.tsx | 12 +- .../plugin-outline-pane/src/views/tree.tsx | 4 +- packages/react-renderer/package.json | 4 +- packages/react-renderer/src/api/component.tsx | 2 + .../src/runtime-api/intl/parser.ts | 2 +- packages/react-renderer/src/utils/element.ts | 4 +- .../{tests => __tests__}/api/app.spec.ts | 0 .../api/component.spec.ts | 0 .../{tests => __tests__}/boosts.spec.ts | 0 .../{tests => __tests__}/code-runtime.spec.ts | 0 .../{tests => __tests__}/package.spec.ts | 0 .../{tests => __tests__}/plugin.spec.ts | 0 .../{tests => __tests__}/utils/hook.spec.ts | 6 +- .../utils/non-setter-proxy.spec.ts | 0 packages/renderer-core/package.json | 9 +- packages/renderer-core/src/index.ts | 2 +- packages/renderer-core/src/utils/error.ts | 2 +- packages/renderer-core/src/utils/hook.ts | 6 +- packages/renderer-core/vite.config.ts | 1 + .../renderer-router/__tests__/matcher.spec.ts | 7 + packages/renderer-router/package.json | 8 +- packages/renderer-router/src/history.ts | 10 +- packages/renderer-router/src/matcher.ts | 62 +- packages/renderer-router/src/router.ts | 33 +- packages/renderer-router/src/types.ts | 2 - .../renderer-router/src/utils/path-parser.ts | 53 -- .../src/utils/path-parser/index.ts | 9 + .../src/utils/path-parser/parser-ranker.ts | 370 +++++++++++ .../src/utils/path-parser/path-tokenizer.ts | 200 ++++++ packages/renderer-router/vite.config.ts | 1 + packages/renderer-router/vitest.config.ts | 5 + packages/types/src/editor.ts | 2 +- packages/types/src/shell/api/command.ts | 2 +- packages/types/src/shell/api/common.ts | 6 +- packages/types/src/shell/api/hotkey.ts | 8 +- packages/types/src/shell/api/index.ts | 2 +- packages/types/src/shell/api/material.ts | 6 +- packages/types/src/shell/api/plugins.ts | 4 +- packages/types/src/shell/api/project.ts | 6 +- packages/types/src/shell/enum/context-menu.ts | 2 +- packages/types/src/shell/enum/event-names.ts | 2 +- packages/types/src/shell/enum/index.ts | 2 +- .../src/shell/enum/plugin-register-level.ts | 2 +- packages/types/src/shell/index.ts | 2 +- packages/types/src/shell/model/clipboard.ts | 6 +- .../types/src/shell/model/component-meta.ts | 6 +- packages/types/src/shell/model/editor-view.ts | 2 +- packages/types/src/shell/model/node.ts | 18 +- packages/types/src/shell/model/props.ts | 2 +- packages/types/src/shell/model/scroller.ts | 2 +- .../types/src/shell/model/setting-field.ts | 2 +- .../src/shell/model/setting-prop-entry.ts | 2 +- .../types/src/shell/model/skeleton-item.ts | 2 +- packages/types/src/shell/model/window.ts | 2 +- packages/types/src/shell/type/advanced.ts | 2 +- packages/types/src/shell/type/command.ts | 2 +- .../src/shell/type/component-instance.ts | 2 +- packages/types/src/shell/type/context-menu.ts | 4 +- packages/types/src/shell/type/disposable.ts | 2 +- .../src/shell/type/editor-view-config.ts | 2 +- packages/types/src/shell/type/editor-view.ts | 2 +- .../types/src/shell/type/engine-options.ts | 2 +- .../src/shell/type/hotkey-callback-config.ts | 2 +- .../types/src/shell/type/hotkey-callbacks.ts | 2 +- packages/types/src/shell/type/location.ts | 2 +- packages/types/src/shell/type/plugin.ts | 2 +- .../types/src/shell/type/resource-list.ts | 2 +- .../types/src/shell/type/resource-type.ts | 2 +- packages/types/src/shell/type/value-type.ts | 2 +- packages/utils/src/check-types/index.ts | 2 +- .../src/check-types/is-basic-prop-type.ts | 2 +- .../src/check-types/is-component-schema.ts | 4 +- .../src/check-types/is-drag-any-object.ts | 2 +- .../check-types/is-drag-node-data-object.ts | 2 +- .../src/check-types/is-drag-node-object.ts | 2 +- packages/utils/src/check-types/is-function.ts | 2 +- .../is-location-children-detail.ts | 2 +- .../utils/src/check-types/is-location-data.ts | 2 +- packages/utils/src/check-types/is-node.ts | 2 +- packages/utils/src/check-types/is-object.ts | 2 +- .../src/check-types/is-required-prop-type.ts | 2 +- packages/utils/src/create-content.ts | 6 +- packages/utils/src/css-helper.ts | 14 +- packages/utils/src/is-shaken.ts | 2 +- packages/utils/src/logger.ts | 10 +- packages/utils/src/node-helper.ts | 2 +- packages/utils/src/schema.ts | 4 +- playground/engine/index.html | 20 +- playground/engine/src/index.css | 2 +- playground/engine/src/index.ts | 50 +- .../src/plugins/plugin-editor-init/index.tsx | 49 ++ playground/engine/src/services/assets.json | 140 +++++ .../src/services/defaultI18nSchema.json | 10 + .../src/services/defaultPageSchema.json | 580 ++++++++++++++++++ playground/engine/src/services/mockService.ts | 118 ++++ playground/engine/src/services/schema.json | 445 ++++++++++++++ playground/package.json | 12 +- playground/vite.config.ts | 12 +- scripts/build.js | 9 +- tsconfig.json | 3 +- vitest.workspace.ts | 13 + 207 files changed, 2700 insertions(+), 660 deletions(-) create mode 100644 .npmrc create mode 100644 packages/editor-core/__tests__/command.spec.ts rename packages/renderer-core/{tests => __tests__}/api/app.spec.ts (100%) rename packages/renderer-core/{tests => __tests__}/api/component.spec.ts (100%) rename packages/renderer-core/{tests => __tests__}/boosts.spec.ts (100%) rename packages/renderer-core/{tests => __tests__}/code-runtime.spec.ts (100%) rename packages/renderer-core/{tests => __tests__}/package.spec.ts (100%) rename packages/renderer-core/{tests => __tests__}/plugin.spec.ts (100%) rename packages/renderer-core/{tests => __tests__}/utils/hook.spec.ts (96%) rename packages/renderer-core/{tests => __tests__}/utils/non-setter-proxy.spec.ts (100%) create mode 100644 packages/renderer-router/__tests__/matcher.spec.ts delete mode 100644 packages/renderer-router/src/utils/path-parser.ts create mode 100644 packages/renderer-router/src/utils/path-parser/index.ts create mode 100644 packages/renderer-router/src/utils/path-parser/parser-ranker.ts create mode 100644 packages/renderer-router/src/utils/path-parser/path-tokenizer.ts create mode 100644 playground/engine/src/plugins/plugin-editor-init/index.tsx create mode 100644 playground/engine/src/services/assets.json create mode 100644 playground/engine/src/services/defaultI18nSchema.json create mode 100644 playground/engine/src/services/defaultPageSchema.json create mode 100644 playground/engine/src/services/mockService.ts create mode 100644 playground/engine/src/services/schema.json create mode 100644 vitest.workspace.ts diff --git a/.gitignore b/.gitignore index 9bcfb4675..804755b3d 100644 --- a/.gitignore +++ b/.gitignore @@ -110,4 +110,4 @@ typings/ codealike.json .node -.must.config.js \ No newline at end of file +.must.config.js diff --git a/.npmrc b/.npmrc new file mode 100644 index 000000000..125f6d0e1 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +git-checks=false \ No newline at end of file diff --git a/eslint.config.js b/eslint.config.js index 851559db2..3cfaa3db8 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,23 +1,18 @@ import stylistic from '@stylistic/eslint-plugin'; -import tseslint from 'typescript-eslint' +import tseslint from 'typescript-eslint'; import js from '@eslint/js'; -import react from 'eslint-plugin-react' +import react from 'eslint-plugin-react'; import reactHooks from 'eslint-plugin-react-hooks'; -import reactRefresh from 'eslint-plugin-react-refresh'; -import globals from 'globals' +import globals from 'globals'; export default tseslint.config({ - files: ['packages/*/src/**/*.{ts?(x),js?(x)}'], - ignores: ["**/*.test.ts"], - extends: [ - js.configs.recommended, - ...tseslint.configs.recommended, - ], + files: ['packages/*/{src,__tests__}/**/*.{ts?(x),js?(x)}'], + ignores: ['**/*.test.ts'], + extends: [js.configs.recommended, ...tseslint.configs.recommended], plugins: { '@stylistic': stylistic, react, 'react-hooks': reactHooks, - 'react-refresh': reactRefresh }, languageOptions: { parserOptions: { @@ -28,18 +23,22 @@ export default tseslint.config({ globals: { ...globals.browser, ...globals.nodeBuiltin, - ...globals.jest + ...globals.jest, }, }, rules: { '@stylistic/indent': ['error', 2], '@stylistic/indent-binary-ops': ['error', 2], - '@stylistic/max-len': ['error', { tabWidth: 2, "ignoreStrings": true }], + '@stylistic/max-len': ['error', { code: 100, tabWidth: 2, ignoreStrings: true, ignoreComments: true }], '@stylistic/no-tabs': 'error', '@stylistic/quotes': ['error', 'single'], '@stylistic/jsx-pascal-case': [2], '@stylistic/jsx-indent': [2, 2, { checkAttributes: true, indentLogicalExpressions: true }], '@stylistic/semi': ['error', 'always'], + '@stylistic/eol-last': ['error', 'always'], + '@stylistic/jsx-quotes': ['error', 'prefer-double'], + + "@typescript-eslint/ban-ts-comment": ["error", { 'ts-expect-error': 'allow-with-description' }], 'react/jsx-no-undef': 'error', 'react/jsx-uses-vars': 'error', @@ -50,7 +49,5 @@ export default tseslint.config({ 'react-hooks/rules-of-hooks': 'error', // Checks rules of Hooks 'react-hooks/exhaustive-deps': 'warn', // Checks effect dependencies - - 'react-refresh/only-export-components': 'warn', }, -}) +}); diff --git a/package.json b/package.json index a8d695306..575faa62b 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,8 @@ "type": "module", "scripts": { "playground": "pnpm --filter playground dev", - "test": "pnpm -r test", "build": "node ./scripts/build.js", + "test": "vitest", "clean": "rimraf ./packages/*/dist", "clean:lib": "rimraf ./node_modules ./packages/*/node_modules", "lint": "eslint . --cache", @@ -35,7 +35,6 @@ "eslint": "^8.57.0", "eslint-plugin-react": "^7.34.1", "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-react-refresh": "^0.4.6", "globals": "^15.0.0", "husky": "^9.0.11", "less": "^4.2.0", diff --git a/packages/designer/package.json b/packages/designer/package.json index 771289710..3bcbde815 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -11,6 +11,10 @@ "import": "./dist/low-code-designer.js", "require": "./dist/low-code-designer.cjs", "types": "./dist/index.d.ts" + }, + "./dist/": { + "import": "./dist/", + "require": "./dist/" } }, "files": [ diff --git a/packages/designer/src/builtin-simulator/bem-tools/border-container.tsx b/packages/designer/src/builtin-simulator/bem-tools/border-container.tsx index 212cb80bb..0854564bd 100644 --- a/packages/designer/src/builtin-simulator/bem-tools/border-container.tsx +++ b/packages/designer/src/builtin-simulator/bem-tools/border-container.tsx @@ -50,8 +50,8 @@ function getTitle(title: string | IPublicTypeI18nData | ReactElement) { export class BorderContainer extends Component<{ host: BuiltinSimulatorHost; }, { - target?: INode; -}> { + target?: INode; + }> { state = {} as any; @computed get scale() { @@ -70,7 +70,7 @@ export class BorderContainer extends Component<{ const { host } = this.props; host.designer.editor.eventBus.on('designer.dropLocation.change', (loc: DropLocation) => { - let { target } = this.state; + const { target } = this.state; if (target === loc?.target) return; this.setState({ target: loc?.target, diff --git a/packages/designer/src/builtin-simulator/bem-tools/index.tsx b/packages/designer/src/builtin-simulator/bem-tools/index.tsx index bc485af1b..a3ba81c4b 100644 --- a/packages/designer/src/builtin-simulator/bem-tools/index.tsx +++ b/packages/designer/src/builtin-simulator/bem-tools/index.tsx @@ -34,4 +34,4 @@ export class BemTools extends Component<{ host: BuiltinSimulatorHost }> { ); } -} \ No newline at end of file +} diff --git a/packages/designer/src/builtin-simulator/bem-tools/manager.ts b/packages/designer/src/builtin-simulator/bem-tools/manager.ts index 3756600ed..1b1eb1de3 100644 --- a/packages/designer/src/builtin-simulator/bem-tools/manager.ts +++ b/packages/designer/src/builtin-simulator/bem-tools/manager.ts @@ -34,4 +34,4 @@ export class BemToolsManager { getAllBemTools() { return this.toolsContainer; } -} \ No newline at end of file +} diff --git a/packages/designer/src/builtin-simulator/host.ts b/packages/designer/src/builtin-simulator/host.ts index ffdec7f3f..740f11da0 100644 --- a/packages/designer/src/builtin-simulator/host.ts +++ b/packages/designer/src/builtin-simulator/host.ts @@ -1225,9 +1225,9 @@ export class BuiltinSimulatorHost implements ISimulatorHost 1 ? instances.find( - (_inst) => - this.getClosestNodeInstance(_inst, container.id)?.instance === containerInstance, - ) + (_inst) => + this.getClosestNodeInstance(_inst, container.id)?.instance === containerInstance, + ) : instances[0] : null; const rect = inst diff --git a/packages/designer/src/builtin-simulator/live-editing/live-editing.ts b/packages/designer/src/builtin-simulator/live-editing/live-editing.ts index 27e0dbeae..b97e225af 100644 --- a/packages/designer/src/builtin-simulator/live-editing/live-editing.ts +++ b/packages/designer/src/builtin-simulator/live-editing/live-editing.ts @@ -197,8 +197,8 @@ export class LiveEditing { export type SpecificRule = (target: EditingTarget) => | (IPublicTypeLiveTextEditingConfig & { - propElement?: HTMLElement; - }) + propElement?: HTMLElement; + }) | null; export interface SaveHandler { diff --git a/packages/designer/src/builtin-simulator/node-selector/index.tsx b/packages/designer/src/builtin-simulator/node-selector/index.tsx index 1ff60101b..9d0af9fa1 100644 --- a/packages/designer/src/builtin-simulator/node-selector/index.tsx +++ b/packages/designer/src/builtin-simulator/node-selector/index.tsx @@ -81,19 +81,19 @@ export default class InstanceNodeSelector extends React.Component - (_: any, flag = true) => { - if (node && typeof node.hover === 'function') { - node.hover(flag); - } - }; + (_: any, flag = true) => { + if (node && typeof node.hover === 'function') { + node.hover(flag); + } + }; onMouseOut = (node: INode) => - (_: any, flag = false) => { - if (node && typeof node.hover === 'function') { - node.hover(flag); - } - }; + (_: any, flag = false) => { + if (node && typeof node.hover === 'function') { + node.hover(flag); + } + }; renderNodes = () => { const nodes = this.state.parentNodes; diff --git a/packages/designer/src/component-actions.ts b/packages/designer/src/component-actions.ts index 57ad30bf2..3c0c290a4 100644 --- a/packages/designer/src/component-actions.ts +++ b/packages/designer/src/component-actions.ts @@ -160,4 +160,4 @@ export class ComponentActions { getRegisteredMetadataTransducers(): IPublicTypeMetadataTransducer[] { return this.metadataTransducers; } -} \ No newline at end of file +} diff --git a/packages/designer/src/component-meta.ts b/packages/designer/src/component-meta.ts index 7ec4a175d..4cf422868 100644 --- a/packages/designer/src/component-meta.ts +++ b/packages/designer/src/component-meta.ts @@ -226,10 +226,10 @@ export class ComponentMeta implements IComponentMeta { this._title = typeof title === 'string' ? { - type: 'i18n', - 'en-US': this.componentName, - 'zh-CN': title, - } + type: 'i18n', + 'en-US': this.componentName, + 'zh-CN': title, + } : title; } diff --git a/packages/designer/src/context-menu-actions.ts b/packages/designer/src/context-menu-actions.ts index 87348d6c8..4fa029a77 100644 --- a/packages/designer/src/context-menu-actions.ts +++ b/packages/designer/src/context-menu-actions.ts @@ -45,7 +45,7 @@ export class GlobalContextMenuActions { event.preventDefault(); const actions: IPublicTypeContextMenuAction[] = []; - let contextMenu: ContextMenuActions = this.contextMenuActionsMap.values().next().value; + const contextMenu: ContextMenuActions = this.contextMenuActionsMap.values().next().value; this.contextMenuActionsMap.forEach((contextMenu) => { actions.push(...contextMenu.actions); }); diff --git a/packages/designer/src/designer/designer.ts b/packages/designer/src/designer/designer.ts index 48c163493..cc5dfbe3b 100644 --- a/packages/designer/src/designer/designer.ts +++ b/packages/designer/src/designer/designer.ts @@ -55,9 +55,9 @@ export interface DesignerProps { onDragstart?: (e: IPublicModelLocateEvent) => void; onDrag?: (e: IPublicModelLocateEvent) => void; onDragend?: ( - e: { dragObject: IPublicModelDragObject; copy: boolean }, - loc?: DropLocation, - ) => void; + e: { dragObject: IPublicModelDragObject; copy: boolean }, + loc?: DropLocation, + ) => void; } export class Designer { @@ -406,8 +406,8 @@ export class Designer { if (components) { // 合并 assets - let assets = this.editor.get('assets') || {}; - let newAssets = mergeAssets(assets, incrementalAssets); + const assets = this.editor.get('assets') || {}; + const newAssets = mergeAssets(assets, incrementalAssets); // 对于 assets 存在需要二次网络下载的过程,必须 await 等待结束之后,再进行事件触发 await this.editor.set('assets', newAssets); } diff --git a/packages/designer/src/designer/setting/setting-field.ts b/packages/designer/src/designer/setting/setting-field.ts index 56bf22466..8ef57aa9a 100644 --- a/packages/designer/src/designer/setting/setting-field.ts +++ b/packages/designer/src/designer/setting/setting-field.ts @@ -37,10 +37,10 @@ function getSettingFieldCollectorKey( // @ts-ignore export interface ISettingField extends ISettingPropEntry, - Omit< - IBaseModelSettingField, + Omit< + IBaseModelSettingField, 'setValue' | 'key' | 'node' - > { + > { readonly isSettingField: true; readonly isRequired: boolean; diff --git a/packages/designer/src/designer/setting/setting-top-entry.ts b/packages/designer/src/designer/setting/setting-top-entry.ts index 7d7b6ab68..e62b66b99 100644 --- a/packages/designer/src/designer/setting/setting-top-entry.ts +++ b/packages/designer/src/designer/setting/setting-top-entry.ts @@ -21,7 +21,7 @@ function generateSessionId(nodes: INode[]) { export interface ISettingTopEntry extends ISettingEntry, - IPublicModelSettingTopEntry { + IPublicModelSettingTopEntry { readonly top: ISettingTopEntry; readonly parent: ISettingTopEntry; diff --git a/packages/designer/src/designer/setting/utils.ts b/packages/designer/src/designer/setting/utils.ts index 81916f501..f8dfdf99c 100644 --- a/packages/designer/src/designer/setting/utils.ts +++ b/packages/designer/src/designer/setting/utils.ts @@ -11,9 +11,9 @@ function getHotterFromSetter(setter: any) { function getTransducerFromSetter(setter: any) { return ( (setter && - (setter.transducer || - setter.Transducer || - (setter.type && (setter.type.transducer || setter.type.Transducer)))) || + (setter.transducer || + setter.Transducer || + (setter.type && (setter.type.transducer || setter.type.Transducer)))) || null ); // eslint-disable-line } diff --git a/packages/designer/src/document/document-model.ts b/packages/designer/src/document/document-model.ts index b8fc789a0..a7a3cc997 100644 --- a/packages/designer/src/document/document-model.ts +++ b/packages/designer/src/document/document-model.ts @@ -46,14 +46,14 @@ import { EDITOR_EVENT } from '../types'; export type GetDataType = T extends undefined ? NodeType extends { - schema: infer R; - } + schema: infer R; + } ? R : any : T; export class DocumentModel - implements +implements Omit< IPublicModelDocumentModel< ISelection, diff --git a/packages/designer/src/document/history.ts b/packages/designer/src/document/history.ts index ca288c03a..3a2f15257 100644 --- a/packages/designer/src/document/history.ts +++ b/packages/designer/src/document/history.ts @@ -41,10 +41,10 @@ export class History implements IHistory { private timeGap: number = 1000; constructor( - dataFn: () => T | null, - private redoer: (data: T) => void, - private document?: IDocumentModel, - ) { + dataFn: () => T | null, + private redoer: (data: T) => void, + private document?: IDocumentModel, + ) { this.session = new Session(0, null, this.timeGap); this.records = [this.session]; diff --git a/packages/designer/src/document/node/node-children.ts b/packages/designer/src/document/node/node-children.ts index b7f03d9fe..ff2e3645f 100644 --- a/packages/designer/src/document/node/node-children.ts +++ b/packages/designer/src/document/node/node-children.ts @@ -11,10 +11,10 @@ export interface IOnChangeOptions { } export class NodeChildren implements Omit, -'importSchema' | -'exportSchema' | -'isEmpty' | -'notEmpty' + 'importSchema' | + 'exportSchema' | + 'isEmpty' | + 'notEmpty' > { @obx.shallow children: INode[]; @@ -46,9 +46,9 @@ export class NodeChildren implements Omit, } constructor( - readonly owner: INode, - data: IPublicTypeNodeData | IPublicTypeNodeData[], - ) { + readonly owner: INode, + data: IPublicTypeNodeData | IPublicTypeNodeData[], + ) { makeObservable(this); this.children = (Array.isArray(data) ? data : [data]).filter(child => !!child).map((child) => { return this.owner.document?.createNode(child); @@ -469,4 +469,4 @@ export class NodeChildren implements Omit, } } -export interface INodeChildren extends NodeChildren {} \ No newline at end of file +export interface INodeChildren extends NodeChildren {} diff --git a/packages/designer/src/document/node/node.ts b/packages/designer/src/document/node/node.ts index 86bf76302..b6f03a6ca 100644 --- a/packages/designer/src/document/node/node.ts +++ b/packages/designer/src/document/node/node.ts @@ -97,7 +97,7 @@ export interface IBaseNode extends Node {} * hidden */ export class Node - implements +implements Omit< IBaseModelNode< IDocumentModel, @@ -191,7 +191,7 @@ export class Node } @computed get title(): string | IPublicTypeI18nData | ReactElement { - let t = this.getExtraProp('title'); + const t = this.getExtraProp('title'); // TODO: 暂时走不到这个分支 // if (!t && this.componentMeta.descriptor) { // t = this.getProp(this.componentMeta.descriptor, false); @@ -325,17 +325,17 @@ export class Node @action private initBuiltinProps() { this.props.has(getConvertedExtraKey('hidden')) || - this.props.add(false, getConvertedExtraKey('hidden')); + this.props.add(false, getConvertedExtraKey('hidden')); this.props.has(getConvertedExtraKey('title')) || - this.props.add('', getConvertedExtraKey('title')); + this.props.add('', getConvertedExtraKey('title')); this.props.has(getConvertedExtraKey('isLocked')) || - this.props.add(false, getConvertedExtraKey('isLocked')); + this.props.add(false, getConvertedExtraKey('isLocked')); this.props.has(getConvertedExtraKey('condition')) || - this.props.add(true, getConvertedExtraKey('condition')); + this.props.add(true, getConvertedExtraKey('condition')); this.props.has(getConvertedExtraKey('conditionGroup')) || - this.props.add('', getConvertedExtraKey('conditionGroup')); + this.props.add('', getConvertedExtraKey('conditionGroup')); this.props.has(getConvertedExtraKey('loop')) || - this.props.add(undefined, getConvertedExtraKey('loop')); + this.props.add(undefined, getConvertedExtraKey('loop')); } @action @@ -1164,7 +1164,7 @@ export class Node const isRGLContainerNode = this.isRGLContainer; const isRGLNode = this.getParent()?.isRGLContainer as boolean; const isRGL = isRGLContainerNode || (isRGLNode && (!isContainerNode || !isEmptyNode)); - let rglNode = isRGLContainerNode ? this : isRGL ? this?.getParent() : null; + const rglNode = isRGLContainerNode ? this : isRGL ? this?.getParent() : null; return { isContainerNode, isEmptyNode, isRGLContainerNode, isRGLNode, isRGL, rglNode }; } diff --git a/packages/designer/src/document/node/props/prop.ts b/packages/designer/src/document/node/props/prop.ts index 5a7187daa..bacf7b02a 100644 --- a/packages/designer/src/document/node/props/prop.ts +++ b/packages/designer/src/document/node/props/prop.ts @@ -646,7 +646,7 @@ export class Prop implements IProp, IPropParent { } } const prop = isProp(value) ? value : new Prop(this, value, key); - let items = this._items! || []; + const items = this._items! || []; if (this.type === 'list') { if (!isValidArrayIndex(key)) { return null; diff --git a/packages/designer/src/document/node/props/props.ts b/packages/designer/src/document/node/props/props.ts index 78995df57..bb2ac526c 100644 --- a/packages/designer/src/document/node/props/props.ts +++ b/packages/designer/src/document/node/props/props.ts @@ -138,13 +138,13 @@ export class Props implements Omit, | 'getExtraProp' | 'g if (this.items.length < 1) { return {}; } - let allProps = {} as any; + const allProps = {} as any; let props: any = {}; const extras: any = {}; if (this.type === 'list') { props = []; this.items.forEach((item) => { - let value = item.export(stage); + const value = item.export(stage); let name = item.key as string; if (name && typeof name === 'string' && name.startsWith(EXTRA_KEY_PREFIX)) { name = getOriginalExtraKey(name); @@ -159,9 +159,9 @@ export class Props implements Omit, | 'getExtraProp' | 'g }); } else { this.items.forEach((item) => { - let name = item.key as string; + const name = item.key as string; if (name == null || item.isUnset() || item.isVirtual()) return; - let value = item.export(stage); + const value = item.export(stage); if (value != null) { allProps[name] = value; } diff --git a/packages/designer/src/document/node/props/value-to-source.ts b/packages/designer/src/document/node/props/value-to-source.ts index 7d7de7f76..366f11754 100644 --- a/packages/designer/src/document/node/props/value-to-source.ts +++ b/packages/designer/src/document/node/props/value-to-source.ts @@ -14,7 +14,7 @@ function propertyNameRequiresQuotes(propertyName: string) { } function quoteString(str: string, { doubleQuote }: any) { - return doubleQuote ? `"${str.replace(/"/gu, '\\"')}"` : `'${str.replace(/'/gu, "\\'")}'`; + return doubleQuote ? `"${str.replace(/"/gu, '\\"')}"` : `'${str.replace(/'/gu, '\\\'')}'`; } export function valueToSource( @@ -96,12 +96,12 @@ export function valueToSource( const itemsStayOnTheSameLine = value.every( item => typeof item === 'object' && - item && - !(item instanceof Date) && - !(item instanceof Map) && - !(item instanceof RegExp) && - !(item instanceof Set) && - (Object.keys(item).length || value.length === 1), + item && + !(item instanceof Date) && + !(item instanceof Map) && + !(item instanceof RegExp) && + !(item instanceof Set) && + (Object.keys(item).length || value.length === 1), ); let previousIndex: number | null = null; diff --git a/packages/designer/src/plugin/plugin-context.ts b/packages/designer/src/plugin/plugin-context.ts index d9a47c451..88d1921b9 100644 --- a/packages/designer/src/plugin/plugin-context.ts +++ b/packages/designer/src/plugin/plugin-context.ts @@ -52,9 +52,9 @@ export default class PluginContext implements command: IPublicApiCommand; constructor( - options: IPluginContextOptions, - contextApiAssembler: ILowCodePluginContextApiAssembler, - ) { + options: IPluginContextOptions, + contextApiAssembler: ILowCodePluginContextApiAssembler, + ) { const { pluginName = 'anonymous', meta = {} } = options; contextApiAssembler.assembleApis(this, pluginName, meta); this.pluginEvent = createModuleEventBus(pluginName, 200); @@ -71,7 +71,7 @@ export default class PluginContext implements const getPreferenceValue = ( key: string, defaultValue?: IPublicTypePreferenceValueType, - ): IPublicTypePreferenceValueType | undefined => { + ): IPublicTypePreferenceValueType | undefined => { if (!isValidPreferenceKey(key, preferenceDeclaration)) { return undefined; } diff --git a/packages/designer/src/project/project.ts b/packages/designer/src/project/project.ts index 88978e467..b70587fd7 100644 --- a/packages/designer/src/project/project.ts +++ b/packages/designer/src/project/project.ts @@ -16,24 +16,24 @@ import { ISimulatorHost } from '../simulator'; export interface IProject extends Omit, - 'simulatorHost' | - 'importSchema' | - 'exportSchema' | - 'openDocument' | - 'getDocumentById' | - 'getCurrentDocument' | - 'addPropsTransducer' | - 'onRemoveDocument' | - 'onChangeDocument' | - 'onSimulatorHostReady' | - 'onSimulatorRendererReady' | - 'setI18n' | - 'setConfig' | - 'currentDocument' | - 'selection' | - 'documents' | - 'createDocument' | - 'getDocumentByFileName' +'simulatorHost' | +'importSchema' | +'exportSchema' | +'openDocument' | +'getDocumentById' | +'getCurrentDocument' | +'addPropsTransducer' | +'onRemoveDocument' | +'onChangeDocument' | +'onSimulatorHostReady' | +'onSimulatorRendererReady' | +'setI18n' | +'setConfig' | +'currentDocument' | +'selection' | +'documents' | +'createDocument' | +'getDocumentByFileName' > { get designer(): IDesigner; diff --git a/packages/designer/src/types/index.ts b/packages/designer/src/types/index.ts index 50fd82bcd..f47ce9ac8 100644 --- a/packages/designer/src/types/index.ts +++ b/packages/designer/src/types/index.ts @@ -17,4 +17,4 @@ export enum EDITOR_EVENT { NODE_VISIBLE_CHANGE = 'node.visible.change', } -export type Utils = typeof utils; \ No newline at end of file +export type Utils = typeof utils; diff --git a/packages/designer/src/utils/misc.ts b/packages/designer/src/utils/misc.ts index 3fab1c823..71c0fa470 100644 --- a/packages/designer/src/utils/misc.ts +++ b/packages/designer/src/utils/misc.ts @@ -34,7 +34,7 @@ export function normalizeTriggers(triggers: string[]) { /** * make a handler that listen all sensors:document, avoid frame lost */ - export function makeEventsHandler( +export function makeEventsHandler( boostEvent: MouseEvent | DragEvent, sensors: ISimulatorHost[], ): (fn: (sdoc: Document) => void) => void { @@ -53,4 +53,4 @@ export function normalizeTriggers(triggers: string[]) { return (handle: (sdoc: Document) => void) => { docs.forEach((doc) => handle(doc)); }; -} \ No newline at end of file +} diff --git a/packages/editor-core/__tests__/command.spec.ts b/packages/editor-core/__tests__/command.spec.ts new file mode 100644 index 000000000..e69de29bb diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index 55d6ff50b..3020b77e2 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -11,6 +11,10 @@ ".": { "import": "./dist/low-code-editor-core.js", "types": "./dist/index.d.ts" + }, + "./dist/": { + "import": "./dist/", + "require": "./dist/" } }, "sideEffects": [ diff --git a/packages/editor-core/src/di/setter.ts b/packages/editor-core/src/di/setter.ts index 37447bbd9..b33d39cc9 100644 --- a/packages/editor-core/src/di/setter.ts +++ b/packages/editor-core/src/di/setter.ts @@ -115,4 +115,4 @@ export class Setters implements ISetters { return createContent(setter, props); }; -} \ No newline at end of file +} diff --git a/packages/editor-core/src/editor.ts b/packages/editor-core/src/editor.ts index d1756868a..11949c856 100644 --- a/packages/editor-core/src/editor.ts +++ b/packages/editor-core/src/editor.ts @@ -202,9 +202,9 @@ export class Editor extends EventEmitter implements IEditor { Array.isArray(d) ? setArrayAssets(d, exportName, subName) : setAssetsComponent(d, { - exportName, - subName, - }); + exportName, + subName, + }); }); } if ((window as any)[exportName]) { diff --git a/packages/editor-core/src/event-bus.ts b/packages/editor-core/src/event-bus.ts index ae9d28905..0da18f877 100644 --- a/packages/editor-core/src/event-bus.ts +++ b/packages/editor-core/src/event-bus.ts @@ -106,4 +106,4 @@ export const createModuleEventBus = (moduleName: string, maxListeners?: number): emitter.setMaxListeners(maxListeners); } return new EventBus(emitter, moduleName); -}; \ No newline at end of file +}; diff --git a/packages/editor-core/src/hotkey.ts b/packages/editor-core/src/hotkey.ts index 08ac34188..b8235b558 100644 --- a/packages/editor-core/src/hotkey.ts +++ b/packages/editor-core/src/hotkey.ts @@ -75,7 +75,7 @@ const KEYCODE_MAP: KeyMap = { 219: '[', 220: '\\', 221: ']', - 222: "'", + 222: '\'', }; const SHIFT_MAP: CtrlKeyMap = { @@ -93,7 +93,7 @@ const SHIFT_MAP: CtrlKeyMap = { _: '-', '+': '=', ':': ';', - '"': "'", + '"': '\'', '<': ',', '>': '.', '?': '/', diff --git a/packages/editor-core/src/intl/global-locale.ts b/packages/editor-core/src/intl/global-locale.ts index fd67bb51f..a8b4f1861 100644 --- a/packages/editor-core/src/intl/global-locale.ts +++ b/packages/editor-core/src/intl/global-locale.ts @@ -61,7 +61,7 @@ class GlobalLocale { } if (!result) { // store 2: config from window - let localeFromConfig: string = getConfig('locale'); + const localeFromConfig: string = getConfig('locale'); if (localeFromConfig) { result = languageMap[localeFromConfig] || localeFromConfig.replace('_', '-'); logger.debug(`getting locale from config: ${result}`); @@ -147,6 +147,6 @@ function hasLocalStorage(obj: any): obj is WindowLocalStorage { return obj.localStorage; } -let globalLocale = new GlobalLocale(); +const globalLocale = new GlobalLocale(); export { globalLocale }; diff --git a/packages/editor-core/src/utils/control.ts b/packages/editor-core/src/utils/control.ts index 664ca938b..985bfc31b 100644 --- a/packages/editor-core/src/utils/control.ts +++ b/packages/editor-core/src/utils/control.ts @@ -27,4 +27,4 @@ export function wrapWithEventSwitch(fn: ListenerFunc): ListenerFunc { return (...args: any[]) => { if (isGlobalEventOn()) fn(...args); }; -} \ No newline at end of file +} diff --git a/packages/editor-core/src/utils/preference.ts b/packages/editor-core/src/utils/preference.ts index 6f17a8f63..240e9b199 100644 --- a/packages/editor-core/src/utils/preference.ts +++ b/packages/editor-core/src/utils/preference.ts @@ -52,4 +52,4 @@ export default class Preference implements IPublicModelPreference { return !(result === undefined || result === null); } -} \ No newline at end of file +} diff --git a/packages/editor-core/src/widgets/tip/help-tips.tsx b/packages/editor-core/src/widgets/tip/help-tips.tsx index ab5f65050..17fe07edf 100644 --- a/packages/editor-core/src/widgets/tip/help-tips.tsx +++ b/packages/editor-core/src/widgets/tip/help-tips.tsx @@ -37,4 +37,4 @@ export function HelpTip({ {help.content} ); -} \ No newline at end of file +} diff --git a/packages/editor-core/src/widgets/title/index.tsx b/packages/editor-core/src/widgets/title/index.tsx index 28fd3a99f..de19e6265 100644 --- a/packages/editor-core/src/widgets/title/index.tsx +++ b/packages/editor-core/src/widgets/title/index.tsx @@ -59,7 +59,7 @@ export class Title extends Component { } renderLabel = (label: string | IPublicTypeI18nData | ReactNode) => { - let { match, keywords } = this.props; + const { match, keywords } = this.props; if (!label) { return null; diff --git a/packages/editor-core/vitest.config.ts b/packages/editor-core/vitest.config.ts index e69de29bb..5b100d2a3 100644 --- a/packages/editor-core/vitest.config.ts +++ b/packages/editor-core/vitest.config.ts @@ -0,0 +1,5 @@ +import { defineProject } from 'vitest/config' + +export default defineProject({ + test: {} +}) diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index 83b2c0859..aecb60e2d 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -11,6 +11,10 @@ "import": "./dist/low-code-editor-skeleton.js", "require": "./dist/low-code-editor-skeleton.cjs", "types": "./dist/index.d.ts" + }, + "./dist/": { + "import": "./dist/", + "require": "./dist/" } }, "sideEffects": [ diff --git a/packages/editor-skeleton/src/components/settings/settings-pane.tsx b/packages/editor-skeleton/src/components/settings/settings-pane.tsx index a6f20899b..4e91d114d 100644 --- a/packages/editor-skeleton/src/components/settings/settings-pane.tsx +++ b/packages/editor-skeleton/src/components/settings/settings-pane.tsx @@ -139,8 +139,8 @@ class SettingFieldView extends Component) + setters?: (ReactNode | string)[]; + } & Record) | IPublicTypeDynamicProps = {}; let setterType: any; let initialValue: any = null; @@ -251,8 +251,8 @@ class SettingFieldView extends Component { - this.setState({ - fromOnChange: true, - // eslint-disable-next-line react/no-unused-state - value, - }); - field.setValue(value, true); - if (onChangeAPI) onChangeAPI(value, field.internalToShellField()); - }, - onInitial: () => { - if (initialValue == null) { - return; - } - const value = + this.setters?.createSetterContent(setterType, { + ...shallowIntl(setterProps), + forceInline: extraProps.forceInline, + key: field.id, + // === injection + prop: field.internalToShellField(), // for compatible vision + selected: field.top?.getNode()?.internalToShellNode(), + field: field.internalToShellField(), + // === IO + value, // reaction point + initialValue, + onChange: (value: any) => { + this.setState({ + fromOnChange: true, + // eslint-disable-next-line react/no-unused-state + value, + }); + field.setValue(value, true); + if (onChangeAPI) onChangeAPI(value, field.internalToShellField()); + }, + onInitial: () => { + if (initialValue == null) { + return; + } + const value = typeof initialValue === 'function' ? initialValue(field.internalToShellField()) : initialValue; - this.setState({ - // eslint-disable-next-line react/no-unused-state - value, - }); - field.setValue(value, true); - }, - - removeProp: () => { - if (field.name) { - field.parent.clearPropValue(field.name); - } - }, - }), + this.setState({ + // eslint-disable-next-line react/no-unused-state + value, + }); + field.setValue(value, true); + }, + + removeProp: () => { + if (field.name) { + field.parent.clearPropValue(field.name); + } + }, + }), extraProps.forceInline ? 'plain' : extraProps.display, ); } diff --git a/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx b/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx index 783df1034..c0a15a75b 100644 --- a/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx +++ b/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx @@ -104,29 +104,29 @@ export class SettingsPrimaryPane extends Component< l === 2 ? {} : { - onMouseOver: hoverNode.bind(null, _node, true), - onMouseOut: hoverNode.bind(null, _node, false), - onClick: () => { - if (!_node) { - return; - } - selectNode.call(null, _node); - const getName = (node: any) => { - const npm = node?.componentMeta?.npm; - return ( - [npm?.package, npm?.componentName].filter((item) => !!item).join('-') || - node?.componentMeta?.componentName || - '' - ); - }; - const selected = getName(current); - const target = getName(_node); - editor?.eventBus.emit('skeleton.settingsPane.Breadcrumb', { - selected, - target, - }); - }, - }; + onMouseOver: hoverNode.bind(null, _node, true), + onMouseOut: hoverNode.bind(null, _node, false), + onClick: () => { + if (!_node) { + return; + } + selectNode.call(null, _node); + const getName = (node: any) => { + const npm = node?.componentMeta?.npm; + return ( + [npm?.package, npm?.componentName].filter((item) => !!item).join('-') || + node?.componentMeta?.componentName || + '' + ); + }; + const selected = getName(current); + const target = getName(_node); + editor?.eventBus.emit('skeleton.settingsPane.Breadcrumb', { + selected, + target, + }); + }, + }; items.unshift( diff --git a/packages/editor-skeleton/src/components/settings/utils.ts b/packages/editor-skeleton/src/components/settings/utils.ts index ca1e4a6e8..80b3d449a 100644 --- a/packages/editor-skeleton/src/components/settings/utils.ts +++ b/packages/editor-skeleton/src/components/settings/utils.ts @@ -5,9 +5,9 @@ function getHotterFromSetter(setter: any) { function getTransducerFromSetter(setter: any) { return ( (setter && - (setter.transducer || - setter.Transducer || - (setter.type && (setter.type.transducer || setter.type.Transducer)))) || + (setter.transducer || + setter.Transducer || + (setter.type && (setter.type.transducer || setter.type.Transducer)))) || null ); // eslint-disable-line } diff --git a/packages/editor-skeleton/src/icons/arrow.tsx b/packages/editor-skeleton/src/icons/arrow.tsx index 520a99323..ab96e0894 100644 --- a/packages/editor-skeleton/src/icons/arrow.tsx +++ b/packages/editor-skeleton/src/icons/arrow.tsx @@ -8,4 +8,4 @@ export function IconArrow(props: IconProps) { </SVGIcon> ); } -IconArrow.displayName = 'Arrow'; \ No newline at end of file +IconArrow.displayName = 'Arrow'; diff --git a/packages/editor-skeleton/src/icons/exit.tsx b/packages/editor-skeleton/src/icons/exit.tsx index bdcc9e513..a0d2aa38b 100644 --- a/packages/editor-skeleton/src/icons/exit.tsx +++ b/packages/editor-skeleton/src/icons/exit.tsx @@ -8,4 +8,4 @@ export function IconExit(props: IconProps) { </SVGIcon> ); } -IconExit.displayName = 'Exit'; \ No newline at end of file +IconExit.displayName = 'Exit'; diff --git a/packages/editor-skeleton/src/layouts/index.ts b/packages/editor-skeleton/src/layouts/index.ts index b3c7a1058..16bcaef4d 100644 --- a/packages/editor-skeleton/src/layouts/index.ts +++ b/packages/editor-skeleton/src/layouts/index.ts @@ -4,4 +4,4 @@ export { default as LeftFixedPane } from './left-fixed-pane'; export { default as MainArea } from './main-area'; export { default as BottomArea } from './bottom-area'; export { default as TopArea } from './top-area'; -export { default as SubTopArea } from './sub-top-area'; \ No newline at end of file +export { default as SubTopArea } from './sub-top-area'; diff --git a/packages/editor-skeleton/src/layouts/sub-top-area.tsx b/packages/editor-skeleton/src/layouts/sub-top-area.tsx index 4b0ef1e35..59d1f3011 100644 --- a/packages/editor-skeleton/src/layouts/sub-top-area.tsx +++ b/packages/editor-skeleton/src/layouts/sub-top-area.tsx @@ -52,7 +52,7 @@ class Contents extends Component<{ area: Area; itemClassName?: string }> { right.push(content); } }); - let children = []; + const children = []; if (left && left.length) { children.push( <div className="lc-workspace-sub-top-area-left lc-sub-top-area-left">{left}</div>, diff --git a/packages/editor-skeleton/src/skeleton.ts b/packages/editor-skeleton/src/skeleton.ts index 072370789..a4745fccc 100644 --- a/packages/editor-skeleton/src/skeleton.ts +++ b/packages/editor-skeleton/src/skeleton.ts @@ -47,23 +47,23 @@ export enum SkeletonEvents { export interface ISkeleton extends Skeleton {} export class Skeleton implements Omit<IPublicApiSkeleton, -'showPanel' | -'hidePanel' | -'showWidget' | -'enableWidget' | -'hideWidget' | -'disableWidget' | -'showArea' | -'onShowPanel' | -'onHidePanel' | -'onShowWidget' | -'onHideWidget' | -'remove' | -'hideArea' | -'add' | -'getAreaItems' | -'onDisableWidget' | -'onEnableWidget' + 'showPanel' | + 'hidePanel' | + 'showWidget' | + 'enableWidget' | + 'hideWidget' | + 'disableWidget' | + 'showArea' | + 'onShowPanel' | + 'onHidePanel' | + 'onShowWidget' | + 'onHideWidget' | + 'remove' | + 'hideArea' | + 'add' | + 'getAreaItems' | + 'onDisableWidget' | + 'onEnableWidget' > { private panels = new Map<string, Panel>(); @@ -425,7 +425,10 @@ export class Skeleton implements Omit<IPublicApiSkeleton, return this.configTransducers; } - add(config: IPublicTypeSkeletonConfig, extraConfig?: Record<string, any>): IWidget | Widget | Panel | Stage | Dock | PanelDock | undefined { + add( + config: IPublicTypeSkeletonConfig, + extraConfig?: Record<string, any> + ): IWidget | Widget | Panel | Stage | Dock | PanelDock | undefined { const registeredTransducers = this.getRegisteredConfigTransducers(); const parsedConfig = registeredTransducers.reduce((prevConfig, current) => { diff --git a/packages/editor-skeleton/src/transducers/addon-combine.ts b/packages/editor-skeleton/src/transducers/addon-combine.ts index c2bc2dd4c..8a25a3324 100644 --- a/packages/editor-skeleton/src/transducers/addon-combine.ts +++ b/packages/editor-skeleton/src/transducers/addon-combine.ts @@ -221,23 +221,23 @@ export default function ( setValue(field: IPublicModelSettingField, eventData) { const { eventDataList, eventList } = eventData; Array.isArray(eventList) && - eventList.map((item) => { - field.parent.clearPropValue(item.name); - return item; - }); + eventList.map((item) => { + field.parent.clearPropValue(item.name); + return item; + }); Array.isArray(eventDataList) && - eventDataList.map((item) => { - field.parent.setPropValue(item.name, { - type: 'JSFunction', - // 需要传下入参 - value: `function(){return this.${ - item.relatedEventName - }.apply(this,Array.prototype.slice.call(arguments).concat([${ - item.paramStr ? item.paramStr : '' - }])) }`, - }); - return item; + eventDataList.map((item) => { + field.parent.setPropValue(item.name, { + type: 'JSFunction', + // 需要传下入参 + value: `function(){return this.${ + item.relatedEventName + }.apply(this,Array.prototype.slice.call(arguments).concat([${ + item.paramStr ? item.paramStr : '' + }])) }`, }); + return item; + }); }, }, ], diff --git a/packages/editor-skeleton/src/transducers/parse-func.ts b/packages/editor-skeleton/src/transducers/parse-func.ts index 741c0ce21..d908ecdfc 100644 --- a/packages/editor-skeleton/src/transducers/parse-func.ts +++ b/packages/editor-skeleton/src/transducers/parse-func.ts @@ -20,7 +20,7 @@ function transformStringToFunction(str: string) { if (leadingFnNameRe.test(str) && !leadingFnRe.test(str)) { str = `function ${str}`; } - let fnBody = ` + const fnBody = ` return function() { const self = this; try { diff --git a/packages/editor-skeleton/src/widget/index.ts b/packages/editor-skeleton/src/widget/index.ts index c6dd495f1..17d77d8c4 100644 --- a/packages/editor-skeleton/src/widget/index.ts +++ b/packages/editor-skeleton/src/widget/index.ts @@ -3,4 +3,4 @@ export * from './panel'; export * from './panel-dock'; export * from './dock'; export * from './widget'; -export * from './stage'; \ No newline at end of file +export * from './stage'; diff --git a/packages/engine/package.json b/packages/engine/package.json index e3237effb..473c914c5 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -11,6 +11,10 @@ "import": "./dist/ali-low-code-engine.js", "require": "./dist/ali-low-code-engine.cjs", "types": "./dist/index.d.ts" + }, + "./dist/": { + "import": "./dist/", + "require": "./dist/" } }, "files": [ diff --git a/packages/engine/src/engine-core.ts b/packages/engine/src/engine-core.ts index f5093c0ee..da74b628f 100644 --- a/packages/engine/src/engine-core.ts +++ b/packages/engine/src/engine-core.ts @@ -1,5 +1,6 @@ import { createElement } from 'react'; import { createRoot, type Root } from 'react-dom/client'; +import { isPlainObject } from '@alilc/lowcode-utils'; import { globalContext, Editor, @@ -28,16 +29,13 @@ import { PluginPreference, IDesigner, } from '@alilc/lowcode-designer'; -import { - Skeleton as InnerSkeleton, - registerDefaults, -} from '@alilc/lowcode-editor-skeleton'; +import { Skeleton as InnerSkeleton, registerDefaults } from '@alilc/lowcode-editor-skeleton'; + import { Workspace as InnerWorkspace, Workbench as WorkSpaceWorkbench, IWorkspace, } from './workspace'; - import { Hotkey, Project, @@ -54,10 +52,10 @@ import { CommonUI, Command, } from './shell'; -import { isPlainObject } from '@alilc/lowcode-utils'; import './modules/live-editing'; import * as classes from './modules/classes'; import symbols from './modules/symbols'; + import { componentMetaParser } from './inner-plugins/component-meta-parser'; import { setterRegistry } from './inner-plugins/setter-registry'; import { defaultPanelRegistry } from './inner-plugins/default-panel-registry'; @@ -66,13 +64,19 @@ import { builtinHotkey } from './inner-plugins/builtin-hotkey'; import { defaultContextMenu } from './inner-plugins/default-context-menu'; import { CommandPlugin } from '@alilc/lowcode-plugin-command'; import { OutlinePlugin } from '@alilc/lowcode-plugin-outline-pane'; -import { version } from '../package.json' +import { version } from '../package.json'; + +import '@alilc/lowcode-editor-skeleton/dist/style.css'; export * from './modules/skeleton-types'; export * from './modules/designer-types'; export * from './modules/lowcode-types'; -async function registryInnerPlugin(designer: IDesigner, editor: IEditor, plugins: IPublicApiPlugins): Promise<IPublicTypeDisposable> { +async function registryInnerPlugin( + designer: IDesigner, + editor: IEditor, + plugins: IPublicApiPlugins +): Promise<IPublicTypeDisposable> { // 注册一批内置插件 const componentMetaParserPlugin = componentMetaParser(designer); const defaultPanelRegistryPlugin = defaultPanelRegistry(editor); @@ -97,9 +101,13 @@ async function registryInnerPlugin(designer: IDesigner, editor: IEditor, plugins }; } -const innerWorkspace: IWorkspace = new InnerWorkspace(registryInnerPlugin, shellModelFactory); +const innerWorkspace: IWorkspace = new InnerWorkspace( + registryInnerPlugin, + shellModelFactory +); const workspace: IPublicApiWorkspace = new Workspace(innerWorkspace); const editor = new Editor(); + globalContext.register(editor, Editor); globalContext.register(editor, 'editor'); globalContext.register(innerWorkspace, 'workspace'); @@ -121,24 +129,30 @@ const skeleton = new Skeleton(innerSkeleton, 'any', false); const innerSetters = new InnerSetters(); const setters = new Setters(innerSetters); const innerCommand = new InnerCommand(); -const command = new Command(innerCommand, engineContext as IPublicModelPluginContext); - +const command = new Command( + innerCommand, + engineContext as IPublicModelPluginContext +); const material = new Material(editor); const commonUI = new CommonUI(editor); + editor.set('project', project); editor.set('setters' as any, setters); editor.set('material', material); editor.set('innerHotkey', innerHotkey); + const config = new Config(engineConfig); const event = new Event(commonEvent, { prefix: 'common' }); const logger = new Logger({ level: 'warn', bizName: 'common' }); const common = new Common(editor, innerSkeleton); const canvas = new Canvas(editor); -let plugins: Plugins; const pluginContextApiAssembler: ILowCodePluginContextApiAssembler = { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - assembleApis: (context: ILowCodePluginContextPrivate, pluginName: string, meta: IPublicTypePluginMeta) => { + assembleApis: ( + context: ILowCodePluginContextPrivate, + pluginName: string, + meta: IPublicTypePluginMeta + ) => { context.hotkey = hotkey; context.project = project; context.skeleton = new Skeleton(innerSkeleton, pluginName, false); @@ -154,9 +168,10 @@ const pluginContextApiAssembler: ILowCodePluginContextApiAssembler = { context.logger = new Logger({ level: 'warn', bizName: `plugin:${pluginName}` }); context.workspace = workspace; context.commonUI = commonUI; - context.command = new Command(innerCommand, context as IPublicModelPluginContext, { - commandScope, - }); + context.command = new Command( + innerCommand, context as IPublicModelPluginContext, { + commandScope, + }); context.registerLevel = IPublicEnumPluginRegisterLevel.Default; context.isPluginRegisteredInWorkspace = false; editor.set('pluginContext', context); @@ -164,7 +179,7 @@ const pluginContextApiAssembler: ILowCodePluginContextApiAssembler = { }; const innerPlugins = new LowCodePluginManager(pluginContextApiAssembler); -plugins = new Plugins(innerPlugins).toProxy(); +const plugins = new Plugins(innerPlugins).toProxy(); editor.set('innerPlugins' as any, innerPlugins); editor.set('plugins' as any, plugins); @@ -198,19 +213,25 @@ export { commonUI, command, }; + + // declare this is open-source version +/** + * @deprecated + */ export const isOpenSource = true; +engineConfig.set('isOpenSource', isOpenSource); + +engineConfig.set('ENGINE_VERSION', version); +export { version }; + +/** + * @deprecated + */ export const __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { symbols, classes, }; -engineConfig.set('isOpenSource', isOpenSource); - -// container which will host LowCodeEngine DOM -let engineContainer: HTMLElement; - -export { version } -engineConfig.set('ENGINE_VERSION', version); const pluginPromise = registryInnerPlugin(designer, editor, plugins); @@ -219,10 +240,14 @@ let root: Root | undefined; export async function init( container?: HTMLElement, options?: IPublicTypeEngineOptions, - pluginPreference?: PluginPreference, - ) { + pluginPreference?: PluginPreference +) { await destroy(); + + // container which will host LowCodeEngine DOM + let engineContainer: HTMLElement; let engineOptions = null; + if (isPlainObject(container)) { engineOptions = container; engineContainer = document.createElement('div'); @@ -237,6 +262,7 @@ export async function init( document.body.appendChild(engineContainer); } } + engineConfig.setEngineOptions(engineOptions as any); const { Workbench } = common.skeletonCabin; @@ -245,15 +271,15 @@ export async function init( disposeFun && disposeFun(); if (!root) { - root = createRoot( - engineContainer, + root = createRoot(engineContainer); + root.render( + createElement(WorkSpaceWorkbench, { + workspace: innerWorkspace, + // skeleton: workspace.skeleton, + className: 'engine-main', + topAreaItemClassName: 'engine-actionitem', + }) ); - root.render(createElement(WorkSpaceWorkbench, { - workspace: innerWorkspace, - // skeleton: workspace.skeleton, - className: 'engine-main', - topAreaItemClassName: 'engine-actionitem', - })) } innerWorkspace.enableAutoOpenFirstWindow = engineConfig.get('enableAutoOpenFirstWindow', true); @@ -267,12 +293,14 @@ export async function init( await plugins.init(pluginPreference as any); if (!root) { - root = createRoot(engineContainer) - root.render(createElement(Workbench, { - skeleton: innerSkeleton, - className: 'engine-main', - topAreaItemClassName: 'engine-actionitem', - })) + root = createRoot(engineContainer); + root.render( + createElement(Workbench, { + skeleton: innerSkeleton, + className: 'engine-main', + topAreaItemClassName: 'engine-actionitem', + }) + ); } } @@ -280,7 +308,9 @@ export async function destroy() { // remove all documents const { documents } = project; if (Array.isArray(documents) && documents.length > 0) { - documents.forEach(((doc: IPublicModelDocumentModel) => project.removeDocument(doc))); + documents.forEach( + (doc: IPublicModelDocumentModel) => project.removeDocument(doc) + ); } // TODO: delete plugins except for core plugins diff --git a/packages/engine/src/index.ts b/packages/engine/src/index.ts index fe57036eb..0c7ec397a 100644 --- a/packages/engine/src/index.ts +++ b/packages/engine/src/index.ts @@ -1,6 +1,7 @@ import { version } from './engine-core'; export * from './engine-core'; + console.log( `%c AliLowCodeEngine %c v${version} `, 'padding: 2px 1px; border-radius: 3px 0 0 3px; color: #fff; background: #606060; font-weight: bold;', diff --git a/packages/engine/src/inner-plugins/builtin-hotkey.ts b/packages/engine/src/inner-plugins/builtin-hotkey.ts index 8d15df74f..6d3291ce4 100644 --- a/packages/engine/src/inner-plugins/builtin-hotkey.ts +++ b/packages/engine/src/inner-plugins/builtin-hotkey.ts @@ -328,7 +328,7 @@ export const builtinHotkey = (ctx: IPublicModelPluginContext) => { if (!target) { return; } - let canAddComponentsTree = componentsTree.filter((node: IPublicModelNode) => { + const canAddComponentsTree = componentsTree.filter((node: IPublicModelNode) => { const dragNodeObject: IPublicTypeDragNodeObject = { type: IPublicEnumDragObjectType.Node, nodes: [node], diff --git a/packages/engine/src/inner-plugins/default-context-menu.ts b/packages/engine/src/inner-plugins/default-context-menu.ts index 81978d920..c9d5c845b 100644 --- a/packages/engine/src/inner-plugins/default-context-menu.ts +++ b/packages/engine/src/inner-plugins/default-context-menu.ts @@ -129,7 +129,7 @@ export const defaultContextMenu = (ctx: IPublicModelPluginContext) => { return; } if (parent) { - let canAddNodes = nodeSchema.filter((nodeSchema: IPublicTypeNodeSchema) => { + const canAddNodes = nodeSchema.filter((nodeSchema: IPublicTypeNodeSchema) => { const dragNodeObject: IPublicTypeDragNodeDataObject = { type: IPublicEnumDragObjectType.NodeData, data: nodeSchema, @@ -177,7 +177,7 @@ export const defaultContextMenu = (ctx: IPublicModelPluginContext) => { if (nodeSchema.length === 0) { return; } - let canAddNodes = nodeSchema.filter((nodeSchema: IPublicTypeNodeSchema) => { + const canAddNodes = nodeSchema.filter((nodeSchema: IPublicTypeNodeSchema) => { const dragNodeObject: IPublicTypeDragNodeDataObject = { type: IPublicEnumDragObjectType.NodeData, data: nodeSchema, diff --git a/packages/engine/src/inner-plugins/setter-registry.ts b/packages/engine/src/inner-plugins/setter-registry.ts index a9515b39f..cf3998222 100644 --- a/packages/engine/src/inner-plugins/setter-registry.ts +++ b/packages/engine/src/inner-plugins/setter-registry.ts @@ -6,11 +6,13 @@ export const setterRegistry = (ctx: IPublicModelPluginContext) => { init() { const { config } = ctx; if (config.get('disableDefaultSetters')) return; - // todo: 互相依赖 + // const builtinSetters = require('@alilc/lowcode-engine-ext')?.setters; - // if (builtinSetters) { - // ctx.setters.registerSetter(builtinSetters); - // } + // @ts-expect-error: todo remove + const builtinSetters = window.AliLowCodeEngineExt?.setters; + if (builtinSetters) { + ctx.setters.registerSetter(builtinSetters); + } }, }; }; diff --git a/packages/engine/src/module.d.ts b/packages/engine/src/module.d.ts index 74f3fbd94..ebf77e1a4 100644 --- a/packages/engine/src/module.d.ts +++ b/packages/engine/src/module.d.ts @@ -1 +1 @@ -declare module 'ric-shim'; \ No newline at end of file +declare module 'ric-shim'; diff --git a/packages/engine/src/modules/classes.ts b/packages/engine/src/modules/classes.ts index 66586febd..1a63b8da7 100644 --- a/packages/engine/src/modules/classes.ts +++ b/packages/engine/src/modules/classes.ts @@ -13,4 +13,3 @@ export { SkeletonItem, } from '../shell'; export { Node as InnerNode } from '@alilc/lowcode-designer'; - diff --git a/packages/engine/src/modules/designer-types.ts b/packages/engine/src/modules/designer-types.ts index e410d1b97..1d9a1a08b 100644 --- a/packages/engine/src/modules/designer-types.ts +++ b/packages/engine/src/modules/designer-types.ts @@ -8,4 +8,4 @@ export type SaveHandler = designerCabin.SaveHandler; export type ComponentMeta = designerCabin.ComponentMeta; export type SettingField = designerCabin.SettingField; export type ILowCodePluginManager = designerCabin.ILowCodePluginManager; -export type PluginPreference = designerCabin.PluginPreference; \ No newline at end of file +export type PluginPreference = designerCabin.PluginPreference; diff --git a/packages/engine/src/modules/lowcode-types.ts b/packages/engine/src/modules/lowcode-types.ts index 50618bd31..c6a6bb4ec 100644 --- a/packages/engine/src/modules/lowcode-types.ts +++ b/packages/engine/src/modules/lowcode-types.ts @@ -1 +1 @@ -export type { IPublicTypeNodeSchema } from '@alilc/lowcode-types'; \ No newline at end of file +export type { IPublicTypeNodeSchema } from '@alilc/lowcode-types'; diff --git a/packages/engine/src/modules/shell-model-factory.ts b/packages/engine/src/modules/shell-model-factory.ts index 4af8cd42e..bd5dccd6d 100644 --- a/packages/engine/src/modules/shell-model-factory.ts +++ b/packages/engine/src/modules/shell-model-factory.ts @@ -18,4 +18,4 @@ class ShellModelFactory implements IShellModelFactory { } } -export const shellModelFactory = new ShellModelFactory(); \ No newline at end of file +export const shellModelFactory = new ShellModelFactory(); diff --git a/packages/engine/src/shell/api/common.tsx b/packages/engine/src/shell/api/common.tsx index 6534968f2..729ef0a63 100644 --- a/packages/engine/src/shell/api/common.tsx +++ b/packages/engine/src/shell/api/common.tsx @@ -465,4 +465,4 @@ export class Common implements IPublicApiCommon { TransformStage: InnerTransitionStage, }; } -} \ No newline at end of file +} diff --git a/packages/engine/src/shell/api/hotkey.ts b/packages/engine/src/shell/api/hotkey.ts index 78a782994..121eb335c 100644 --- a/packages/engine/src/shell/api/hotkey.ts +++ b/packages/engine/src/shell/api/hotkey.ts @@ -26,13 +26,6 @@ export class Hotkey implements IPublicApiHotkey { return this[hotkeySymbol].callBacks; } - /** - * @deprecated - */ - get callBacks() { - return this.callbacks; - } - /** * 绑定快捷键 * @param combos 快捷键,格式如:['command + s'] 、['ctrl + shift + s'] 等 @@ -41,10 +34,10 @@ export class Hotkey implements IPublicApiHotkey { * @returns */ bind( - combos: string[] | string, - callback: IPublicTypeHotkeyCallback, - action?: string, - ): IPublicTypeDisposable { + combos: string[] | string, + callback: IPublicTypeHotkeyCallback, + action?: string, + ): IPublicTypeDisposable { this[hotkeySymbol].bind(combos, callback, action); return () => { this[hotkeySymbol].unbind(combos, callback, action); @@ -58,4 +51,4 @@ export class Hotkey implements IPublicApiHotkey { mount(window: Window) { return this[hotkeySymbol].mount(window); } -} \ No newline at end of file +} diff --git a/packages/engine/src/shell/api/logger.ts b/packages/engine/src/shell/api/logger.ts index 54fee7a66..1aa67d472 100644 --- a/packages/engine/src/shell/api/logger.ts +++ b/packages/engine/src/shell/api/logger.ts @@ -45,4 +45,4 @@ export class Logger implements IPublicApiLogger { log(...args: any | any[]): void { this[innerLoggerSymbol].log(...args); } -} \ No newline at end of file +} diff --git a/packages/engine/src/shell/api/material.ts b/packages/engine/src/shell/api/material.ts index cfb71f262..3fd5ed14e 100644 --- a/packages/engine/src/shell/api/material.ts +++ b/packages/engine/src/shell/api/material.ts @@ -141,7 +141,7 @@ export class Material implements IPublicApiMaterial { getComponentMetasMap(): Map<string, IPublicModelComponentMeta> { const map = new Map<string, IPublicModelComponentMeta>(); const originalMap = this[designerSymbol].getComponentMetasMap(); - for (let componentName of originalMap.keys()) { + for (const componentName of originalMap.keys()) { map.set(componentName, this.getComponentMeta(componentName)!); } return map; diff --git a/packages/engine/src/shell/api/plugins.ts b/packages/engine/src/shell/api/plugins.ts index b6f5e6371..b596acac6 100644 --- a/packages/engine/src/shell/api/plugins.ts +++ b/packages/engine/src/shell/api/plugins.ts @@ -44,8 +44,8 @@ export class Plugins implements IPublicApiPlugins { } getPluginPreference( - pluginName: string, - ): Record<string, IPublicTypePreferenceValueType> | null | undefined { + pluginName: string, + ): Record<string, IPublicTypePreferenceValueType> | null | undefined { return this[pluginsSymbol].getPluginPreference(pluginName); } diff --git a/packages/engine/src/shell/api/project.ts b/packages/engine/src/shell/api/project.ts index bd9f4a1a1..035508b0d 100644 --- a/packages/engine/src/shell/api/project.ts +++ b/packages/engine/src/shell/api/project.ts @@ -164,9 +164,9 @@ export class Project implements IPublicApiProject { * @param stage */ addPropsTransducer( - transducer: IPublicTypePropsTransducer, - stage: IPublicEnumTransformStage, - ): void { + transducer: IPublicTypePropsTransducer, + stage: IPublicEnumTransformStage, + ): void { this[projectSymbol].designer.addPropsReducer(transducer, stage); } @@ -177,9 +177,9 @@ export class Project implements IPublicApiProject { */ onRemoveDocument(fn: (data: { id: string}) => void): IPublicTypeDisposable { return this[editorSymbol].eventBus.on( - 'designer.document.remove', - (data: { id: string }) => fn(data), - ); + 'designer.document.remove', + (data: { id: string }) => fn(data), + ); } /** diff --git a/packages/engine/src/shell/api/skeleton.ts b/packages/engine/src/shell/api/skeleton.ts index c61edf95d..4d032f0ee 100644 --- a/packages/engine/src/shell/api/skeleton.ts +++ b/packages/engine/src/shell/api/skeleton.ts @@ -33,10 +33,10 @@ export class Skeleton implements IPublicApiSkeleton { } constructor( - skeleton: ISkeleton, - pluginName: string, - readonly workspaceMode: boolean = false, - ) { + skeleton: ISkeleton, + pluginName: string, + readonly workspaceMode: boolean = false, + ) { this[innerSkeletonSymbol] = skeleton; this.pluginName = pluginName; } diff --git a/packages/engine/src/shell/components/context-menu.tsx b/packages/engine/src/shell/components/context-menu.tsx index 8c7ab446b..6ae0c198d 100644 --- a/packages/engine/src/shell/components/context-menu.tsx +++ b/packages/engine/src/shell/components/context-menu.tsx @@ -69,4 +69,4 @@ ContextMenu.create = (pluginContext: IPublicModelPluginContext, menus: IPublicTy return createContextMenu(children, { event, }); -}; \ No newline at end of file +}; diff --git a/packages/engine/src/shell/model/active-tracker.ts b/packages/engine/src/shell/model/active-tracker.ts index bd7453bd8..9d9fd10d2 100644 --- a/packages/engine/src/shell/model/active-tracker.ts +++ b/packages/engine/src/shell/model/active-tracker.ts @@ -47,4 +47,4 @@ export class ActiveTracker implements IPublicModelActiveTracker { track(node: IPublicModelNode) { this[activeTrackerSymbol].track((node as any)[nodeSymbol]); } -} \ No newline at end of file +} diff --git a/packages/engine/src/shell/model/clipboard.ts b/packages/engine/src/shell/model/clipboard.ts index 9c4b30945..e7ab18e10 100644 --- a/packages/engine/src/shell/model/clipboard.ts +++ b/packages/engine/src/shell/model/clipboard.ts @@ -14,9 +14,9 @@ export class Clipboard implements IPublicModelClipboard { } waitPasteData( - keyboardEvent: KeyboardEvent, - cb: (data: any, clipboardEvent: ClipboardEvent) => void, - ): void { + keyboardEvent: KeyboardEvent, + cb: (data: any, clipboardEvent: ClipboardEvent) => void, + ): void { this[clipboardSymbol].waitPasteData(keyboardEvent, cb); } -} \ No newline at end of file +} diff --git a/packages/engine/src/shell/model/component-meta.ts b/packages/engine/src/shell/model/component-meta.ts index 448f0584e..8a920079d 100644 --- a/packages/engine/src/shell/model/component-meta.ts +++ b/packages/engine/src/shell/model/component-meta.ts @@ -130,14 +130,14 @@ export class ComponentMeta implements IPublicModelComponentMeta { * @returns */ checkNestingDown( - my: IPublicModelNode | IPublicTypeNodeData, - target: IPublicTypeNodeSchema | IPublicModelNode | IPublicTypeNodeSchema[], - ) { + my: IPublicModelNode | IPublicTypeNodeData, + target: IPublicTypeNodeSchema | IPublicModelNode | IPublicTypeNodeSchema[], + ) { const curNode = (my as any)?.isNode ? (my as any)[nodeSymbol] : my; return this[componentMetaSymbol].checkNestingDown( - curNode as any, - (target as any)[nodeSymbol] || target, - ); + curNode as any, + (target as any)[nodeSymbol] || target, + ); } refreshMetadata(): void { diff --git a/packages/engine/src/shell/model/detecting.ts b/packages/engine/src/shell/model/detecting.ts index 7ce0fe1e5..188043a71 100644 --- a/packages/engine/src/shell/model/detecting.ts +++ b/packages/engine/src/shell/model/detecting.ts @@ -60,4 +60,4 @@ export class Detecting implements IPublicModelDetecting { }; return this[detectingSymbol].onDetectingChange(innerFn); } -} \ No newline at end of file +} diff --git a/packages/engine/src/shell/model/document-model.ts b/packages/engine/src/shell/model/document-model.ts index 20795aea8..abfe325b9 100644 --- a/packages/engine/src/shell/model/document-model.ts +++ b/packages/engine/src/shell/model/document-model.ts @@ -111,8 +111,8 @@ export class DocumentModel implements IPublicModelDocumentModel { this._focusNode = node; this[editorSymbol].eventBus.emit( 'shell.document.focusNodeChanged', - { document: this, focusNode: node }, - ); + { document: this, focusNode: node }, + ); } /** @@ -121,7 +121,7 @@ export class DocumentModel implements IPublicModelDocumentModel { */ get nodesMap(): Map<string, IPublicModelNode> { const map = new Map<string, IPublicModelNode>(); - for (let id of this[documentSymbol].nodesMap.keys()) { + for (const id of this[documentSymbol].nodesMap.keys()) { map.set(id, this.getNodeById(id)!); } return map; @@ -227,14 +227,14 @@ export class DocumentModel implements IPublicModelDocumentModel { * @returns boolean 是否可以放置 */ checkNesting( - dropTarget: IPublicModelNode, - dragObject: IPublicTypeDragNodeObject | IPublicTypeDragNodeDataObject, - ): boolean { - let innerDragObject = dragObject; + dropTarget: IPublicModelNode, + dragObject: IPublicTypeDragNodeObject | IPublicTypeDragNodeDataObject, + ): boolean { + const innerDragObject = dragObject; if (isDragNodeObject(dragObject)) { innerDragObject.nodes = innerDragObject.nodes?.map( - (node: IPublicModelNode) => ((node as any)[nodeSymbol] || node), - ); + (node: IPublicModelNode) => ((node as any)[nodeSymbol] || node), + ); } return this[documentSymbol].checkNesting( ((dropTarget as any)[nodeSymbol] || dropTarget) as any, diff --git a/packages/engine/src/shell/model/drag-object.ts b/packages/engine/src/shell/model/drag-object.ts index 064680fde..38e756442 100644 --- a/packages/engine/src/shell/model/drag-object.ts +++ b/packages/engine/src/shell/model/drag-object.ts @@ -31,4 +31,4 @@ export class DragObject implements IPublicModelDragObject { get data(): IPublicTypeNodeSchema | IPublicTypeNodeSchema[] { return (this[dragObjectSymbol] as IPublicTypeDragNodeDataObject).data; } -} \ No newline at end of file +} diff --git a/packages/engine/src/shell/model/dragon.ts b/packages/engine/src/shell/model/dragon.ts index ca6d8267f..797c3dea1 100644 --- a/packages/engine/src/shell/model/dragon.ts +++ b/packages/engine/src/shell/model/dragon.ts @@ -41,9 +41,9 @@ export class Dragon implements IPublicModelDragon { } static create( - dragon: IDragon | null, - workspaceMode: boolean, - ): IPublicModelDragon | null { + dragon: IDragon | null, + workspaceMode: boolean, + ): IPublicModelDragon | null { if (!dragon) { return null; } diff --git a/packages/engine/src/shell/model/locate-event.ts b/packages/engine/src/shell/model/locate-event.ts index 20451f946..94165a417 100644 --- a/packages/engine/src/shell/model/locate-event.ts +++ b/packages/engine/src/shell/model/locate-event.ts @@ -48,4 +48,4 @@ export default class LocateEvent implements IPublicModelLocateEvent { get dragObject(): IPublicModelDragObject | null { return DragObject.create(this[locateEventSymbol].dragObject); } -} \ No newline at end of file +} diff --git a/packages/engine/src/shell/model/modal-nodes-manager.ts b/packages/engine/src/shell/model/modal-nodes-manager.ts index b1e27596f..ab0035964 100644 --- a/packages/engine/src/shell/model/modal-nodes-manager.ts +++ b/packages/engine/src/shell/model/modal-nodes-manager.ts @@ -70,7 +70,7 @@ export class ModalNodesManager implements IPublicModelModalNodesManager { * 设置指定节点为不可见态 * @param node Node */ - setInvisible(node: IPublicModelNode): void { + setInvisible(node: IPublicModelNode): void { this[modalNodesManagerSymbol].setInvisible((node as any)[nodeSymbol]); } -} \ No newline at end of file +} diff --git a/packages/engine/src/shell/model/node.ts b/packages/engine/src/shell/model/node.ts index 29d24232e..e38c1a51e 100644 --- a/packages/engine/src/shell/model/node.ts +++ b/packages/engine/src/shell/model/node.ts @@ -518,9 +518,9 @@ export class Node implements IPublicModelNode { * @returns */ exportSchema( - stage: IPublicEnumTransformStage = IPublicEnumTransformStage.Render, - options?: any, - ): IPublicTypeNodeSchema { + stage: IPublicEnumTransformStage = IPublicEnumTransformStage.Render, + options?: any, + ): IPublicTypeNodeSchema { return this[nodeSymbol].export(stage, options); } @@ -531,15 +531,15 @@ export class Node implements IPublicModelNode { * @param useMutator */ insertBefore( - node: IPublicModelNode, - ref?: IPublicModelNode | undefined, - useMutator?: boolean, - ): void { + node: IPublicModelNode, + ref?: IPublicModelNode | undefined, + useMutator?: boolean, + ): void { this[nodeSymbol].insertBefore( - (node as any)[nodeSymbol] || node, - (ref as any)?.[nodeSymbol], - useMutator, - ); + (node as any)[nodeSymbol] || node, + (ref as any)?.[nodeSymbol], + useMutator, + ); } /** @@ -549,15 +549,15 @@ export class Node implements IPublicModelNode { * @param useMutator */ insertAfter( - node: IPublicModelNode, - ref?: IPublicModelNode | undefined, - useMutator?: boolean, - ): void { + node: IPublicModelNode, + ref?: IPublicModelNode | undefined, + useMutator?: boolean, + ): void { this[nodeSymbol].insertAfter( - (node as any)[nodeSymbol] || node, - (ref as any)?.[nodeSymbol], - useMutator, - ); + (node as any)[nodeSymbol] || node, + (ref as any)?.[nodeSymbol], + useMutator, + ); } /** diff --git a/packages/engine/src/shell/model/prop.ts b/packages/engine/src/shell/model/prop.ts index 8d4ca7842..15948298b 100644 --- a/packages/engine/src/shell/model/prop.ts +++ b/packages/engine/src/shell/model/prop.ts @@ -91,4 +91,4 @@ export class Prop implements IPublicModelProp { exportSchema(stage: IPublicEnumTransformStage = IPublicEnumTransformStage.Render) { return this[propSymbol].export(stage); } -} \ No newline at end of file +} diff --git a/packages/engine/src/shell/model/props.ts b/packages/engine/src/shell/model/props.ts index 86a9a2142..c658f0212 100644 --- a/packages/engine/src/shell/model/props.ts +++ b/packages/engine/src/shell/model/props.ts @@ -115,4 +115,4 @@ export class Props implements IPublicModelProps { add(value: IPublicTypeCompositeValue, key?: string | number | undefined): any { return this[propsSymbol].add(value, key); } -} \ No newline at end of file +} diff --git a/packages/engine/src/shell/model/resource.ts b/packages/engine/src/shell/model/resource.ts index 9b5491ac6..7061370ba 100644 --- a/packages/engine/src/shell/model/resource.ts +++ b/packages/engine/src/shell/model/resource.ts @@ -52,4 +52,4 @@ export class Resource implements IPublicModelResource { get viewName() { return this[resourceSymbol].viewName; } -} \ No newline at end of file +} diff --git a/packages/engine/src/shell/model/setting-top-entry.ts b/packages/engine/src/shell/model/setting-top-entry.ts index 8afed43a5..de67e89e5 100644 --- a/packages/engine/src/shell/model/setting-top-entry.ts +++ b/packages/engine/src/shell/model/setting-top-entry.ts @@ -59,4 +59,4 @@ export class SettingTopEntry implements IPublicModelSettingTopEntry { clearPropValue(propName: string | number) { this[settingTopEntrySymbol].clearPropValue(propName); } -} \ No newline at end of file +} diff --git a/packages/engine/src/shell/model/simulator-render.ts b/packages/engine/src/shell/model/simulator-render.ts index f6ae47996..0313d68ca 100644 --- a/packages/engine/src/shell/model/simulator-render.ts +++ b/packages/engine/src/shell/model/simulator-render.ts @@ -20,4 +20,4 @@ export class SimulatorRender implements IPublicModelSimulatorRender { rerender() { return this[simulatorRenderSymbol].rerender(); } -} \ No newline at end of file +} diff --git a/packages/engine/src/shell/model/skeleton-item.ts b/packages/engine/src/shell/model/skeleton-item.ts index 7f1224c0d..90757a3e0 100644 --- a/packages/engine/src/shell/model/skeleton-item.ts +++ b/packages/engine/src/shell/model/skeleton-item.ts @@ -36,4 +36,4 @@ export class SkeletonItem implements IPublicModelSkeletonItem { toggle() { this[skeletonItemSymbol].toggle(); } -} \ No newline at end of file +} diff --git a/packages/engine/src/shell/symbols.ts b/packages/engine/src/shell/symbols.ts index e0f846ad3..5e5264e68 100644 --- a/packages/engine/src/shell/symbols.ts +++ b/packages/engine/src/shell/symbols.ts @@ -40,4 +40,4 @@ export const conditionGroupSymbol = Symbol('conditionGroup'); export const editorViewSymbol = Symbol('editorView'); export const pluginContextSymbol = Symbol('pluginContext'); export const skeletonItemSymbol = Symbol('skeletonItem'); -export const commandSymbol = Symbol('command'); \ No newline at end of file +export const commandSymbol = Symbol('command'); diff --git a/packages/engine/src/workspace/context/base-context.ts b/packages/engine/src/workspace/context/base-context.ts index 78d47c88b..78bbb8bfb 100644 --- a/packages/engine/src/workspace/context/base-context.ts +++ b/packages/engine/src/workspace/context/base-context.ts @@ -56,7 +56,7 @@ import { IEditorWindow } from '../window'; export interface IBasicContext extends BasicContext {} export class BasicContext - implements +implements Omit< IPublicModelPluginContext, 'workspace' | 'commonUI' | 'command' | 'isPluginRegisteredInWorkspace' | 'editorWindow' diff --git a/packages/engine/src/workspace/layouts/workbench.tsx b/packages/engine/src/workspace/layouts/workbench.tsx index 2913576e1..69583b524 100644 --- a/packages/engine/src/workspace/layouts/workbench.tsx +++ b/packages/engine/src/workspace/layouts/workbench.tsx @@ -15,9 +15,9 @@ export class Workbench extends Component<{ className?: string; topAreaItemClassName?: string; }, { - workspaceEmptyComponent: any; - theme?: string; -}> { + workspaceEmptyComponent: any; + theme?: string; + }> { constructor(props: any) { super(props); const { config, components, workspace } = this.props; diff --git a/packages/engine/src/workspace/resource-type.ts b/packages/engine/src/workspace/resource-type.ts index 2ab7b9942..bb3a533be 100644 --- a/packages/engine/src/workspace/resource-type.ts +++ b/packages/engine/src/workspace/resource-type.ts @@ -13,4 +13,4 @@ export class ResourceType implements Omit<IPublicTypeResourceType, 'resourceName get type() { return this.resourceTypeModel.resourceType; } -} \ No newline at end of file +} diff --git a/packages/engine/src/workspace/resource.ts b/packages/engine/src/workspace/resource.ts index d65cf0874..7f166e08b 100644 --- a/packages/engine/src/workspace/resource.ts +++ b/packages/engine/src/workspace/resource.ts @@ -106,4 +106,4 @@ export class Resource implements IBaseModelResource<IResource> { getEditorView(name: string) { return this.editorViewMap.get(name); } -} \ No newline at end of file +} diff --git a/packages/engine/src/workspace/view/resource-view.tsx b/packages/engine/src/workspace/view/resource-view.tsx index e2204dd50..07c666a5c 100644 --- a/packages/engine/src/workspace/view/resource-view.tsx +++ b/packages/engine/src/workspace/view/resource-view.tsx @@ -33,4 +33,4 @@ export class ResourceView extends PureComponent<{ </div> ); } -} \ No newline at end of file +} diff --git a/packages/engine/src/workspace/view/window-view.tsx b/packages/engine/src/workspace/view/window-view.tsx index e66082910..69c98634f 100644 --- a/packages/engine/src/workspace/view/window-view.tsx +++ b/packages/engine/src/workspace/view/window-view.tsx @@ -36,4 +36,4 @@ export class WindowView extends PureComponent<{ </div> ); } -} \ No newline at end of file +} diff --git a/packages/engine/src/workspace/window.ts b/packages/engine/src/workspace/window.ts index 340c902f4..c0821035e 100644 --- a/packages/engine/src/workspace/window.ts +++ b/packages/engine/src/workspace/window.ts @@ -234,4 +234,4 @@ export class EditorWindow implements Omit<IPublicModelWindow<IResource>, 'change get innerPlugins() { return this.editorView?.innerPlugins; } -} \ No newline at end of file +} diff --git a/packages/engine/src/workspace/workspace.ts b/packages/engine/src/workspace/workspace.ts index d7b5a1ea5..6743ec3a7 100644 --- a/packages/engine/src/workspace/workspace.ts +++ b/packages/engine/src/workspace/workspace.ts @@ -333,4 +333,4 @@ export class Workspace implements Omit<IPublicApiWorkspace< } } -export interface IWorkspace extends Workspace {} \ No newline at end of file +export interface IWorkspace extends Workspace {} diff --git a/packages/engine/vitest.config.ts b/packages/engine/vitest.config.ts index 73d181d02..5b100d2a3 100644 --- a/packages/engine/vitest.config.ts +++ b/packages/engine/vitest.config.ts @@ -1,8 +1,5 @@ -import { defineConfig } from 'vitest/config' +import { defineProject } from 'vitest/config' -export default defineConfig({ - test: { - include: ['tests/*.spec.ts'], - environment: 'jsdom' - } +export default defineProject({ + test: {} }) diff --git a/packages/plugin-command/src/index.ts b/packages/plugin-command/src/index.ts index fa6f32b32..0264342a6 100644 --- a/packages/plugin-command/src/index.ts +++ b/packages/plugin-command/src/index.ts @@ -22,4 +22,4 @@ CommandPlugin.meta = { commandScope: 'common', }; -export default CommandPlugin; \ No newline at end of file +export default CommandPlugin; diff --git a/packages/plugin-outline-pane/src/controllers/pane-controller.ts b/packages/plugin-outline-pane/src/controllers/pane-controller.ts index 05823bbc8..9d135e23d 100644 --- a/packages/plugin-outline-pane/src/controllers/pane-controller.ts +++ b/packages/plugin-outline-pane/src/controllers/pane-controller.ts @@ -195,7 +195,7 @@ export class PaneController implements IPublicModelSensor, ITreeBoard, IPublicTy if ( originLoc && ((pos && pos === 'unchanged') || - (irect && globalY >= irect.top && globalY <= irect.bottom)) && + (irect && globalY >= irect.top && globalY <= irect.bottom)) && dragObject ) { const loc = originLoc.clone(e); diff --git a/packages/plugin-outline-pane/src/controllers/tree-master.ts b/packages/plugin-outline-pane/src/controllers/tree-master.ts index f86ce3dec..c988501a7 100644 --- a/packages/plugin-outline-pane/src/controllers/tree-master.ts +++ b/packages/plugin-outline-pane/src/controllers/tree-master.ts @@ -66,7 +66,7 @@ export class TreeMaster { 'en-US': enUS, 'zh-CN': zhCN, }); - let _pluginContext: IOutlinePanelPluginContext = Object.assign(pluginContext, { + const _pluginContext: IOutlinePanelPluginContext = Object.assign(pluginContext, { intl, intlNode, getLocale, diff --git a/packages/plugin-outline-pane/src/helper/consts.ts b/packages/plugin-outline-pane/src/helper/consts.ts index aa6395d20..38725d79b 100644 --- a/packages/plugin-outline-pane/src/helper/consts.ts +++ b/packages/plugin-outline-pane/src/helper/consts.ts @@ -1,2 +1,2 @@ export const BackupPaneName = 'outline-backup-pane'; -export const MasterPaneName = 'outline-master-pane'; \ No newline at end of file +export const MasterPaneName = 'outline-master-pane'; diff --git a/packages/plugin-outline-pane/src/ric-shim.d.ts b/packages/plugin-outline-pane/src/ric-shim.d.ts index 74f3fbd94..ebf77e1a4 100644 --- a/packages/plugin-outline-pane/src/ric-shim.d.ts +++ b/packages/plugin-outline-pane/src/ric-shim.d.ts @@ -1 +1 @@ -declare module 'ric-shim'; \ No newline at end of file +declare module 'ric-shim'; diff --git a/packages/plugin-outline-pane/src/views/pane.tsx b/packages/plugin-outline-pane/src/views/pane.tsx index 4b807ca18..66f842819 100644 --- a/packages/plugin-outline-pane/src/views/pane.tsx +++ b/packages/plugin-outline-pane/src/views/pane.tsx @@ -13,8 +13,8 @@ export class Pane extends PureComponent<{ controller: PaneController; hideFilter?: boolean; }, { - tree: Tree | null; -}> { + tree: Tree | null; + }> { private controller; private simulatorRendererReadyDispose: IPublicTypeDisposable; diff --git a/packages/plugin-outline-pane/src/views/tree-branches.tsx b/packages/plugin-outline-pane/src/views/tree-branches.tsx index 41bd69481..c0d3597e7 100644 --- a/packages/plugin-outline-pane/src/views/tree-branches.tsx +++ b/packages/plugin-outline-pane/src/views/tree-branches.tsx @@ -69,10 +69,10 @@ interface ITreeNodeChildrenState { dropDetail: IPublicTypeLocationChildrenDetail | undefined | null; } class TreeNodeChildren extends PureComponent<{ - treeNode: TreeNode; - isModal?: boolean; - treeChildren: TreeNode[] | null; - }, ITreeNodeChildrenState> { + treeNode: TreeNode; + isModal?: boolean; + treeChildren: TreeNode[] | null; +}, ITreeNodeChildrenState> { state: ITreeNodeChildrenState = { filterWorking: false, matchSelf: false, @@ -96,7 +96,7 @@ class TreeNodeChildren extends PureComponent<{ filterWorking: newFilterWorking, matchSelf: newMatchChild, keywords: newKeywords, - } = treeNode.filterReult; + } = treeNode.filterReult; this.setState({ filterWorking: newFilterWorking, matchSelf: newMatchChild, @@ -104,10 +104,10 @@ class TreeNodeChildren extends PureComponent<{ }); }); this.offLocationChanged = project.currentDocument?.onDropLocationChanged( - () => { - this.setState({ dropDetail: treeNode.dropDetail }); - }, - ); + () => { + this.setState({ dropDetail: treeNode.dropDetail }); + }, + ); } componentWillUnmount(): void { this.offLocationChanged && this.offLocationChanged(); @@ -188,8 +188,8 @@ class TreeNodeChildren extends PureComponent<{ } class TreeNodeSlots extends PureComponent<{ - treeNode: TreeNode; - }> { + treeNode: TreeNode; +}> { render() { const { treeNode } = this.props; if (!treeNode.hasSlots()) { diff --git a/packages/plugin-outline-pane/src/views/tree-node.tsx b/packages/plugin-outline-pane/src/views/tree-node.tsx index 96a833852..59f786628 100644 --- a/packages/plugin-outline-pane/src/views/tree-node.tsx +++ b/packages/plugin-outline-pane/src/views/tree-node.tsx @@ -103,21 +103,21 @@ export default class TreeNodeView extends PureComponent<{ matchChild: boolean; matchSelf: boolean; } = { - expanded: false, - selected: false, - hidden: false, - locked: false, - detecting: false, - isRoot: false, - highlight: false, - dropping: false, - conditionFlow: false, - expandable: false, - treeChildren: [], - filterWorking: false, - matchChild: false, - matchSelf: false, - }; + expanded: false, + selected: false, + hidden: false, + locked: false, + detecting: false, + isRoot: false, + highlight: false, + dropping: false, + conditionFlow: false, + expandable: false, + treeChildren: [], + filterWorking: false, + matchChild: false, + matchSelf: false, + }; eventOffCallbacks: Array<IPublicTypeDisposable | undefined> = []; constructor(props: any) { @@ -232,7 +232,7 @@ export default class TreeNodeView extends PureComponent<{ 'condition-flow': this.state.conditionFlow, highlight: this.state.highlight, }); - let shouldShowModalTreeNode: boolean = this.shouldShowModalTreeNode(); + const shouldShowModalTreeNode: boolean = this.shouldShowModalTreeNode(); // filter 处理 const { filterWorking, matchChild, matchSelf } = this.state; diff --git a/packages/plugin-outline-pane/src/views/tree-title.tsx b/packages/plugin-outline-pane/src/views/tree-title.tsx index 19c2817a1..70dd5b769 100644 --- a/packages/plugin-outline-pane/src/views/tree-title.tsx +++ b/packages/plugin-outline-pane/src/views/tree-title.tsx @@ -52,12 +52,12 @@ export default class TreeTitle extends PureComponent<{ keywords: string; matchSelf: boolean; } = { - editing: false, - title: '', - filterWorking: false, - keywords: '', - matchSelf: false, - }; + editing: false, + title: '', + filterWorking: false, + keywords: '', + matchSelf: false, + }; private lastInput?: HTMLInputElement; diff --git a/packages/plugin-outline-pane/src/views/tree.tsx b/packages/plugin-outline-pane/src/views/tree.tsx index 8428ec944..5d9a99f04 100644 --- a/packages/plugin-outline-pane/src/views/tree.tsx +++ b/packages/plugin-outline-pane/src/views/tree.tsx @@ -30,8 +30,8 @@ export default class TreeView extends PureComponent<{ state: { root: TreeNode | null; } = { - root: null, - }; + root: null, + }; private hover(e: ReactMouseEvent) { const { project } = this.props.tree.pluginContext; diff --git a/packages/react-renderer/package.json b/packages/react-renderer/package.json index c2224fea9..13a9f3c19 100644 --- a/packages/react-renderer/package.json +++ b/packages/react-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-renderer", - "version": "2.0.0-beta.0", + "version": "2.0.0-alpha.0", "description": "react renderer for ali lowcode engine", "type": "module", "bugs": "https://github.com/alibaba/lowcode-engine/issues", @@ -18,7 +18,7 @@ }, "scripts": { "build:target": "vite build", - "build:dts": "tsc -p tsconfig.declaration.json && node ../../scripts/rollup-dts.mjs", + "build:dts": "tsc -p tsconfig.declaration.json && node ../../scripts/rollup-dts.js", "test": "vitest" }, "dependencies": { diff --git a/packages/react-renderer/src/api/component.tsx b/packages/react-renderer/src/api/component.tsx index c8c491db2..0416db721 100644 --- a/packages/react-renderer/src/api/component.tsx +++ b/packages/react-renderer/src/api/component.tsx @@ -3,3 +3,5 @@ import { createComponent as internalCreate, ComponentOptions } from '../componen export function createComponent(options: ComponentOptions) { return internalCreate(options); } + +export type { ComponentOptions }; diff --git a/packages/react-renderer/src/runtime-api/intl/parser.ts b/packages/react-renderer/src/runtime-api/intl/parser.ts index 2289cf9cc..a2beba33e 100644 --- a/packages/react-renderer/src/runtime-api/intl/parser.ts +++ b/packages/react-renderer/src/runtime-api/intl/parser.ts @@ -81,7 +81,7 @@ export function compile(tokens: Token[], values: Record<string, any> | any[] = { break; case 'unknown': if (process.env.NODE_ENV !== 'production') { - console.warn(`Detect 'unknown' type of token!`); + console.warn('Detect \'unknown\' type of token!'); } break; } diff --git a/packages/react-renderer/src/utils/element.ts b/packages/react-renderer/src/utils/element.ts index cf19e1702..1ac0942d6 100644 --- a/packages/react-renderer/src/utils/element.ts +++ b/packages/react-renderer/src/utils/element.ts @@ -98,7 +98,7 @@ async function appendExternalCss( } return new Promise((resolve, reject) => { - let el: HTMLLinkElement = document.createElement('link'); + const el: HTMLLinkElement = document.createElement('link'); el.rel = 'stylesheet'; el.href = url; @@ -122,7 +122,7 @@ export async function appendExternalStyle( root: HTMLElement = document.head, ): Promise<HTMLElement> { return new Promise((resolve, reject) => { - let el: HTMLStyleElement = document.createElement('style'); + const el: HTMLStyleElement = document.createElement('style'); el.innerText = cssText; el.addEventListener( diff --git a/packages/renderer-core/tests/api/app.spec.ts b/packages/renderer-core/__tests__/api/app.spec.ts similarity index 100% rename from packages/renderer-core/tests/api/app.spec.ts rename to packages/renderer-core/__tests__/api/app.spec.ts diff --git a/packages/renderer-core/tests/api/component.spec.ts b/packages/renderer-core/__tests__/api/component.spec.ts similarity index 100% rename from packages/renderer-core/tests/api/component.spec.ts rename to packages/renderer-core/__tests__/api/component.spec.ts diff --git a/packages/renderer-core/tests/boosts.spec.ts b/packages/renderer-core/__tests__/boosts.spec.ts similarity index 100% rename from packages/renderer-core/tests/boosts.spec.ts rename to packages/renderer-core/__tests__/boosts.spec.ts diff --git a/packages/renderer-core/tests/code-runtime.spec.ts b/packages/renderer-core/__tests__/code-runtime.spec.ts similarity index 100% rename from packages/renderer-core/tests/code-runtime.spec.ts rename to packages/renderer-core/__tests__/code-runtime.spec.ts diff --git a/packages/renderer-core/tests/package.spec.ts b/packages/renderer-core/__tests__/package.spec.ts similarity index 100% rename from packages/renderer-core/tests/package.spec.ts rename to packages/renderer-core/__tests__/package.spec.ts diff --git a/packages/renderer-core/tests/plugin.spec.ts b/packages/renderer-core/__tests__/plugin.spec.ts similarity index 100% rename from packages/renderer-core/tests/plugin.spec.ts rename to packages/renderer-core/__tests__/plugin.spec.ts diff --git a/packages/renderer-core/tests/utils/hook.spec.ts b/packages/renderer-core/__tests__/utils/hook.spec.ts similarity index 96% rename from packages/renderer-core/tests/utils/hook.spec.ts rename to packages/renderer-core/__tests__/utils/hook.spec.ts index 266632ce4..53e9bcd07 100644 --- a/packages/renderer-core/tests/utils/hook.spec.ts +++ b/packages/renderer-core/__tests__/utils/hook.spec.ts @@ -1,9 +1,9 @@ import { describe, it, expect, vi, beforeEach } from 'vitest'; -import { useEvent, createHookStore, type HookStore } from '../../src/utils/hook'; +import { createEvent, createHookStore, type HookStore } from '../../src/utils/hook'; describe('event', () => { - it("event's listener ops", () => { - const event = useEvent(); + it('event\'s listener ops', () => { + const event = createEvent(); const fn = () => {}; event.add(fn); diff --git a/packages/renderer-core/tests/utils/non-setter-proxy.spec.ts b/packages/renderer-core/__tests__/utils/non-setter-proxy.spec.ts similarity index 100% rename from packages/renderer-core/tests/utils/non-setter-proxy.spec.ts rename to packages/renderer-core/__tests__/utils/non-setter-proxy.spec.ts diff --git a/packages/renderer-core/package.json b/packages/renderer-core/package.json index 51a531c2a..fee016ba7 100644 --- a/packages/renderer-core/package.json +++ b/packages/renderer-core/package.json @@ -1,17 +1,18 @@ { "name": "@alilc/lowcode-renderer-core", - "version": "2.0.0-beta.0", - "description": "", + "version": "2.0.0-alpha.0", + "description": "core package for lowCode renderer", "type": "module", "bugs": "https://github.com/alibaba/lowcode-engine/issues", "homepage": "https://github.com/alibaba/lowcode-engine/#readme", "license": "MIT", - "main": "dist/low-code-renderer-core.js", + "main": "dist/low-code-renderer-core.cjs", "module": "dist/low-code-renderer-core.js", "types": "dist/index.d.ts", "exports": { ".": { "import": "./dist/low-code-renderer-core.js", + "require": "./dist/low-code-renderer-core.cjs", "types": "./dist/index.d.ts" } }, @@ -22,7 +23,7 @@ ], "scripts": { "build:target": "vite build", - "build:dts": "tsc -p tsconfig.declaration.json && node ../../scripts/rollup-dts.mjs", + "build:dts": "tsc -p tsconfig.declaration.json && node ../../scripts/rollup-dts.js", "test": "vitest --run", "test:watch": "vitest" }, diff --git a/packages/renderer-core/src/index.ts b/packages/renderer-core/src/index.ts index 9af567f34..ece74eac2 100644 --- a/packages/renderer-core/src/index.ts +++ b/packages/renderer-core/src/index.ts @@ -5,7 +5,7 @@ export { createCodeRuntime, createScope } from './code-runtime'; export { definePlugin } from './plugin'; export { createWidget } from './widget'; export { createContainer } from './container'; -export { createHookStore, useEvent } from './utils/hook'; +export { createHookStore, createEvent } from './utils/hook'; export * from './utils/type-guard'; export * from './utils/value'; export * from './widget'; diff --git a/packages/renderer-core/src/utils/error.ts b/packages/renderer-core/src/utils/error.ts index 73e338daa..759493c6a 100644 --- a/packages/renderer-core/src/utils/error.ts +++ b/packages/renderer-core/src/utils/error.ts @@ -8,7 +8,7 @@ export class RuntimeError extends Error { message: string, ) { super(message); - appBoosts.hookStore.call(`app:error`, this); + appBoosts.hookStore.call('app:error', this); } } diff --git a/packages/renderer-core/src/utils/hook.ts b/packages/renderer-core/src/utils/hook.ts index d47e5031f..f68df026d 100644 --- a/packages/renderer-core/src/utils/hook.ts +++ b/packages/renderer-core/src/utils/hook.ts @@ -2,7 +2,7 @@ import type { AnyFunction } from '../types'; export type EventName = string | number | symbol; -export function useEvent<T = AnyFunction>() { +export function createEvent<T = AnyFunction>() { let events: T[] = []; function add(fn: T) { @@ -31,7 +31,7 @@ export function useEvent<T = AnyFunction>() { }; } -export type Event<F = AnyFunction> = ReturnType<typeof useEvent<F>>; +export type Event<F = AnyFunction> = ReturnType<typeof createEvent<F>>; export type HookCallback = (...args: any) => Promise<any> | any; @@ -93,7 +93,7 @@ export function createHookStore< let hooks = hooksMap.get(name); if (!hooks) { - hooks = useEvent(); + hooks = createEvent(); hooksMap.set(name, hooks); } diff --git a/packages/renderer-core/vite.config.ts b/packages/renderer-core/vite.config.ts index 38efe9f37..467e36d55 100644 --- a/packages/renderer-core/vite.config.ts +++ b/packages/renderer-core/vite.config.ts @@ -4,5 +4,6 @@ import baseConfigFn from '../../vite.base.config' export default defineConfig(async () => { return baseConfigFn({ name: 'LowCodeRendererCore', + defaultFormats: ['es', 'cjs'] }) }); diff --git a/packages/renderer-router/__tests__/matcher.spec.ts b/packages/renderer-router/__tests__/matcher.spec.ts new file mode 100644 index 000000000..d7b4ac791 --- /dev/null +++ b/packages/renderer-router/__tests__/matcher.spec.ts @@ -0,0 +1,7 @@ +import { createRouterMatcher } from '../src/matcher'; + +describe('RouterMatcher', () => { + it('', () => { + + }); +}); diff --git a/packages/renderer-router/package.json b/packages/renderer-router/package.json index a6c331634..64c9caefe 100644 --- a/packages/renderer-router/package.json +++ b/packages/renderer-router/package.json @@ -1,22 +1,24 @@ { "name": "@alilc/lowcode-renderer-router", - "version": "1.0.0-beta.0", - "description": "", + "version": "1.0.0-alpha.0", + "description": "router for lowCode renderer", "type": "module", "bugs": "https://github.com/alibaba/lowcode-engine/issues", "homepage": "https://github.com/alibaba/lowcode-engine/#readme", "license": "MIT", + "main": "dist/low-code-runtime-router.cjs", "module": "dist/low-code-runtime-router.js", "types": "dist/index.d.ts", "exports": { ".": { "import": "./dist/low-code-runtime-router.js", + "require": "./dist/low-code-runtime-router.cjs", "types": "./dist/index.d.ts" } }, "scripts": { "build:target": "vite build", - "build:dts": "tsc -p tsconfig.declaration.json && node ../../scripts/rollup-dts.mjs", + "build:dts": "tsc -p tsconfig.declaration.json && node ../../scripts/rollup-dts.js", "test": "vitest" }, "dependencies": { diff --git a/packages/renderer-router/src/history.ts b/packages/renderer-router/src/history.ts index 9387a05a1..34505c651 100644 --- a/packages/renderer-router/src/history.ts +++ b/packages/renderer-router/src/history.ts @@ -1,4 +1,4 @@ -import { useEvent } from '@alilc/lowcode-renderer-core'; +import { createEvent } from '@alilc/lowcode-renderer-core'; export type HistoryState = History['state']; export type HistoryLocation = string; @@ -166,8 +166,8 @@ export function createBrowserHistory(base?: string): RouterHistory { currentLocation = to; } - let listeners = useEvent<NavigationCallback>(); - let teardowns = useEvent<() => void>(); + const listeners = createEvent<NavigationCallback>(); + const teardowns = createEvent<() => void>(); let pauseState: HistoryLocation | null = null; @@ -285,7 +285,7 @@ function createCurrentLocation(base: string, location: Location) { // hash bases like #, /#, #/, #!, #!/, /#!/, or even /folder#end const hashPos = base.indexOf('#'); if (hashPos > -1) { - let slicePos = hash.includes(base.slice(hashPos)) ? base.slice(hashPos).length : 1; + const slicePos = hash.includes(base.slice(hashPos)) ? base.slice(hashPos).length : 1; let pathFromHash = hash.slice(slicePos); // prepend the starting slash to hash so the url starts with /# if (pathFromHash[0] !== '/') pathFromHash = '/' + pathFromHash; @@ -348,7 +348,7 @@ export function createMemoryHistory(base = ''): RouterHistory { historyStack.push({ location, state }); } - const listeners = useEvent<NavigationCallback>(); + const listeners = createEvent<NavigationCallback>(); function triggerListeners( to: HistoryLocation, diff --git a/packages/renderer-router/src/matcher.ts b/packages/renderer-router/src/matcher.ts index 3db4ee677..9c82f82b1 100644 --- a/packages/renderer-router/src/matcher.ts +++ b/packages/renderer-router/src/matcher.ts @@ -1,9 +1,11 @@ +// refer from https://github.com/vuejs/router/blob/main/packages/router/src/matcher/index.ts + import { type PlainObject, type RawLocation } from '@alilc/lowcode-renderer-core'; import { pick } from 'lodash-es'; import { createRouteRecordMatcher, type RouteRecordMatcher } from './utils/record-matcher'; -import { type PathParserOptions } from './utils/path-parser'; +import { type PathParserOptions, type PathParams, comparePathParserScore } from './utils/path-parser'; -import type { RouteRecord, RouteParams, RouteLocationNormalized } from './types'; +import type { RouteRecord, RouteLocationNormalized } from './types'; export interface RouteRecordNormalized { /** @@ -58,7 +60,9 @@ export interface RouterMatcher { * @param location - MatcherLocationRaw to resolve to a url * @param currentLocation - MatcherLocation of the current location */ - resolve: (location: RawLocation, currentLocation: MatcherLocation) => MatcherLocation; + resolve: ( + location: RawLocation, currentLocation: MatcherLocation + ) => MatcherLocation; } export function createRouterMatcher( @@ -83,7 +87,7 @@ export function createRouterMatcher( const parentPath = parent.record.path; const connectingSlash = parentPath[parentPath.length - 1] === '/' ? '' : '/'; - normalizedRecord.path = parent.record.path + (path && connectingSlash + path); + normalizedRecord.path = parent.record.path + (path ? connectingSlash + path : ''); } const matcher = createRouteRecordMatcher(normalizedRecord, parent, options); @@ -96,7 +100,16 @@ export function createRouterMatcher( } if (matcher.record.path) { - matchers.push(matcher); + let i = 0; + while ( + i < matchers.length && + comparePathParserScore(matcher, matchers[i]) >= 0 && + (matcher.record.path !== matchers[i].record.path || + !isRecordChildOf(matcher, matchers[i])) + ) { + i++; + } + matchers.splice(i, 0, matcher); if (matcher.record.name) { matcherMap.set(matcher.record.name, matcher); @@ -126,9 +139,12 @@ export function createRouterMatcher( return matcherMap.get(name); } - function resolve(location: RawLocation, currentLocation: MatcherLocation): MatcherLocation { + function resolve( + location: RawLocation, + currentLocation: MatcherLocation + ): MatcherLocation { let matcher: RouteRecordMatcher | undefined; - let params: RouteParams = {}; + let params: PathParams = {}; let path: MatcherLocation['path']; let name: MatcherLocation['name']; @@ -136,7 +152,9 @@ export function createRouterMatcher( matcher = matcherMap.get(location.name); if (!matcher) { - throw new Error(`Router error: no match for ${JSON.stringify(location)}`); + throw new Error(` + Router error: no match for ${JSON.stringify(location)} + `); } name = matcher.record.name; @@ -145,19 +163,20 @@ export function createRouterMatcher( paramsFromLocation( currentLocation.params ?? {}, matcher.keys - .filter((k) => { - return !(k.modifier === '?' || k.modifier === '*'); - }) + .filter(k => !k.optional) + .concat( + matcher.parent ? matcher.parent.keys.filter(k => k.optional) : [] + ) .map((k) => k.name), ), location.params ? paramsFromLocation( - location.params, - matcher.keys.map((k) => k.name), - ) + location.params, + matcher.keys.map((k) => k.name), + ) : {}, ); - // throws if cannot be stringified + path = matcher.stringify(params); } else if ('path' in location) { path = location.path; @@ -214,8 +233,8 @@ export function createRouterMatcher( }; } -function paramsFromLocation(params: RouteParams, keys: (string | number)[]): RouteParams { - const newParams = {} as RouteParams; +function paramsFromLocation(params: PathParams, keys: (string | number)[]): PathParams { + const newParams = {} as PathParams; for (const key of keys) { if (key in params) newParams[key] = params[key]; } @@ -233,3 +252,12 @@ export function normalizeRouteRecord(record: RouteRecord): RouteRecordNormalized children: record.children || [], }; } + +function isRecordChildOf( + record: RouteRecordMatcher, + parent: RouteRecordMatcher +): boolean { + return parent.children.some( + child => child === record || isRecordChildOf(record, child) + ); +} diff --git a/packages/renderer-router/src/router.ts b/packages/renderer-router/src/router.ts index 1b61ab9bb..439b0832f 100644 --- a/packages/renderer-router/src/router.ts +++ b/packages/renderer-router/src/router.ts @@ -2,7 +2,7 @@ import { type RouterApi, type RouterConfig, type RouteLocation, - useEvent, + createEvent, type RawRouteLocation, type RawLocationOptions, } from '@alilc/lowcode-renderer-core'; @@ -14,10 +14,10 @@ import { type HistoryState, } from './history'; import { createRouterMatcher } from './matcher'; -import { type PathParserOptions } from './utils/path-parser'; +import { type PathParserOptions, type PathParams } from './utils/path-parser'; import { parseURL, stringifyURL } from './utils/url'; import { isSameRouteLocation } from './utils/helper'; -import type { RouteParams, RouteRecord, RouteLocationNormalized } from './types'; +import type { RouteRecord, RouteLocationNormalized } from './types'; import { type NavigationHookAfter, type NavigationGuard, guardToPromiseFn } from './guard'; export interface RouterOptions extends RouterConfig, PathParserOptions { @@ -72,8 +72,8 @@ export function createRouter(options: RouterOptions = defaultRouterOptions): Rou ? createMemoryHistory(baseName) : createBrowserHistory(baseName); - const beforeGuards = useEvent<NavigationGuard>(); - const afterGuards = useEvent<NavigationHookAfter>(); + const beforeGuards = createEvent<NavigationGuard>(); + const afterGuards = createEvent<NavigationHookAfter>(); let currentLocation: RouteLocationNormalized = START_LOCATION; let pendingLocation = currentLocation; @@ -114,9 +114,9 @@ export function createRouter(options: RouterOptions = defaultRouterOptions): Rou matcherLocation = { ...rawLocation, - params: rawLocation.params as RouteParams, + params: rawLocation.params as PathParams, }; - currentLocation.params = currentLocation.params; + currentLocation.params = matcherLocation.params; } const matchedRoute = matcher.resolve(matcherLocation, currentLocation); @@ -256,7 +256,7 @@ export function createRouter(options: RouterOptions = defaultRouterOptions): Rou to: RouteLocationNormalized, from: RouteLocationNormalized, ): Promise<any> { - let guards: ((...args: any[]) => Promise<any>)[] = []; + const guards: ((...args: any[]) => Promise<any>)[] = []; const canceledNavigationCheck = async (): Promise<any> => { if (pendingLocation !== to) { @@ -265,19 +265,14 @@ export function createRouter(options: RouterOptions = defaultRouterOptions): Rou return Promise.resolve(); }; - try { - guards = []; - const beforeGuardsList = beforeGuards.list(); + const beforeGuardsList = beforeGuards.list(); - for (const guard of beforeGuardsList) { - guards.push(guardToPromiseFn(guard, to, from)); - } - if (beforeGuardsList.length > 0) guards.push(canceledNavigationCheck); - - return guards.reduce((promise, guard) => promise.then(() => guard()), Promise.resolve()); - } catch (err) { - throw err; + for (const guard of beforeGuardsList) { + guards.push(guardToPromiseFn(guard, to, from)); } + if (beforeGuardsList.length > 0) guards.push(canceledNavigationCheck); + + return guards.reduce((promise, guard) => promise.then(() => guard()), Promise.resolve()); } function finalizeNavigation( diff --git a/packages/renderer-router/src/types.ts b/packages/renderer-router/src/types.ts index 6c164723e..d13253d28 100644 --- a/packages/renderer-router/src/types.ts +++ b/packages/renderer-router/src/types.ts @@ -18,5 +18,3 @@ export interface RouteRecord extends RouterRecordSpec, PathParserOptions { export interface RouteLocationNormalized extends RouteLocation { matched: RouteRecord[]; } - -export type RouteParams = Record<string, string | string[]>; diff --git a/packages/renderer-router/src/utils/path-parser.ts b/packages/renderer-router/src/utils/path-parser.ts deleted file mode 100644 index fc1cc5b7d..000000000 --- a/packages/renderer-router/src/utils/path-parser.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { - pathToRegexp, - match, - compile, - type Key, - type TokensToRegexpOptions, -} from 'path-to-regexp'; -import type { RouteParams } from '../types'; - -export interface PathParser { - re: RegExp; - /** - * optional = token.modifier === "?" || token.modifier === "*"; - * repeat = token.modifier === "*" || token.modifier === "+"; - */ - keys: Key[]; - /** - * 解析路径中的参数 - */ - parse: (path: string) => RouteParams | undefined; - stringify: (params: RouteParams) => string; -} - -export type PathParserOptions = Pick< - TokensToRegexpOptions, - 'end' | 'strict' | 'sensitive' ->; - -export function createPathParser(path: string, options: PathParserOptions) { - if (!path.startsWith('/')) { - throw new Error( - `Route paths should start with a "/": "${path}" should be "/${path}".` - ); - } - - const keys: Key[] = []; - const re = pathToRegexp(path, keys, options); - const parse = match(path); - const stringify = compile(path, { encode: encodeURIComponent }); - - return { - re, - keys, - parse: (path: string) => { - const parsed = parse(path); - if (!parsed) return undefined; - return parsed.params as RouteParams; - }, - stringify: (params: RouteParams) => { - return stringify(params); - }, - }; -} diff --git a/packages/renderer-router/src/utils/path-parser/index.ts b/packages/renderer-router/src/utils/path-parser/index.ts new file mode 100644 index 000000000..740afbe7c --- /dev/null +++ b/packages/renderer-router/src/utils/path-parser/index.ts @@ -0,0 +1,9 @@ +import { type PathParserOptions, tokensToParser } from './parser-ranker'; +import { tokenizePath } from './path-tokenizer'; + +export function createPathParser(path: string, options?: PathParserOptions) { + return tokensToParser(tokenizePath(path), options); +} + +export { comparePathParserScore } from './parser-ranker'; +export type { PathParser, PathParams, PathParserOptions } from './parser-ranker'; diff --git a/packages/renderer-router/src/utils/path-parser/parser-ranker.ts b/packages/renderer-router/src/utils/path-parser/parser-ranker.ts new file mode 100644 index 000000000..12d2b16cd --- /dev/null +++ b/packages/renderer-router/src/utils/path-parser/parser-ranker.ts @@ -0,0 +1,370 @@ +// fork from https://github.com/vuejs/router/blob/main/packages/router/src/matcher/pathParserRanker.ts + +import { Token, TokenType } from './path-tokenizer'; + +export type PathParams = Record<string, string | string[]>; + +/** + * A param in a url like `/users/:id` + */ +interface PathParserParamKey { + name: string + repeatable: boolean + optional: boolean +} + +export interface PathParser { + /** + * The regexp used to match a url + */ + re: RegExp + + /** + * The score of the parser + */ + score: Array<number[]> + + /** + * Keys that appeared in the path + */ + keys: PathParserParamKey[] + /** + * Parses a url and returns the matched params or null if it doesn't match. An + * optional param that isn't preset will be an empty string. A repeatable + * param will be an array if there is at least one value. + * + * @param path - url to parse + * @returns a Params object, empty if there are no params. `null` if there is + * no match + */ + parse(path: string): PathParams | null + + /** + * Creates a string version of the url + * + * @param params - object of params + * @returns a url + */ + stringify(params: PathParams): string +} + +/** + * @internal + */ +export interface _PathParserOptions { + /** + * Makes the RegExp case-sensitive. + * + * @defaultValue `false` + */ + sensitive?: boolean + + /** + * Whether to disallow a trailing slash or not. + * + * @defaultValue `false` + */ + strict?: boolean + + /** + * Should the RegExp match from the beginning by prepending a `^` to it. + * @internal + * + * @defaultValue `true` + */ + start?: boolean + + /** + * Should the RegExp match until the end by appending a `$` to it. + * + * @defaultValue `true` + */ + end?: boolean +} + +export type PathParserOptions = Pick< + _PathParserOptions, + 'end' | 'sensitive' | 'strict' +>; + +// default pattern for a param: non-greedy everything but / +const BASE_PARAM_PATTERN = '[^/]+?'; + +const BASE_PATH_PARSER_OPTIONS: Required<_PathParserOptions> = { + sensitive: false, + strict: false, + start: true, + end: true, +}; + +// Scoring values used in tokensToParser +const enum PathScore { + _multiplier = 10, + Root = 9 * _multiplier, // just / + Segment = 4 * _multiplier, // /a-segment + SubSegment = 3 * _multiplier, // /multiple-:things-in-one-:segment + Static = 4 * _multiplier, // /static + Dynamic = 2 * _multiplier, // /:someId + BonusCustomRegExp = 1 * _multiplier, // /:someId(\\d+) + BonusWildcard = -4 * _multiplier - BonusCustomRegExp, // /:namedWildcard(.*) we remove the bonus added by the custom regexp + BonusRepeatable = -2 * _multiplier, // /:w+ or /:w* + BonusOptional = -0.8 * _multiplier, // /:w? or /:w* + // these two have to be under 0.1 so a strict /:page is still lower than /:a-:b + BonusStrict = 0.07 * _multiplier, // when options strict: true is passed, as the regex omits \/? + BonusCaseSensitive = 0.025 * _multiplier, // when options strict: true is passed, as the regex omits \/? +} + +// Special Regex characters that must be escaped in static tokens +const REGEX_CHARS_RE = /[.+*?^${}()[\]/\\]/g; + +/** + * Creates a path parser from an array of Segments (a segment is an array of Tokens) + * + * @param segments - array of segments returned by tokenizePath + * @param extraOptions - optional options for the regexp + * @returns a PathParser + */ +export function tokensToParser( + segments: Array<Token[]>, + extraOptions?: _PathParserOptions +): PathParser { + const options = Object.assign({}, BASE_PATH_PARSER_OPTIONS, extraOptions); + + // the amount of scores is the same as the length of segments except for the root segment "/" + const score: Array<number[]> = []; + // the regexp as a string + let pattern = options.start ? '^' : ''; + // extracted keys + const keys: PathParserParamKey[] = []; + + for (const segment of segments) { + // the root segment needs special treatment + const segmentScores: number[] = segment.length ? [] : [PathScore.Root]; + + // allow trailing slash + if (options.strict && !segment.length) pattern += '/'; + for (let tokenIndex = 0; tokenIndex < segment.length; tokenIndex++) { + const token = segment[tokenIndex]; + // resets the score if we are inside a sub-segment /:a-other-:b + let subSegmentScore: number = + PathScore.Segment + + (options.sensitive ? PathScore.BonusCaseSensitive : 0); + + if (token.type === TokenType.Static) { + // prepend the slash if we are starting a new segment + if (!tokenIndex) pattern += '/'; + pattern += token.value.replace(REGEX_CHARS_RE, '\\$&'); + subSegmentScore += PathScore.Static; + } else if (token.type === TokenType.Param) { + const { value, repeatable, optional, regexp } = token; + keys.push({ + name: value, + repeatable, + optional, + }); + const re = regexp ? regexp : BASE_PARAM_PATTERN; + // the user provided a custom regexp /:id(\\d+) + if (re !== BASE_PARAM_PATTERN) { + subSegmentScore += PathScore.BonusCustomRegExp; + // make sure the regexp is valid before using it + try { + new RegExp(`(${re})`); + } catch (err) { + throw new Error( + `Invalid custom RegExp for param "${value}" (${re}): ` + + (err as Error).message + ); + } + } + + // when we repeat we must take care of the repeating leading slash + let subPattern = repeatable ? `((?:${re})(?:/(?:${re}))*)` : `(${re})`; + + // prepend the slash if we are starting a new segment + if (!tokenIndex) + subPattern = + // avoid an optional / if there are more segments e.g. /:p?-static + // or /:p?-:p2 + optional && segment.length < 2 + ? `(?:/${subPattern})` + : '/' + subPattern; + if (optional) subPattern += '?'; + + pattern += subPattern; + + subSegmentScore += PathScore.Dynamic; + if (optional) subSegmentScore += PathScore.BonusOptional; + if (repeatable) subSegmentScore += PathScore.BonusRepeatable; + if (re === '.*') subSegmentScore += PathScore.BonusWildcard; + } + + segmentScores.push(subSegmentScore); + } + + // an empty array like /home/ -> [[{home}], []] + // if (!segment.length) pattern += '/' + + score.push(segmentScores); + } + + // only apply the strict bonus to the last score + if (options.strict && options.end) { + const i = score.length - 1; + score[i][score[i].length - 1] += PathScore.BonusStrict; + } + + // TODO: dev only warn double trailing slash + if (!options.strict) pattern += '/?'; + + if (options.end) pattern += '$'; + // allow paths like /dynamic to only match dynamic or dynamic/... but not dynamic_something_else + else if (options.strict) pattern += '(?:/|$)'; + + const re = new RegExp(pattern, options.sensitive ? '' : 'i'); + + function parse(path: string): PathParams | null { + const match = path.match(re); + const params: PathParams = {}; + + if (!match) return null; + + for (let i = 1; i < match.length; i++) { + const value: string = match[i] || ''; + const key = keys[i - 1]; + params[key.name] = value && key.repeatable ? value.split('/') : value; + } + + return params; + } + + function stringify(params: PathParams): string { + let path = ''; + // for optional parameters to allow to be empty + let avoidDuplicatedSlash: boolean = false; + for (const segment of segments) { + if (!avoidDuplicatedSlash || !path.endsWith('/')) path += '/'; + avoidDuplicatedSlash = false; + + for (const token of segment) { + if (token.type === TokenType.Static) { + path += token.value; + } else if (token.type === TokenType.Param) { + const { value, repeatable, optional } = token; + const param: string | readonly string[] = + value in params ? params[value] : ''; + + if (Array.isArray(param) && !repeatable) { + throw new Error( + `Provided param "${value}" is an array but it is not repeatable (* or + modifiers)` + ); + } + + const text: string = Array.isArray(param) + ? (param as string[]).join('/') + : (param as string); + if (!text) { + if (optional) { + // if we have more than one optional param like /:a?-static we don't need to care about the optional param + if (segment.length < 2) { + // remove the last slash as we could be at the end + if (path.endsWith('/')) path = path.slice(0, -1); + // do not append a slash on the next iteration + else avoidDuplicatedSlash = true; + } + } else throw new Error(`Missing required param "${value}"`); + } + path += text; + } + } + } + + // avoid empty path when we have multiple optional params + return path || '/'; + } + + return { + re, + score, + keys, + parse, + stringify, + }; +} + +/** + * Compares an array of numbers as used in PathParser.score and returns a + * number. This function can be used to `sort` an array + * + * @param a - first array of numbers + * @param b - second array of numbers + * @returns 0 if both are equal, < 0 if a should be sorted first, > 0 if b + * should be sorted first + */ +function compareScoreArray(a: number[], b: number[]): number { + let i = 0; + while (i < a.length && i < b.length) { + const diff = b[i] - a[i]; + // only keep going if diff === 0 + if (diff) return diff; + + i++; + } + + // if the last subsegment was Static, the shorter segments should be sorted first + // otherwise sort the longest segment first + if (a.length < b.length) { + return a.length === 1 && a[0] === PathScore.Static + PathScore.Segment + ? -1 + : 1; + } else if (a.length > b.length) { + return b.length === 1 && b[0] === PathScore.Static + PathScore.Segment + ? 1 + : -1; + } + + return 0; +} + +/** + * Compare function that can be used with `sort` to sort an array of PathParser + * + * @param a - first PathParser + * @param b - second PathParser + * @returns 0 if both are equal, < 0 if a should be sorted first, > 0 if b + */ +export function comparePathParserScore(a: PathParser, b: PathParser): number { + let i = 0; + const aScore = a.score; + const bScore = b.score; + while (i < aScore.length && i < bScore.length) { + const comp = compareScoreArray(aScore[i], bScore[i]); + // do not return if both are equal + if (comp) return comp; + + i++; + } + if (Math.abs(bScore.length - aScore.length) === 1) { + if (isLastScoreNegative(aScore)) return 1; + if (isLastScoreNegative(bScore)) return -1; + } + + // if a and b share the same score entries but b has more, sort b first + return bScore.length - aScore.length; + // this is the ternary version + // return aScore.length < bScore.length + // ? 1 + // : aScore.length > bScore.length + // ? -1 + // : 0 +} + +/** + * This allows detecting splats at the end of a path: /home/:id(.*)* + * + * @param score - score to check + * @returns true if the last entry is negative + */ +function isLastScoreNegative(score: PathParser['score']): boolean { + const last = score[score.length - 1]; + return score.length > 0 && last[last.length - 1] < 0; +} diff --git a/packages/renderer-router/src/utils/path-parser/path-tokenizer.ts b/packages/renderer-router/src/utils/path-parser/path-tokenizer.ts new file mode 100644 index 000000000..7386f29b8 --- /dev/null +++ b/packages/renderer-router/src/utils/path-parser/path-tokenizer.ts @@ -0,0 +1,200 @@ +// fork from https://github.com/vuejs/router/blob/main/packages/router/src/matcher/pathTokenizer.ts + +export const enum TokenType { + Static, + Param, + Group, +} + +const enum TokenizerState { + Static, + Param, + ParamRegExp, // custom re for a param + ParamRegExpEnd, // check if there is any ? + * + EscapeNext, +} + +interface TokenStatic { + type: TokenType.Static + value: string +} + +interface TokenParam { + type: TokenType.Param + regexp?: string + value: string + optional: boolean + repeatable: boolean +} + +interface TokenGroup { + type: TokenType.Group + value: Exclude<Token, TokenGroup>[] +} + +export type Token = TokenStatic | TokenParam | TokenGroup; + +const ROOT_TOKEN: Token = { + type: TokenType.Static, + value: '', +}; + +const VALID_PARAM_RE = /[a-zA-Z0-9_]/; +// After some profiling, the cache seems to be unnecessary because tokenizePath +// (the slowest part of adding a route) is very fast + +// const tokenCache = new Map<string, Token[][]>() + +export function tokenizePath(path: string): Array<Token[]> { + if (!path) return [[]]; + if (path === '/') return [[ROOT_TOKEN]]; + if (!path.startsWith('/')) { + throw new Error( + `Route paths should start with a "/": "${path}" should be "/${path}".` + ); + } + + // if (tokenCache.has(path)) return tokenCache.get(path)! + + function crash(message: string) { + throw new Error(`ERR (${state})/"${buffer}": ${message}`); + } + + let state: TokenizerState = TokenizerState.Static; + let previousState: TokenizerState = state; + const tokens: Array<Token[]> = []; + // the segment will always be valid because we get into the initial state + // with the leading / + let segment!: Token[]; + + function finalizeSegment() { + if (segment) tokens.push(segment); + segment = []; + } + + // index on the path + let i = 0; + // char at index + let char: string; + // buffer of the value read + let buffer: string = ''; + // custom regexp for a param + let customRe: string = ''; + + function consumeBuffer() { + if (!buffer) return; + + if (state === TokenizerState.Static) { + segment.push({ + type: TokenType.Static, + value: buffer, + }); + } else if ( + state === TokenizerState.Param || + state === TokenizerState.ParamRegExp || + state === TokenizerState.ParamRegExpEnd + ) { + if (segment.length > 1 && (char === '*' || char === '+')) + crash( + `A repeatable param (${buffer}) must be alone in its segment. eg: '/:ids+.` + ); + segment.push({ + type: TokenType.Param, + value: buffer, + regexp: customRe, + repeatable: char === '*' || char === '+', + optional: char === '*' || char === '?', + }); + } else { + crash('Invalid state to consume buffer'); + } + buffer = ''; + } + + function addCharToBuffer() { + buffer += char; + } + + while (i < path.length) { + char = path[i++]; + + if (char === '\\' && state !== TokenizerState.ParamRegExp) { + previousState = state; + state = TokenizerState.EscapeNext; + continue; + } + + switch (state) { + case TokenizerState.Static: + if (char === '/') { + if (buffer) { + consumeBuffer(); + } + finalizeSegment(); + } else if (char === ':') { + consumeBuffer(); + state = TokenizerState.Param; + } else { + addCharToBuffer(); + } + break; + + case TokenizerState.EscapeNext: + addCharToBuffer(); + state = previousState; + break; + + case TokenizerState.Param: + if (char === '(') { + state = TokenizerState.ParamRegExp; + } else if (VALID_PARAM_RE.test(char)) { + addCharToBuffer(); + } else { + consumeBuffer(); + state = TokenizerState.Static; + // go back one character if we were not modifying + if (char !== '*' && char !== '?' && char !== '+') i--; + } + break; + + case TokenizerState.ParamRegExp: + // TODO: is it worth handling nested regexp? like :p(?:prefix_([^/]+)_suffix) + // it already works by escaping the closing ) + // https://paths.esm.dev/?p=AAMeJbiAwQEcDKbAoAAkP60PG2R6QAvgNaA6AFACM2ABuQBB# + // is this really something people need since you can also write + // /prefix_:p()_suffix + if (char === ')') { + // handle the escaped ) + if (customRe[customRe.length - 1] == '\\') + customRe = customRe.slice(0, -1) + char; + else state = TokenizerState.ParamRegExpEnd; + } else { + customRe += char; + } + break; + + case TokenizerState.ParamRegExpEnd: + // same as finalizing a param + consumeBuffer(); + state = TokenizerState.Static; + // go back one character if we were not modifying + if (char !== '*' && char !== '?' && char !== '+') i--; + customRe = ''; + break; + + default: + crash('Unknown state'); + break; + } + } + + if (state === TokenizerState.ParamRegExp) + crash(`Unfinished custom RegExp for param "${buffer}"`); + + consumeBuffer(); + finalizeSegment(); + + // tokenCache.set(path, tokens) + + return tokens; +} diff --git a/packages/renderer-router/vite.config.ts b/packages/renderer-router/vite.config.ts index e4e227ede..9130dcb58 100644 --- a/packages/renderer-router/vite.config.ts +++ b/packages/renderer-router/vite.config.ts @@ -4,5 +4,6 @@ import baseConfigFn from '../../vite.base.config' export default defineConfig(async () => { return baseConfigFn({ name: 'LowCodeRuntimeRouter', + defaultFormats: ['es', 'cjs'] }) }); diff --git a/packages/renderer-router/vitest.config.ts b/packages/renderer-router/vitest.config.ts index e69de29bb..5b100d2a3 100644 --- a/packages/renderer-router/vitest.config.ts +++ b/packages/renderer-router/vitest.config.ts @@ -0,0 +1,5 @@ +import { defineProject } from 'vitest/config' + +export default defineProject({ + test: {} +}) diff --git a/packages/types/src/editor.ts b/packages/types/src/editor.ts index 3691a7f94..468aedb9f 100644 --- a/packages/types/src/editor.ts +++ b/packages/types/src/editor.ts @@ -144,4 +144,4 @@ export interface PluginStatus { export interface PluginStatusSet { [key: string]: PluginStatus; -} \ No newline at end of file +} diff --git a/packages/types/src/shell/api/command.ts b/packages/types/src/shell/api/command.ts index 1f8425dce..5361c8777 100644 --- a/packages/types/src/shell/api/command.ts +++ b/packages/types/src/shell/api/command.ts @@ -31,4 +31,4 @@ export interface IPublicApiCommand { * 注册错误处理回调函数 */ onCommandError(callback: (name: string, error: Error) => void): void; -} \ No newline at end of file +} diff --git a/packages/types/src/shell/api/common.ts b/packages/types/src/shell/api/common.ts index 16b02f65d..bc2d5a281 100644 --- a/packages/types/src/shell/api/common.ts +++ b/packages/types/src/shell/api/common.ts @@ -30,9 +30,9 @@ export interface IPublicApiCommonUtils { * @returns {(IPublicTypeNodeSchema | undefined)} */ getNodeSchemaById( - schema: IPublicTypeNodeSchema, - nodeId: string, - ): IPublicTypeNodeSchema | undefined; + schema: IPublicTypeNodeSchema, + nodeId: string, + ): IPublicTypeNodeSchema | undefined; // TODO: add comments getConvertedExtraKey(key: string): string; diff --git a/packages/types/src/shell/api/hotkey.ts b/packages/types/src/shell/api/hotkey.ts index 55bde5d01..4c478b5c5 100644 --- a/packages/types/src/shell/api/hotkey.ts +++ b/packages/types/src/shell/api/hotkey.ts @@ -18,10 +18,10 @@ export interface IPublicApiHotkey { * @param action */ bind( - combos: string[] | string, - callback: IPublicTypeHotkeyCallback, - action?: string, - ): IPublicTypeDisposable; + combos: string[] | string, + callback: IPublicTypeHotkeyCallback, + action?: string, + ): IPublicTypeDisposable; /** * 给指定窗口绑定快捷键 diff --git a/packages/types/src/shell/api/index.ts b/packages/types/src/shell/api/index.ts index 8f14d8dad..849dd108a 100644 --- a/packages/types/src/shell/api/index.ts +++ b/packages/types/src/shell/api/index.ts @@ -11,4 +11,4 @@ export * from './logger'; export * from './canvas'; export * from './workspace'; export * from './commonUI'; -export * from './command'; \ No newline at end of file +export * from './command'; diff --git a/packages/types/src/shell/api/material.ts b/packages/types/src/shell/api/material.ts index 89b2b39ad..1ef9932cc 100644 --- a/packages/types/src/shell/api/material.ts +++ b/packages/types/src/shell/api/material.ts @@ -112,9 +112,9 @@ export interface IPublicApiMaterial { * @param handle */ modifyBuiltinComponentAction( - actionName: string, - handle: (action: IPublicTypeComponentAction) => void, - ): void; + actionName: string, + handle: (action: IPublicTypeComponentAction) => void, + ): void; /** * 监听 assets 变化的事件 diff --git a/packages/types/src/shell/api/plugins.ts b/packages/types/src/shell/api/plugins.ts index a93016290..cbac40566 100644 --- a/packages/types/src/shell/api/plugins.ts +++ b/packages/types/src/shell/api/plugins.ts @@ -30,8 +30,8 @@ export interface IPublicApiPlugins { * use this to get preference config for this plugin when engine.init() called */ getPluginPreference( - pluginName: string, - ): Record<string, IPublicTypePreferenceValueType> | null | undefined; + pluginName: string, + ): Record<string, IPublicTypePreferenceValueType> | null | undefined; /** * 获取指定插件 diff --git a/packages/types/src/shell/api/project.ts b/packages/types/src/shell/api/project.ts index 662f302cc..b01532733 100644 --- a/packages/types/src/shell/api/project.ts +++ b/packages/types/src/shell/api/project.ts @@ -93,9 +93,9 @@ export interface IBaseApiProject< * @param stage */ addPropsTransducer( - transducer: IPublicTypePropsTransducer, - stage: IPublicEnumTransformStage, - ): void; + transducer: IPublicTypePropsTransducer, + stage: IPublicEnumTransformStage, + ): void; /** * 绑定删除文档事件 diff --git a/packages/types/src/shell/enum/context-menu.ts b/packages/types/src/shell/enum/context-menu.ts index fd209b197..190dc039d 100644 --- a/packages/types/src/shell/enum/context-menu.ts +++ b/packages/types/src/shell/enum/context-menu.ts @@ -4,4 +4,4 @@ export enum IPublicEnumContextMenuType { MENU_ITEM = 'menuItem', // 'nodeTree' NODE_TREE = 'nodeTree', -} \ No newline at end of file +} diff --git a/packages/types/src/shell/enum/event-names.ts b/packages/types/src/shell/enum/event-names.ts index 1bb8682d4..563ac7fe6 100644 --- a/packages/types/src/shell/enum/event-names.ts +++ b/packages/types/src/shell/enum/event-names.ts @@ -6,4 +6,4 @@ */ // eslint-disable-next-line no-shadow export enum IPublicEnumEventNames { -} \ No newline at end of file +} diff --git a/packages/types/src/shell/enum/index.ts b/packages/types/src/shell/enum/index.ts index 13282d0f2..d746976fb 100644 --- a/packages/types/src/shell/enum/index.ts +++ b/packages/types/src/shell/enum/index.ts @@ -4,4 +4,4 @@ export * from './transform-stage'; export * from './drag-object-type'; export * from './prop-value-changed-type'; export * from './plugin-register-level'; -export * from './context-menu'; \ No newline at end of file +export * from './context-menu'; diff --git a/packages/types/src/shell/enum/plugin-register-level.ts b/packages/types/src/shell/enum/plugin-register-level.ts index a0d9b746b..3ec37cb3a 100644 --- a/packages/types/src/shell/enum/plugin-register-level.ts +++ b/packages/types/src/shell/enum/plugin-register-level.ts @@ -3,4 +3,4 @@ export enum IPublicEnumPluginRegisterLevel { Workspace = 'workspace', Resource = 'resource', EditorView = 'editorView', -} \ No newline at end of file +} diff --git a/packages/types/src/shell/index.ts b/packages/types/src/shell/index.ts index c392c1e12..534c1fae1 100644 --- a/packages/types/src/shell/index.ts +++ b/packages/types/src/shell/index.ts @@ -2,4 +2,4 @@ export * from './type'; export * from './api'; export * from './model'; -export * from './enum'; \ No newline at end of file +export * from './enum'; diff --git a/packages/types/src/shell/model/clipboard.ts b/packages/types/src/shell/model/clipboard.ts index 7fdcc4b1c..3c57373b2 100644 --- a/packages/types/src/shell/model/clipboard.ts +++ b/packages/types/src/shell/model/clipboard.ts @@ -19,7 +19,7 @@ export interface IPublicModelClipboard { * @since v1.1.0 */ waitPasteData( - keyboardEvent: KeyboardEvent, - cb: (data: any, clipboardEvent: ClipboardEvent) => void, - ): void; + keyboardEvent: KeyboardEvent, + cb: (data: any, clipboardEvent: ClipboardEvent) => void, + ): void; } diff --git a/packages/types/src/shell/model/component-meta.ts b/packages/types/src/shell/model/component-meta.ts index f2b0032a7..88dbfe6af 100644 --- a/packages/types/src/shell/model/component-meta.ts +++ b/packages/types/src/shell/model/component-meta.ts @@ -103,9 +103,9 @@ export interface IPublicModelComponentMeta< * @param parent 父节点 */ checkNestingDown( - my: Node | IPublicTypeNodeData, - target: IPublicTypeNodeSchema | Node | IPublicTypeNodeSchema[], - ): boolean; + my: Node | IPublicTypeNodeData, + target: IPublicTypeNodeSchema | Node | IPublicTypeNodeSchema[], + ): boolean; /** * 刷新元数据,会触发元数据的重新解析和刷新 diff --git a/packages/types/src/shell/model/editor-view.ts b/packages/types/src/shell/model/editor-view.ts index d51e4f9ff..ccdfe5cca 100644 --- a/packages/types/src/shell/model/editor-view.ts +++ b/packages/types/src/shell/model/editor-view.ts @@ -4,4 +4,4 @@ export interface IPublicModelEditorView extends IPublicModelPluginContext { viewName: string; viewType: 'editor' | 'webview'; -} \ No newline at end of file +} diff --git a/packages/types/src/shell/model/node.ts b/packages/types/src/shell/model/node.ts index 9d8cec364..1a964c952 100644 --- a/packages/types/src/shell/model/node.ts +++ b/packages/types/src/shell/model/node.ts @@ -369,10 +369,10 @@ export interface IBaseModelNode< * @param useMutator */ insertBefore( - node: Node, - ref?: Node | undefined, - useMutator?: boolean, - ): void; + node: Node, + ref?: Node | undefined, + useMutator?: boolean, + ): void; /** * 在指定位置之后插入一个节点 @@ -382,10 +382,10 @@ export interface IBaseModelNode< * @param useMutator */ insertAfter( - node: Node, - ref?: Node | undefined, - useMutator?: boolean, - ): void; + node: Node, + ref?: Node | undefined, + useMutator?: boolean, + ): void; /** * 替换指定节点 @@ -504,4 +504,4 @@ export interface IBaseModelNode< }; } -export interface IPublicModelNode extends IBaseModelNode<IPublicModelDocumentModel, IPublicModelNode> {} \ No newline at end of file +export interface IPublicModelNode extends IBaseModelNode<IPublicModelDocumentModel, IPublicModelNode> {} diff --git a/packages/types/src/shell/model/props.ts b/packages/types/src/shell/model/props.ts index f3ef2e451..07b57a78c 100644 --- a/packages/types/src/shell/model/props.ts +++ b/packages/types/src/shell/model/props.ts @@ -86,4 +86,4 @@ export interface IBaseModelProps< } -export interface IPublicModelProps extends IBaseModelProps<IPublicModelProp> {}; \ No newline at end of file +export interface IPublicModelProps extends IBaseModelProps<IPublicModelProp> {} diff --git a/packages/types/src/shell/model/scroller.ts b/packages/types/src/shell/model/scroller.ts index 7c1a43840..22a57b6fd 100644 --- a/packages/types/src/shell/model/scroller.ts +++ b/packages/types/src/shell/model/scroller.ts @@ -5,4 +5,4 @@ export interface IPublicModelScroller { cancel(): void; scrolling(point: { globalX: number; globalY: number }): void; -} \ No newline at end of file +} diff --git a/packages/types/src/shell/model/setting-field.ts b/packages/types/src/shell/model/setting-field.ts index a011fc21f..06d8375f6 100644 --- a/packages/types/src/shell/model/setting-field.ts +++ b/packages/types/src/shell/model/setting-field.ts @@ -195,4 +195,4 @@ export interface IPublicModelSettingField extends IBaseModelSettingField< IPublicModelNode > { -} \ No newline at end of file +} diff --git a/packages/types/src/shell/model/setting-prop-entry.ts b/packages/types/src/shell/model/setting-prop-entry.ts index b40eab8bf..eb4ca0144 100644 --- a/packages/types/src/shell/model/setting-prop-entry.ts +++ b/packages/types/src/shell/model/setting-prop-entry.ts @@ -3,4 +3,4 @@ import { IPublicModelSettingField } from './'; /** * @deprecated please use IPublicModelSettingField */ -export type IPublicModelSettingPropEntry = IPublicModelSettingField +export type IPublicModelSettingPropEntry = IPublicModelSettingField; diff --git a/packages/types/src/shell/model/skeleton-item.ts b/packages/types/src/shell/model/skeleton-item.ts index beb18f222..55d1c2a24 100644 --- a/packages/types/src/shell/model/skeleton-item.ts +++ b/packages/types/src/shell/model/skeleton-item.ts @@ -18,4 +18,4 @@ export interface IPublicModelSkeletonItem { * @since v1.1.10 */ toggle(): void; -} \ No newline at end of file +} diff --git a/packages/types/src/shell/model/window.ts b/packages/types/src/shell/model/window.ts index 95ab738bc..ea9ec90c5 100644 --- a/packages/types/src/shell/model/window.ts +++ b/packages/types/src/shell/model/window.ts @@ -48,4 +48,4 @@ export interface IPublicModelWindow< * @since 1.1.7 */ onSave(fn: () => void): IPublicTypeDisposable; -} \ No newline at end of file +} diff --git a/packages/types/src/shell/type/advanced.ts b/packages/types/src/shell/type/advanced.ts index 8a6db85b6..c87613a65 100644 --- a/packages/types/src/shell/type/advanced.ts +++ b/packages/types/src/shell/type/advanced.ts @@ -37,7 +37,7 @@ export interface IPublicTypeAdvanced { propTarget?: string; appearOn?: 'mouse-enter' | 'mouse-hover' | 'selected' | 'always'; }> | - ReactElement[]); + ReactElement[]); /** * @deprecated 用于动态初始化拖拽到设计器里的组件的 prop 的值 diff --git a/packages/types/src/shell/type/command.ts b/packages/types/src/shell/type/command.ts index 0f301bd65..1bda10116 100644 --- a/packages/types/src/shell/type/command.ts +++ b/packages/types/src/shell/type/command.ts @@ -56,4 +56,4 @@ export interface IPublicTypeCommand { } export interface IPublicTypeListCommand extends Pick<IPublicTypeCommand, 'name' | 'description' | 'parameters'> { -} \ No newline at end of file +} diff --git a/packages/types/src/shell/type/component-instance.ts b/packages/types/src/shell/type/component-instance.ts index 4c3716f5d..bf7a8c040 100644 --- a/packages/types/src/shell/type/component-instance.ts +++ b/packages/types/src/shell/type/component-instance.ts @@ -3,4 +3,4 @@ import { Component as ReactComponent } from 'react'; /** * 组件实例定义 */ -export type IPublicTypeComponentInstance = Element | ReactComponent<any> | object; \ No newline at end of file +export type IPublicTypeComponentInstance = Element | ReactComponent<any> | object; diff --git a/packages/types/src/shell/type/context-menu.ts b/packages/types/src/shell/type/context-menu.ts index 8b58284f2..608e657aa 100644 --- a/packages/types/src/shell/type/context-menu.ts +++ b/packages/types/src/shell/type/context-menu.ts @@ -47,8 +47,8 @@ export interface IPublicTypeContextMenuAction { items?: | Omit<IPublicTypeContextMenuAction, 'items'>[] | (( - nodes?: IPublicModelNode[], - ) => Omit<IPublicTypeContextMenuAction, 'items'>[]); + nodes?: IPublicModelNode[], + ) => Omit<IPublicTypeContextMenuAction, 'items'>[]); /** * 显示条件函数 diff --git a/packages/types/src/shell/type/disposable.ts b/packages/types/src/shell/type/disposable.ts index aa0c2ac4d..7aaaeb7a0 100644 --- a/packages/types/src/shell/type/disposable.ts +++ b/packages/types/src/shell/type/disposable.ts @@ -1,3 +1,3 @@ export interface IPublicTypeDisposable { (): void; -} \ No newline at end of file +} diff --git a/packages/types/src/shell/type/editor-view-config.ts b/packages/types/src/shell/type/editor-view-config.ts index 9bb3b7555..701a600fb 100644 --- a/packages/types/src/shell/type/editor-view-config.ts +++ b/packages/types/src/shell/type/editor-view-config.ts @@ -8,4 +8,4 @@ export interface IPublicEditorViewConfig { /** viewType 类型为 'webview' 时渲染的地址 */ url?: () => Promise<string>; -} \ No newline at end of file +} diff --git a/packages/types/src/shell/type/editor-view.ts b/packages/types/src/shell/type/editor-view.ts index 2357a48f5..e05f8be00 100644 --- a/packages/types/src/shell/type/editor-view.ts +++ b/packages/types/src/shell/type/editor-view.ts @@ -9,4 +9,4 @@ export interface IPublicTypeEditorView { viewType?: 'editor' | 'webview'; (ctx: any, options: any): IPublicEditorViewConfig; -} \ No newline at end of file +} diff --git a/packages/types/src/shell/type/engine-options.ts b/packages/types/src/shell/type/engine-options.ts index 8221c4089..fc4fdab5a 100644 --- a/packages/types/src/shell/type/engine-options.ts +++ b/packages/types/src/shell/type/engine-options.ts @@ -196,4 +196,4 @@ export interface IPublicTypeEngineOptions { */ export interface EngineOptions { -} \ No newline at end of file +} diff --git a/packages/types/src/shell/type/hotkey-callback-config.ts b/packages/types/src/shell/type/hotkey-callback-config.ts index 1903d6a84..cc4193612 100644 --- a/packages/types/src/shell/type/hotkey-callback-config.ts +++ b/packages/types/src/shell/type/hotkey-callback-config.ts @@ -7,4 +7,4 @@ export interface IPublicTypeHotkeyCallbackConfig { seq?: string; level?: number; combo?: string; -} \ No newline at end of file +} diff --git a/packages/types/src/shell/type/hotkey-callbacks.ts b/packages/types/src/shell/type/hotkey-callbacks.ts index 3fd80a480..d31b744d1 100644 --- a/packages/types/src/shell/type/hotkey-callbacks.ts +++ b/packages/types/src/shell/type/hotkey-callbacks.ts @@ -2,4 +2,4 @@ import { IPublicTypeHotkeyCallbackConfig } from './'; export interface IPublicTypeHotkeyCallbacks { [key: string]: IPublicTypeHotkeyCallbackConfig[]; -} \ No newline at end of file +} diff --git a/packages/types/src/shell/type/location.ts b/packages/types/src/shell/type/location.ts index 4f8b59a7c..8a60c6870 100644 --- a/packages/types/src/shell/type/location.ts +++ b/packages/types/src/shell/type/location.ts @@ -53,4 +53,4 @@ export interface IPublicTypeLocationData< detail: IPublicTypeLocationDetail; source: string; event: IPublicModelLocateEvent; -} \ No newline at end of file +} diff --git a/packages/types/src/shell/type/plugin.ts b/packages/types/src/shell/type/plugin.ts index f5d7b81e5..6f75de65d 100644 --- a/packages/types/src/shell/type/plugin.ts +++ b/packages/types/src/shell/type/plugin.ts @@ -4,4 +4,4 @@ import { IPublicTypePluginMeta, IPublicTypePluginCreater } from './'; export interface IPublicTypePlugin extends IPublicTypePluginCreater { pluginName: string; meta?: IPublicTypePluginMeta; -} \ No newline at end of file +} diff --git a/packages/types/src/shell/type/resource-list.ts b/packages/types/src/shell/type/resource-list.ts index 1d7c34232..543bb14d5 100644 --- a/packages/types/src/shell/type/resource-list.ts +++ b/packages/types/src/shell/type/resource-list.ts @@ -34,4 +34,4 @@ export interface IPublicResourceData { children?: IPublicResourceData[]; } -export type IPublicResourceList = IPublicResourceData[]; \ No newline at end of file +export type IPublicResourceList = IPublicResourceData[]; diff --git a/packages/types/src/shell/type/resource-type.ts b/packages/types/src/shell/type/resource-type.ts index 7d64a4463..05dc135b7 100644 --- a/packages/types/src/shell/type/resource-type.ts +++ b/packages/types/src/shell/type/resource-type.ts @@ -7,4 +7,4 @@ export interface IPublicTypeResourceType { resourceType: 'editor' | 'webview' | string; (ctx: IPublicModelPluginContext, options: Object): IPublicResourceTypeConfig; -} \ No newline at end of file +} diff --git a/packages/types/src/shell/type/value-type.ts b/packages/types/src/shell/type/value-type.ts index 16fb789a2..09aa2d04d 100644 --- a/packages/types/src/shell/type/value-type.ts +++ b/packages/types/src/shell/type/value-type.ts @@ -133,4 +133,4 @@ export interface IPublicTypeJSONObject { export type IPublicTypeCompositeArray = IPublicTypeCompositeValue[]; export interface IPublicTypeCompositeObject<T = IPublicTypeCompositeValue> { [key: string]: IPublicTypeCompositeValue | T; -} \ No newline at end of file +} diff --git a/packages/utils/src/check-types/index.ts b/packages/utils/src/check-types/index.ts index 507259b2c..8db11580d 100644 --- a/packages/utils/src/check-types/index.ts +++ b/packages/utils/src/check-types/index.ts @@ -25,4 +25,4 @@ export * from './is-lowcode-component-type'; export * from './is-lowcode-project-schema'; export * from './is-component-schema'; export * from './is-basic-prop-type'; -export * from './is-required-prop-type'; \ No newline at end of file +export * from './is-required-prop-type'; diff --git a/packages/utils/src/check-types/is-basic-prop-type.ts b/packages/utils/src/check-types/is-basic-prop-type.ts index fd3b1b1dc..5b069fe7f 100644 --- a/packages/utils/src/check-types/is-basic-prop-type.ts +++ b/packages/utils/src/check-types/is-basic-prop-type.ts @@ -5,4 +5,4 @@ export function isBasicPropType(propType: IPublicTypePropType): propType is IPub return false; } return typeof propType === 'string'; -} \ No newline at end of file +} diff --git a/packages/utils/src/check-types/is-component-schema.ts b/packages/utils/src/check-types/is-component-schema.ts index 508d153b9..fc20c2b8d 100644 --- a/packages/utils/src/check-types/is-component-schema.ts +++ b/packages/utils/src/check-types/is-component-schema.ts @@ -1,8 +1,8 @@ -import { IPublicTypeComponentSchema } from "@alilc/lowcode-types"; +import { IPublicTypeComponentSchema } from '@alilc/lowcode-types'; export function isComponentSchema(schema: any): schema is IPublicTypeComponentSchema { if (typeof schema === 'object') { return schema.componentName === 'Component'; } - return false + return false; } diff --git a/packages/utils/src/check-types/is-drag-any-object.ts b/packages/utils/src/check-types/is-drag-any-object.ts index 8711b4e33..8186b6a97 100644 --- a/packages/utils/src/check-types/is-drag-any-object.ts +++ b/packages/utils/src/check-types/is-drag-any-object.ts @@ -6,4 +6,4 @@ export function isDragAnyObject(obj: any): boolean { return false; } return obj.type !== IPublicEnumDragObjectType.NodeData && obj.type !== IPublicEnumDragObjectType.Node; -} \ No newline at end of file +} diff --git a/packages/utils/src/check-types/is-drag-node-data-object.ts b/packages/utils/src/check-types/is-drag-node-data-object.ts index aa62f5b1c..f427505e8 100644 --- a/packages/utils/src/check-types/is-drag-node-data-object.ts +++ b/packages/utils/src/check-types/is-drag-node-data-object.ts @@ -6,4 +6,4 @@ export function isDragNodeDataObject(obj: any): obj is IPublicTypeDragNodeDataOb return false; } return obj.type === IPublicEnumDragObjectType.NodeData; -} \ No newline at end of file +} diff --git a/packages/utils/src/check-types/is-drag-node-object.ts b/packages/utils/src/check-types/is-drag-node-object.ts index 3a29ec967..28350f123 100644 --- a/packages/utils/src/check-types/is-drag-node-object.ts +++ b/packages/utils/src/check-types/is-drag-node-object.ts @@ -6,4 +6,4 @@ export function isDragNodeObject<Node = IPublicModelNode>(obj: any): obj is IPub return false; } return obj.type === IPublicEnumDragObjectType.Node; -} \ No newline at end of file +} diff --git a/packages/utils/src/check-types/is-function.ts b/packages/utils/src/check-types/is-function.ts index d7d3b4c27..3f6f9a06b 100644 --- a/packages/utils/src/check-types/is-function.ts +++ b/packages/utils/src/check-types/is-function.ts @@ -1,3 +1,3 @@ export function isFunction(obj: any): obj is Function { return obj && typeof obj === 'function'; -} \ No newline at end of file +} diff --git a/packages/utils/src/check-types/is-location-children-detail.ts b/packages/utils/src/check-types/is-location-children-detail.ts index cc093c4e4..a0b177988 100644 --- a/packages/utils/src/check-types/is-location-children-detail.ts +++ b/packages/utils/src/check-types/is-location-children-detail.ts @@ -6,4 +6,4 @@ export function isLocationChildrenDetail(obj: any): obj is IPublicTypeLocationCh return false; } return obj.type === IPublicTypeLocationDetailType.Children; -} \ No newline at end of file +} diff --git a/packages/utils/src/check-types/is-location-data.ts b/packages/utils/src/check-types/is-location-data.ts index dabd493fa..000735abc 100644 --- a/packages/utils/src/check-types/is-location-data.ts +++ b/packages/utils/src/check-types/is-location-data.ts @@ -6,4 +6,4 @@ export function isLocationData(obj: any): obj is IPublicTypeLocationData { return false; } return 'target' in obj && 'detail' in obj; -} \ No newline at end of file +} diff --git a/packages/utils/src/check-types/is-node.ts b/packages/utils/src/check-types/is-node.ts index b4690ddff..a12a1775a 100644 --- a/packages/utils/src/check-types/is-node.ts +++ b/packages/utils/src/check-types/is-node.ts @@ -6,4 +6,4 @@ export function isNode<Node = IPublicModelNode>(node: any): node is Node { return false; } return node.isNode; -} \ No newline at end of file +} diff --git a/packages/utils/src/check-types/is-object.ts b/packages/utils/src/check-types/is-object.ts index 56ceb7d97..54fb9b2ae 100644 --- a/packages/utils/src/check-types/is-object.ts +++ b/packages/utils/src/check-types/is-object.ts @@ -1,3 +1,3 @@ export function isObject(obj: any): boolean { return obj && typeof obj === 'object'; -} \ No newline at end of file +} diff --git a/packages/utils/src/check-types/is-required-prop-type.ts b/packages/utils/src/check-types/is-required-prop-type.ts index 106da78a0..b5fc10e76 100644 --- a/packages/utils/src/check-types/is-required-prop-type.ts +++ b/packages/utils/src/check-types/is-required-prop-type.ts @@ -5,4 +5,4 @@ export function isRequiredPropType(propType: IPublicTypePropType): propType is I return false; } return typeof propType === 'object' && propType.type && ['array', 'bool', 'func', 'number', 'object', 'string', 'node', 'element', 'any'].includes(propType.type); -} \ No newline at end of file +} diff --git a/packages/utils/src/create-content.ts b/packages/utils/src/create-content.ts index 09a368d2b..71f53a681 100644 --- a/packages/utils/src/create-content.ts +++ b/packages/utils/src/create-content.ts @@ -2,9 +2,9 @@ import { ReactNode, ComponentType, isValidElement, cloneElement, createElement } import { isReactComponent } from './is-react'; export function createContent( - content: ReactNode | ComponentType<any>, - props?: Record<string, unknown>, - ): ReactNode { + content: ReactNode | ComponentType<any>, + props?: Record<string, unknown>, +): ReactNode { if (isValidElement(content)) { return props ? cloneElement(content, props) : content; } diff --git a/packages/utils/src/css-helper.ts b/packages/utils/src/css-helper.ts index 2bd6db0d1..fed0d14a3 100644 --- a/packages/utils/src/css-helper.ts +++ b/packages/utils/src/css-helper.ts @@ -163,13 +163,13 @@ function cssToRuntime(css: string) { res[2] .split(';') .reduce<string[]>((prev, next) => { - if (next.indexOf('base64') > -1) { - prev[prev.length - 1] += `;${next}`; - } else { - prev.push(next); - } - return prev; - }, []) + if (next.indexOf('base64') > -1) { + prev[prev.length - 1] += `;${next}`; + } else { + prev.push(next); + } + return prev; + }, []) .forEach((item) => { if (item) { if (PROPS_REG.test(item)) { diff --git a/packages/utils/src/is-shaken.ts b/packages/utils/src/is-shaken.ts index 6c4606e71..088e8ce4a 100644 --- a/packages/utils/src/is-shaken.ts +++ b/packages/utils/src/is-shaken.ts @@ -12,4 +12,4 @@ export function isShaken(e1: MouseEvent | DragEvent, e2: MouseEvent | DragEvent) return ( Math.pow(e1.clientY - e2.clientY, 2) + Math.pow(e1.clientX - e2.clientX, 2) > SHAKE_DISTANCE ); -} \ No newline at end of file +} diff --git a/packages/utils/src/logger.ts b/packages/utils/src/logger.ts index 3eb43eedb..c188cde51 100644 --- a/packages/utils/src/logger.ts +++ b/packages/utils/src/logger.ts @@ -76,11 +76,11 @@ const outputFunction: Record<string, any> = { const bizNameColorConfig: Record<string, string> = {}; const shouldOutput = ( - logLevel: string, - targetLevel: string = 'warn', - bizName: string, - targetBizName: string, - ): boolean => { + logLevel: string, + targetLevel: string = 'warn', + bizName: string, + targetBizName: string, +): boolean => { const isLevelFit = (levels as any)[targetLevel] <= (levels as any)[logLevel]; const isBizNameFit = targetBizName === '*' || bizName.indexOf(targetBizName) > -1; return isLevelFit && isBizNameFit; diff --git a/packages/utils/src/node-helper.ts b/packages/utils/src/node-helper.ts index 60102d679..438983b3b 100644 --- a/packages/utils/src/node-helper.ts +++ b/packages/utils/src/node-helper.ts @@ -5,7 +5,7 @@ import { MouseEvent } from 'react'; export const getClosestNode = <Node extends IPublicModelNode = IPublicModelNode>( node: Node, until: (n: Node) => boolean, - ): Node | undefined => { +): Node | undefined => { if (!node) { return undefined; } diff --git a/packages/utils/src/schema.ts b/packages/utils/src/schema.ts index dfeaf4b71..27459440b 100644 --- a/packages/utils/src/schema.ts +++ b/packages/utils/src/schema.ts @@ -103,7 +103,7 @@ export function getNodeSchemaById( function getNodeSchemaFromPropsById(props: any, nodeId: string): IPublicTypeNodeSchema | undefined { let found: IPublicTypeNodeSchema | undefined; - for (const [_key, value] of Object.entries(props)) { + for (const [, value] of Object.entries(props)) { if (isJSSlot(value)) { // value 是数组类型 { type: 'JSSlot', value: IPublicTypeNodeSchema[] } if (Array.isArray(value.value)) { @@ -130,7 +130,7 @@ export function applyActivities( pivotSchema: IPublicTypeRootSchema, activities: any, ): IPublicTypeRootSchema { - let schema = { ...pivotSchema }; + const schema = { ...pivotSchema }; if (!Array.isArray(activities)) { activities = [activities]; } diff --git a/playground/engine/index.html b/playground/engine/index.html index b85032995..99142d85c 100644 --- a/playground/engine/index.html +++ b/playground/engine/index.html @@ -4,12 +4,28 @@ <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Playground + + + +
- - + + + + + + + + + + + + + + diff --git a/playground/engine/src/index.css b/playground/engine/src/index.css index 7c1abc1e3..1e14fa263 100644 --- a/playground/engine/src/index.css +++ b/playground/engine/src/index.css @@ -6,7 +6,7 @@ body * { box-sizing: border-box; } -body, #lce-container { +body, #app { position: fixed; left: 0; right: 0; diff --git a/playground/engine/src/index.ts b/playground/engine/src/index.ts index 728abfd0b..e65be4fab 100644 --- a/playground/engine/src/index.ts +++ b/playground/engine/src/index.ts @@ -1,12 +1,44 @@ -import { init } from '@alilc/lowcode-engine'; +import { init, plugins } from '@alilc/lowcode-engine'; +import EditorInitPlugin from './plugins/plugin-editor-init'; +import '@alilc/lowcode-engine/dist/style.css'; import './index.css'; -init(document.getElementById('app')!, { - locale: 'zh-CN', - enableCondition: true, - enableCanvasLock: true, - // 默认绑定变量 - supportVariableGlobally: true, - requestHandlersMap: {}, -}); +async function run() { + await plugins.register(EditorInitPlugin, { + scenarioName: 'general', + displayName: '综合场景', + info: { + urls: [ + { + key: '设计器', + value: 'https://github.com/alibaba/lowcode-demo/tree/main/demo-general', + }, + { + key: 'fusion-ui 物料', + value: 'https://github.com/alibaba/lowcode-materials/tree/main/packages/fusion-ui', + }, + { + key: 'fusion 物料', + value: 'https://github.com/alibaba/lowcode-materials/tree/main/packages/fusion-lowcode-materials', + } + ], + }, + }); + + await init(document.getElementById('app')!, { + locale: 'zh-CN', + enableCondition: true, + enableCanvasLock: true, + // 默认绑定变量 + supportVariableGlobally: true, + requestHandlersMap: {}, + simulatorUrl: [ + 'https://alifd.alicdn.com/npm/@alilc/lowcode-react-simulator-renderer@1.1.1/dist/css/react-simulator-renderer.css', + 'https://alifd.alicdn.com/npm/@alilc/lowcode-react-simulator-renderer@1.1.1/dist/js/react-simulator-renderer.js' + ], + enableContextMenu: true, + }); +} + +run() diff --git a/playground/engine/src/plugins/plugin-editor-init/index.tsx b/playground/engine/src/plugins/plugin-editor-init/index.tsx new file mode 100644 index 000000000..dcbb6e02f --- /dev/null +++ b/playground/engine/src/plugins/plugin-editor-init/index.tsx @@ -0,0 +1,49 @@ +import { IPublicModelPluginContext } from '@alilc/lowcode-types'; +import assets from '../../services/assets.json'; +import { getProjectSchema } from '../../services/mockService'; + +const EditorInitPlugin = (ctx: IPublicModelPluginContext, options: any) => { + return { + async init() { + const { material, project, config } = ctx; + const scenarioName = options['scenarioName']; + const scenarioDisplayName = options['displayName'] || scenarioName; + const scenarioInfo = options['info'] || {}; + // 保存在 config 中用于引擎范围其他插件使用 + config.set('scenarioName', scenarioName); + config.set('scenarioDisplayName', scenarioDisplayName); + config.set('scenarioInfo', scenarioInfo); + + // 设置物料描述 + await material.setAssets(assets as any); + + const schema = await getProjectSchema(scenarioName); + // 加载 schema + project.importSchema(schema as any); + }, + }; +} +EditorInitPlugin.pluginName = 'EditorInitPlugin'; +EditorInitPlugin.meta = { + preferenceDeclaration: { + title: '保存插件配置', + properties: [ + { + key: 'scenarioName', + type: 'string', + description: '用于localstorage存储key', + }, + { + key: 'displayName', + type: 'string', + description: '用于显示的场景名', + }, + { + key: 'info', + type: 'object', + description: '用于扩展信息', + } + ], + }, +}; +export default EditorInitPlugin; \ No newline at end of file diff --git a/playground/engine/src/services/assets.json b/playground/engine/src/services/assets.json new file mode 100644 index 000000000..ce841fbcd --- /dev/null +++ b/playground/engine/src/services/assets.json @@ -0,0 +1,140 @@ +{ + "packages": [ + { + "package": "moment", + "version": "2.24.0", + "urls": [ + "https://g.alicdn.com/mylib/moment/2.24.0/min/moment.min.js" + ], + "library": "moment" + }, + { + "package": "lodash", + "library": "_", + "urls": [ + "https://g.alicdn.com/platform/c/lodash/4.6.1/lodash.min.js" + ] + }, + { + "title": "fusion组件库", + "package": "@alifd/next", + "version": "1.26.4", + "urls": [ + "https://g.alicdn.com/code/lib/alifd__next/1.26.4/next.min.css", + "https://g.alicdn.com/code/lib/alifd__next/1.26.4/next-with-locales.min.js" + ], + "library": "Next" + }, + { + "title": "NextTable", + "package": "NextTable", + "version": "1.0.1", + "urls": [ + "https://g.alicdn.com/fusion-platform/pro-table/1.0.1/next-table.js", + "https://g.alicdn.com/fusion-platform/pro-table/1.0.1/next-table.css" + ], + "library": "NextTable" + }, + { + "package": "@alilc/lowcode-materials", + "version": "1.0.7", + "library": "AlilcLowcodeMaterials", + "urls": [ + "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.7/dist/AlilcLowcodeMaterials.js", + "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.7/dist/AlilcLowcodeMaterials.css" + ], + "editUrls": [ + "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.7/build/lowcode/view.js", + "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.7/build/lowcode/view.css" + ] + }, + { + "package": "@alifd/layout", + "version": "2.4.1", + "library": "AlifdLayout", + "urls": [ + "https://alifd.alicdn.com/npm/@alifd/layout@2.4.1/dist/AlifdLayout.js", + "https://alifd.alicdn.com/npm/@alifd/layout@2.4.1/dist/AlifdLayout.css" + ], + "editUrls": [ + "https://alifd.alicdn.com/npm/@alifd/layout@2.4.1/build/lowcode/view.js", + "https://alifd.alicdn.com/npm/@alifd/layout@2.4.1/build/lowcode/view.css" + ] + }, + { + "package": "@alifd/fusion-ui", + "version": "2.0.2", + "library": "AlifdFusionUi", + "urls": [ + "https://alifd.alicdn.com/npm/@alifd/fusion-ui@2.0.2/dist/AlifdFusionUi.js", + "https://alifd.alicdn.com/npm/@alifd/fusion-ui@2.0.2/dist/AlifdFusionUi.css" + ], + "editUrls": [ + "https://alifd.alicdn.com/npm/@alifd/fusion-ui@2.0.2/build/lowcode/view.js", + "https://alifd.alicdn.com/npm/@alifd/fusion-ui@2.0.2/build/lowcode/view.css" + ] + } + ], + "components": [ + { + "exportName": "AlilcLowcodeMaterialsMeta", + "npm": { + "package": "@alilc/lowcode-materials" + }, + "url": "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.7/build/lowcode/meta.js", + "urls": { + "default": "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.7/build/lowcode/meta.js", + "design": "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.7/build/lowcode/meta.design.js" + } + }, + { + "exportName": "AlifdLayoutMeta", + "npm": { + "package": "@alifd/layout", + "version": "2.4.1" + }, + "url": "https://alifd.alicdn.com/npm/@alifd/layout@2.4.1/build/lowcode/meta.js", + "urls": { + "default": "https://alifd.alicdn.com/npm/@alifd/layout@2.4.1/build/lowcode/meta.js" + } + }, + { + "exportName": "AlifdFusionUiMeta", + "npm": { + "package": "@alifd/fusion-ui" + }, + "url": "https://alifd.alicdn.com/npm/@alifd/fusion-ui@2.0.2/build/lowcode/meta.js", + "urls": { + "default": "https://alifd.alicdn.com/npm/@alifd/fusion-ui@2.0.2/build/lowcode/meta.js", + "design": "https://alifd.alicdn.com/npm/@alifd/fusion-ui@2.0.2/build/lowcode/meta.design.js" + } + } + ], + "sort": { + "groupList": [ + "精选组件", + "原子组件", + "低代码组件" + ], + "categoryList": [ + "基础元素", + "布局容器类", + "表格类", + "表单详情类", + "帮助类", + "对话框类", + "业务类", + "通用", + "引导", + "信息输入", + "信息展示", + "信息反馈" + ] + }, + "groupList": [ + "精选组件", + "原子组件", + "低代码组件" + ], + "ignoreComponents": {} +} diff --git a/playground/engine/src/services/defaultI18nSchema.json b/playground/engine/src/services/defaultI18nSchema.json new file mode 100644 index 000000000..0490ac8db --- /dev/null +++ b/playground/engine/src/services/defaultI18nSchema.json @@ -0,0 +1,10 @@ +{ + "zh-CN": { + "i18n-jwg27yo4": "你好 ", + "i18n-jwg27yo3": "{name} 博士" + }, + "en-US": { + "i18n-jwg27yo4": "Hello ", + "i18n-jwg27yo3": "Doctor {name}" + } +} \ No newline at end of file diff --git a/playground/engine/src/services/defaultPageSchema.json b/playground/engine/src/services/defaultPageSchema.json new file mode 100644 index 000000000..3dc1a53ed --- /dev/null +++ b/playground/engine/src/services/defaultPageSchema.json @@ -0,0 +1,580 @@ +{ + "componentName": "Page", + "id": "node_dockcviv8fo1", + "props": { + "ref": "outerView", + "style": { + "height": "100%" + } + }, + "docId": "doclaqkk3b9", + "fileName": "/", + "dataSource": { + "list": [ + { + "type": "fetch", + "isInit": true, + "options": { + "params": {}, + "method": "GET", + "isCors": true, + "timeout": 5000, + "headers": {}, + "uri": "mock/info.json" + }, + "id": "info", + "shouldFetch": { + "type": "JSFunction", + "value": "function() { \n console.log('should fetch.....');\n return true; \n}" + } + } + ] + }, + "state": { + "text": { + "type": "JSExpression", + "value": "\"outer\"" + }, + "isShowDialog": { + "type": "JSExpression", + "value": "false" + } + }, + "css": "body {\n font-size: 12px;\n}\n\n.button {\n width: 100px;\n color: #ff00ff\n}", + "lifeCycles": { + "componentDidMount": { + "type": "JSFunction", + "value": "function componentDidMount() {\n console.log('did mount');\n}" + }, + "componentWillUnmount": { + "type": "JSFunction", + "value": "function componentWillUnmount() {\n console.log('will unmount');\n}" + } + }, + "methods": { + "testFunc": { + "type": "JSFunction", + "value": "function testFunc() {\n console.log('test func');\n}" + }, + "onClick": { + "type": "JSFunction", + "value": "function onClick() {\n this.setState({\n isShowDialog: true\n });\n}" + }, + "closeDialog": { + "type": "JSFunction", + "value": "function closeDialog() {\n this.setState({\n isShowDialog: false\n });\n}" + }, + "getHelloWorldText": { + "type": "JSFunction", + "value": "function getHelloWorldText() {\n return this.i18n('i18n-jwg27yo4');\n}" + }, + "getHelloWorldText2": { + "type": "JSFunction", + "value": "function getHelloWorldText2() {\n return this.i18n('i18n-jwg27yo3', {\n name: '絮黎'\n });\n}" + }, + "onTestConstantsButtonClicked": { + "type": "JSFunction", + "value": "function onTestConstantsButtonClicked() {\n console.log('constants.ConstantA:', this.constants.ConstantA);\n console.log('constants.ConstantB:', this.constants.ConstantB);\n}" + }, + "onTestUtilsButtonClicked": { + "type": "JSFunction", + "value": "function onTestUtilsButtonClicked() {\n this.utils.demoUtil('param1', 'param2');\n}" + } + }, + "originCode": "class LowcodeComponent extends Component {\n state = {\n \"text\": \"outer\",\n \"isShowDialog\": false\n }\n componentDidMount() {\n console.log('did mount');\n }\n componentWillUnmount() {\n console.log('will unmount');\n }\n testFunc() {\n console.log('test func');\n }\n onClick() {\n this.setState({\n isShowDialog: true\n });\n }\n closeDialog() {\n this.setState({\n isShowDialog: false\n });\n }\n getHelloWorldText() {\n return this.i18n('i18n-jwg27yo4');\n }\n getHelloWorldText2() {\n return this.i18n('i18n-jwg27yo3', {\n name: '絮黎',\n });\n }\n onTestConstantsButtonClicked() {\n console.log('constants.ConstantA:', this.constants.ConstantA);\n console.log('constants.ConstantB:', this.constants.ConstantB);\n\t}\n\tonTestUtilsButtonClicked(){\n this.utils.demoUtil('param1', 'param2');\n\t}\n}", + "hidden": false, + "title": "", + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "FDPage", + "id": "node_oclfjpfqjy5", + "props": { + "contentProps": { + "style": { + "background": "rgba(255,255,255,0)" + } + }, + "ref": "fdpage-bb43fbb0" + }, + "title": "页面", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "FDSection", + "id": "node_oclfjpfqjy6", + "props": { + "style": { + "backgroundColor": "rgba(255,255,255,1)", + "minHeight": "" + } + }, + "title": "区域", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "FDBlock", + "id": "node_oclfjpfqjy7", + "props": { + "mode": "transparent", + "span": 12 + }, + "title": "区块", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "FDCell", + "id": "node_oclfjpfqjy8", + "props": { + "align": "left", + "verAlign": "top", + "style": { + "backgroundColor": "rgba(255,255,255,1)" + }, + "width": "" + }, + "title": "容器", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "FDP", + "id": "node_oclfjpfqjy10", + "props": {}, + "title": "段落", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "NextText", + "id": "node_oclfjpfqjyz", + "props": { + "type": "h1", + "children": "Home", + "mark": false, + "code": false, + "delete": false, + "underline": false, + "strong": false, + "prefix": "", + "classname": "", + "style": { + "fontSize": "25px" + } + }, + "hidden": false, + "title": "", + "isLocked": false, + "condition": true, + "conditionGroup": "" + } + ] + } + ] + } + ] + }, + { + "componentName": "FDBlock", + "id": "node_oclfjpfqjy9", + "props": { + "mode": "transparent", + "span": 12, + "style": { + "backgroundColor": "rgba(255,255,255,1)", + "minHeight": "" + } + }, + "title": "区块", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "FDRow", + "id": "node_oclfjpfqjy11", + "props": { + "style": { + "backgroundColor": "rgba(255,255,255,1)" + } + }, + "title": "行容器", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "FDCell", + "id": "node_oclfjpfqjya", + "props": { + "align": "left", + "verAlign": "top", + "style": { + "backgroundColor": "rgba(255,255,255,1)" + }, + "width": "" + }, + "title": "容器", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "FDP", + "id": "node_oclfjqcdwn14", + "props": {}, + "title": "段落", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "NextText", + "id": "node_oclfjqcdwn13", + "props": { + "type": "h5", + "children": "多语言展示", + "mark": false, + "code": false, + "delete": false, + "underline": false, + "strong": false, + "prefix": "", + "classname": "", + "style": { + "fontSize": "18px" + } + }, + "hidden": false, + "title": "", + "isLocked": false, + "condition": true, + "conditionGroup": "" + } + ] + }, + { + "componentName": "FDP", + "id": "node_oclfjqcdwn2k", + "props": {}, + "title": "段落", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "NextText", + "id": "node_oclfjqcdwn2j", + "props": { + "type": "inherit", + "children": { + "type": "JSExpression", + "value": "this.getHelloWorldText()", + "mock": "" + }, + "mark": false, + "code": false, + "delete": false, + "underline": false, + "strong": false, + "prefix": "", + "classname": "" + }, + "hidden": false, + "title": "", + "isLocked": false, + "condition": true, + "conditionGroup": "" + }, + { + "componentName": "NextText", + "id": "node_oclfjqcf7z15", + "props": { + "type": "inherit", + "children": { + "type": "JSExpression", + "value": "this.getHelloWorldText2()", + "mock": "基于 Ali-Lowcode-Engine 快速打造高生产力的低代码研发平台, 基于自然布局体系快速搭建页面" + }, + "mark": false, + "code": false, + "delete": false, + "underline": false, + "strong": false, + "prefix": "", + "classname": "" + }, + "hidden": false, + "title": "", + "isLocked": false, + "condition": true, + "conditionGroup": "" + } + ] + } + ] + }, + { + "componentName": "FDCell", + "id": "node_oclfjpfqjy12", + "props": { + "align": "left", + "verAlign": "top", + "style": { + "backgroundColor": "rgba(255,255,255,1)" + } + }, + "title": "容器", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "FDP", + "id": "node_oclfjqcf7z2h", + "props": {}, + "title": "段落", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "NextText", + "id": "node_oclfjqcf7z2g", + "props": { + "type": "h5", + "children": "交互展示", + "mark": false, + "code": false, + "delete": false, + "underline": false, + "strong": false, + "prefix": "", + "classname": "", + "style": { + "fontSize": "18px" + } + }, + "hidden": false, + "title": "", + "isLocked": false, + "condition": true, + "conditionGroup": "" + } + ] + }, + { + "componentName": "FDP", + "id": "node_oclfjqcf7z2l", + "props": {}, + "title": "段落", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "Button", + "id": "node_oclfjqcf7z2k", + "props": { + "prefix": "next-", + "type": "primary", + "size": "medium", + "htmlType": "button", + "component": "button", + "children": "constants", + "iconSize": "xxs", + "loading": false, + "text": false, + "warning": false, + "disabled": false, + "ref": "button-4951c2d3", + "__events": { + "eventDataList": [ + { + "type": "componentEvent", + "name": "onClick", + "relatedEventName": "onTestConstantsButtonClicked" + } + ], + "eventList": [ + { + "name": "onClick", + "description": "点击按钮的回调\n@param {Object} e Event Object", + "disabled": true + }, + { + "name": "onMouseUp", + "disabled": false + } + ] + }, + "onClick": { + "type": "JSFunction", + "value": "function(){this.onTestConstantsButtonClicked.apply(this,Array.prototype.slice.call(arguments).concat([])) }" + } + }, + "docId": "doclawu71ac", + "hidden": false, + "title": "", + "isLocked": false, + "condition": true, + "conditionGroup": "" + }, + { + "componentName": "Button", + "id": "node_oclfjqcf7z2o", + "props": { + "prefix": "next-", + "type": "primary", + "size": "medium", + "htmlType": "button", + "component": "button", + "children": "utils", + "iconSize": "xxs", + "loading": false, + "text": false, + "warning": false, + "disabled": false, + "__events": { + "eventDataList": [ + { + "type": "componentEvent", + "name": "onClick", + "relatedEventName": "onTestUtilsButtonClicked" + } + ], + "eventList": [ + { + "name": "onClick", + "description": "点击按钮的回调\n@param {Object} e Event Object", + "disabled": true + }, + { + "name": "onMouseUp", + "disabled": false + } + ] + }, + "onClick": { + "type": "JSFunction", + "value": "function(){this.onTestUtilsButtonClicked.apply(this,Array.prototype.slice.call(arguments).concat([])) }" + } + }, + "docId": "doclawu71ac", + "hidden": false, + "title": "", + "isLocked": false, + "condition": true, + "conditionGroup": "" + } + ] + } + ] + } + ] + } + ] + }, + { + "componentName": "FDBlock", + "id": "node_oclfjqcf7z3g", + "props": { + "mode": "transparent", + "span": 12, + "style": { + "backgroundColor": "rgba(255,255,255,1)", + "minHeight": "" + } + }, + "title": "区块", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "FDCell", + "id": "node_oclfjqcf7z3h", + "props": { + "align": "left", + "verAlign": "top", + "style": { + "backgroundColor": "rgba(255,255,255,1)" + } + }, + "title": "容器", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "FDP", + "id": "node_oclfjqcf7z43", + "props": {}, + "title": "段落", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "NextText", + "id": "node_oclfjqcf7z42", + "props": { + "type": "inherit", + "children": "Powered By Lowcode Engine", + "mark": false, + "code": false, + "delete": false, + "underline": false, + "strong": false, + "prefix": "", + "classname": "", + "style": { + "height": "30px", + "lineHeight": "30px", + "fontSize": "20px" + } + }, + "hidden": false, + "title": "", + "isLocked": false, + "condition": true, + "conditionGroup": "" + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/playground/engine/src/services/mockService.ts b/playground/engine/src/services/mockService.ts new file mode 100644 index 000000000..b8fce277c --- /dev/null +++ b/playground/engine/src/services/mockService.ts @@ -0,0 +1,118 @@ +import { material, project } from '@alilc/lowcode-engine'; +// import { filterPackages } from '@alilc/lowcode-plugin-inject' +import { Message, Dialog } from '@alifd/next'; +import { IPublicTypeProjectSchema, IPublicEnumTransformStage } from '@alilc/lowcode-types'; +import DefaultPageSchema from './defaultPageSchema.json'; +import DefaultI18nSchema from './defaultI18nSchema.json'; + +const generateProjectSchema = (pageSchema: any, i18nSchema: any): IPublicTypeProjectSchema => { + return { + componentsTree: [pageSchema], + componentsMap: material.componentsMap as any, + version: '1.0.0', + i18n: i18nSchema, + }; +} + + +export const saveSchema = async (scenarioName: string = 'unknown') => { + setProjectSchemaToLocalStorage(scenarioName); + await setPackagesToLocalStorage(scenarioName); + Message.success('成功保存到本地'); +}; + +export const resetSchema = async (scenarioName: string = 'unknown') => { + try { + await new Promise((resolve, reject) => { + Dialog.confirm({ + content: '确定要重置吗?您所有的修改都将消失!', + onOk: () => { + resolve(); + }, + onCancel: () => { + reject() + }, + }) + }) + } catch(err) { + return; + } + const defaultSchema = generateProjectSchema(DefaultPageSchema, DefaultI18nSchema); + + project.importSchema(defaultSchema as any); + project.simulatorHost?.rerender(); + + setProjectSchemaToLocalStorage(scenarioName); + await setPackagesToLocalStorage(scenarioName); + Message.success('成功重置页面'); +} + +const getLSName = (scenarioName: string, ns: string = 'projectSchema') => `${scenarioName}:${ns}`; + +export const getProjectSchemaFromLocalStorage = (scenarioName: string) => { + if (!scenarioName) { + console.error('scenarioName is required!'); + return; + } + const localValue = window.localStorage.getItem(getLSName(scenarioName)); + if (localValue) { + return JSON.parse(localValue); + } + return undefined; +} + +const setProjectSchemaToLocalStorage = (scenarioName: string) => { + if (!scenarioName) { + console.error('scenarioName is required!'); + return; + } + window.localStorage.setItem( + getLSName(scenarioName), + JSON.stringify(project.exportSchema(IPublicEnumTransformStage.Save)) + ); +} + +const setPackagesToLocalStorage = async (scenarioName: string) => { + if (!scenarioName) { + console.error('scenarioName is required!'); + return; + } + // const packages = await filterPackages(material.getAssets().packages); + window.localStorage.setItem( + getLSName(scenarioName, 'packages'), + JSON.stringify({}), + ); +} + +export const getPackagesFromLocalStorage = (scenarioName: string) => { + if (!scenarioName) { + console.error('scenarioName is required!'); + return; + } + return JSON.parse(window.localStorage.getItem(getLSName(scenarioName, 'packages')) || '{}'); +} + +export const getProjectSchema = async (scenarioName: string = 'unknown') : Promise => { + const pageSchema = await getPageSchema(scenarioName); + return generateProjectSchema(pageSchema, DefaultI18nSchema); +}; + +export const getPageSchema = async (scenarioName: string = 'unknown') => { + const pageSchema = getProjectSchemaFromLocalStorage(scenarioName)?.componentsTree?.[0]; + if (pageSchema) { + return pageSchema; + } + + return DefaultPageSchema; +}; + +export const getPreviewLocale = (scenarioName: string) => { + const key = getLSName(scenarioName, 'previewLocale'); + return window.localStorage.getItem(key) || 'zh-CN'; +} + +export const setPreviewLocale = (scenarioName: string, locale: string) => { + const key = getLSName(scenarioName, 'previewLocale'); + window.localStorage.setItem(key, locale || 'zh-CN'); + window.location.reload(); +} diff --git a/playground/engine/src/services/schema.json b/playground/engine/src/services/schema.json new file mode 100644 index 000000000..81e6f002a --- /dev/null +++ b/playground/engine/src/services/schema.json @@ -0,0 +1,445 @@ +{ + "componentName": "Page", + "id": "node_dockcviv8fo1", + "docId": "doclaqkk3b9", + "props": { + "ref": "outerView", + "style": { + "height": "100%" + } + }, + "fileName": "/", + "dataSource": { + "list": [ + { + "type": "fetch", + "isInit": true, + "options": { + "params": {}, + "method": "GET", + "isCors": true, + "timeout": 5000, + "headers": {}, + "uri": "mock/info.json" + }, + "id": "info", + "shouldFetch": { + "type": "JSFunction", + "value": "function() { \n console.log('should fetch.....');\n return true; \n}" + } + } + ] + }, + "state": { + "text": { + "type": "JSExpression", + "value": "\"outer\"" + }, + "isShowDialog": { + "type": "JSExpression", + "value": "false" + } + }, + "css": "body {\n font-size: 12px;\n}\n\n.button {\n width: 100px;\n color: #ff00ff\n}", + "lifeCycles": { + "componentDidMount": { + "type": "JSFunction", + "value": "function componentDidMount() {\n console.log('did mount');\n}" + }, + "componentWillUnmount": { + "type": "JSFunction", + "value": "function componentWillUnmount() {\n console.log('will unmount');\n}" + } + }, + "methods": { + "testFunc": { + "type": "JSFunction", + "value": "function testFunc() {\n console.log('test func');\n}" + }, + "onClick": { + "type": "JSFunction", + "value": "function onClick() {\n this.setState({\n isShowDialog: true\n });\n}" + }, + "closeDialog": { + "type": "JSFunction", + "value": "function closeDialog() {\n this.setState({\n isShowDialog: false\n });\n}" + }, + "onClickTestConstants": { + "type": "JSFunction", + "value": "function onClickTestConstants() {\n console.log('this.constants.ConstantA', this.constants.ConstantA);\n console.log('this.constants.ConstantB', this.constants.ConstantB);\n}" + }, + "onClickTestUtils": { + "type": "JSFunction", + "value": "function onClickTestUtils() {\n this.utils.demoUtil('a', 'b');\n}" + } + }, + "originCode": "class LowcodeComponent extends Component {\n state = {\n \"text\": \"outer\",\n \"isShowDialog\": false\n }\n componentDidMount() {\n console.log('did mount');\n }\n componentWillUnmount() {\n console.log('will unmount');\n }\n testFunc() {\n console.log('test func');\n }\n onClick() {\n this.setState({\n isShowDialog: true\n })\n }\n closeDialog() {\n this.setState({\n isShowDialog: false\n })\n }\n\tonClickTestConstants(){\n console.log('this.constants.ConstantA', this.constants.ConstantA);\n console.log('this.constants.ConstantB', this.constants.ConstantB);\n }\n onClickTestUtils() {\n this.utils.demoUtil('a', 'b');\n }\n}", + "hidden": false, + "title": "", + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "NextPage", + "id": "node_ockzs2vw431", + "docId": "doclaqkk3b9", + "props": { + "headerDivider": true, + "minHeight": "100vh", + "presetNav": true, + "presetAside": true, + "footer": false, + "nav": false, + "aside": false, + "placeholderStyle": { + "gridRowEnd": "span 1", + "gridColumnEnd": "span 12" + }, + "headerProps": { + "background": "surface" + }, + "header": { + "type": "JSSlot", + "value": { + "componentName": "NextPageHeader", + "id": "node_ockzs2vw433", + "docId": "doclaqkk3b9", + "props": {}, + "title": "页面头部", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "NextRowColContainer", + "id": "node_ockzs2vw434", + "docId": "doclaqkk3b9", + "props": { + "rowGap": 20, + "colGap": 20 + }, + "title": "行列容器", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "NextRow", + "id": "node_ockzs2vw435", + "docId": "doclaqkk3b9", + "props": {}, + "title": "行", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "NextCol", + "id": "node_ockzs2vw436", + "docId": "doclaqkk3b9", + "props": { + "colSpan": 1 + }, + "title": "列", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "NextP", + "id": "node_ockzvfoetv17", + "docId": "dockzvfoetv", + "props": { + "wrap": false, + "type": "body2", + "verAlign": "middle", + "textSpacing": true, + "align": "left" + }, + "title": "段落", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "NextText", + "id": "node_ockzvfoetv18", + "docId": "dockzvfoetv", + "props": { + "type": "h5", + "children": { + "type": "JSExpression", + "value": "this.state.info?.info", + "mock": "标题标题" + }, + "mark": false, + "code": false, + "delete": false, + "underline": false, + "strong": false, + "prefix": "", + "classname": "", + "ref": "nexttext-3a39ea8b" + }, + "hidden": false, + "title": "", + "isLocked": false, + "condition": true, + "conditionGroup": "" + } + ] + } + ] + } + ] + } + ] + } + ] + } + }, + "isTab": false, + "contentAlignCenter": false, + "contentProps": { + "style": { + "background": "rgba(255,255,255,0)" + } + }, + "navProps": { + "width": 200 + }, + "asideProps": { + "width": 200 + }, + "background": "lining", + "ref": "nextpage-3cc814e7" + }, + "title": "页面", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "NextBlock", + "id": "node_oclat5fpb6ga", + "docId": "doclat87b8r", + "props": { + "placeholderStyle": { + "height": "100%" + }, + "noPadding": false, + "noBorder": false, + "title": "区域标题", + "rowGap": 20, + "colGap": 20, + "background": "surface", + "layoutmode": "O", + "strict": true, + "colSpan": 12, + "rowSpan": 1, + "mode": "transparent", + "childTotalColumns": 12 + }, + "title": "区域", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "NextBlockCell", + "id": "node_oclat5fpb6gb", + "docId": "doclat87b8r", + "props": { + "colSpan": 12, + "rowSpan": 1, + "mode": "procard", + "isAutoContainer": true, + "title": "区块标题", + "hasDivider": true, + "loading": false, + "hasCollapse": false, + "text": true, + "isFillContainer": true, + "operations": [] + }, + "hidden": false, + "title": "", + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "NextRowColContainer", + "id": "node_oclat5fpb6gc", + "docId": "doclat87b8r", + "props": { + "rowGap": 20, + "colGap": 20 + }, + "title": "行列容器", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "NextRow", + "id": "node_oclat5fpb6gd", + "docId": "doclat87b8r", + "props": {}, + "title": "行", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "NextCol", + "id": "node_oclat5fpb6ge", + "docId": "doclat87b8r", + "props": { + "colSpan": 1 + }, + "title": "列", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "NextP", + "id": "node_oclat5fpb6gf", + "docId": "doclat87b8r", + "props": { + "wrap": false, + "type": "body2", + "verAlign": "middle", + "textSpacing": true, + "align": "left" + }, + "title": "段落", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "Button", + "id": "node_oclat5fpb6gg", + "docId": "doclat5fpb6", + "props": { + "prefix": "next-", + "type": "primary", + "size": "medium", + "htmlType": "button", + "component": "button", + "children": "测试constants", + "iconSize": "xxs", + "loading": false, + "text": false, + "warning": false, + "disabled": false, + "__events": { + "eventDataList": [ + { + "type": "componentEvent", + "name": "onClick", + "relatedEventName": "onClickTestConstants" + } + ], + "eventList": [ + { + "name": "onClick", + "description": "点击按钮的回调\n@param {Object} e Event Object", + "disabled": true + }, + { + "name": "onMouseUp", + "disabled": false + } + ] + }, + "onClick": { + "type": "JSFunction", + "value": "function(){this.onClickTestConstants.apply(this,Array.prototype.slice.call(arguments).concat([])) }" + }, + "ghost": false + }, + "hidden": false, + "title": "", + "isLocked": false, + "condition": true, + "conditionGroup": "" + }, + { + "componentName": "Button", + "id": "node_oclat5fpb6gh", + "docId": "doclat5fpb6", + "props": { + "prefix": "next-", + "type": "primary", + "size": "medium", + "htmlType": "button", + "component": "button", + "children": "测试utils", + "iconSize": "xxs", + "loading": false, + "text": false, + "warning": false, + "disabled": false, + "ref": "button-0d20c188", + "__events": { + "eventDataList": [ + { + "type": "componentEvent", + "name": "onClick", + "relatedEventName": "onClickTestUtils" + } + ], + "eventList": [ + { + "name": "onClick", + "description": "点击按钮的回调\n@param {Object} e Event Object", + "disabled": true + }, + { + "name": "onMouseUp", + "disabled": false + } + ] + }, + "onClick": { + "type": "JSFunction", + "value": "function(){this.onClickTestUtils.apply(this,Array.prototype.slice.call(arguments).concat([])) }" + } + }, + "hidden": false, + "title": "", + "isLocked": false, + "condition": true, + "conditionGroup": "" + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/playground/package.json b/playground/package.json index 98bbc6b3b..ef32bc778 100644 --- a/playground/package.json +++ b/playground/package.json @@ -7,6 +7,16 @@ "dev": "vite" }, "dependencies": { - "@alilc/lowcode-engine": "workspace:*" + "@alilc/lowcode-types": "workspace:*", + "@alilc/lowcode-engine": "workspace:*", + "@alilc/lowcode-react-renderer": "workspace:*", + "@alifd/next": "^1.27.10", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@types/react": "^18.2.75", + "@types/react-dom": "^18.2.24", + "vite-plugin-external": "^4.3.0" } } diff --git a/playground/vite.config.ts b/playground/vite.config.ts index e47b0ea02..56a6f0e9b 100644 --- a/playground/vite.config.ts +++ b/playground/vite.config.ts @@ -1,5 +1,6 @@ import { defineConfig } from 'vite' import { resolve } from 'node:path' +import createExternal from 'vite-plugin-external' export default defineConfig({ build: { @@ -9,5 +10,14 @@ export default defineConfig({ renderer: resolve(import.meta.dirname, 'renderer/index.html') } } - } + }, + plugins: [ + createExternal({ + externals: { + react: 'React', + 'react-dom': 'ReactDOM', + '@alifd/next': 'Next' + } + }) + ] }) diff --git a/scripts/build.js b/scripts/build.js index 15df7a2c2..2fe36693e 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -7,6 +7,7 @@ const args = minimist(argv.slice(2)); const targets = args['_']; const formatArgs = args['formats']; const prod = args['prod'] || args['p']; +const buildTypes = args['types'] || args['t'] async function run() { const packages = await findWorkspacePackages(cwd()); @@ -18,9 +19,15 @@ async function run() { await execa('pnpm', ['--filter', finalName[0], 'build:target'], { stdio: 'inherit', env: { - FORMATS: !prod ? formatArgs : undefined, + FORMATS: formatArgs ? formatArgs : !prod ? 'es' : undefined, }, }); + + if (buildTypes) { + await execa('pnpm', ['--filter', finalName[0], 'build:dts'], { + stdio: 'inherit', + }); + } } run(); diff --git a/tsconfig.json b/tsconfig.json index 3aefccdb6..6854e940c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -36,7 +36,8 @@ // provide type friendly tips "paths": { "@alilc/lowcode-*": ["packages/*/src"] - } + }, + "types": ["vitest/globals", "node"] }, "exclude": ["**/dist", "node_modules"] } diff --git a/vitest.workspace.ts b/vitest.workspace.ts new file mode 100644 index 000000000..631a18210 --- /dev/null +++ b/vitest.workspace.ts @@ -0,0 +1,13 @@ +import { defineWorkspace } from 'vitest/config'; + +export default defineWorkspace([ + 'packages/*/vitest.config.{e2e,unit}.ts', + { + test: { + include: ['**/__tests__/**/*.spec.{ts?(x),js?(x)}'], + name: 'unit test', + environment: 'jsdom', + globals: true + } + }, +])