@nocobase/flow-engine 2.0.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/README.md +30 -0
- package/lib/ContextPathProxy.d.ts +17 -0
- package/lib/ContextPathProxy.js +65 -0
- package/lib/ElementProxy.d.ts +17 -0
- package/lib/ElementProxy.js +93 -0
- package/lib/FlowContextProvider.d.ts +24 -0
- package/lib/FlowContextProvider.js +82 -0
- package/lib/FlowDefinition.d.ts +423 -0
- package/lib/FlowDefinition.js +257 -0
- package/lib/JSRunner.d.ts +32 -0
- package/lib/JSRunner.js +95 -0
- package/lib/ReactView.d.ts +20 -0
- package/lib/ReactView.js +120 -0
- package/lib/ViewScopedFlowEngine.d.ts +23 -0
- package/lib/ViewScopedFlowEngine.js +81 -0
- package/lib/acl/Acl.d.ts +31 -0
- package/lib/acl/Acl.js +115 -0
- package/lib/action-registry/BaseActionRegistry.d.ts +23 -0
- package/lib/action-registry/BaseActionRegistry.js +57 -0
- package/lib/action-registry/EngineActionRegistry.d.ts +20 -0
- package/lib/action-registry/EngineActionRegistry.js +47 -0
- package/lib/action-registry/ModelActionRegistry.d.ts +34 -0
- package/lib/action-registry/ModelActionRegistry.js +79 -0
- package/lib/components/DynamicFlowsEditor.d.ts +17 -0
- package/lib/components/DynamicFlowsEditor.js +49 -0
- package/lib/components/FieldModelRenderer.d.ts +10 -0
- package/lib/components/FieldModelRenderer.js +94 -0
- package/lib/components/FlowContextSelector.d.ts +11 -0
- package/lib/components/FlowContextSelector.js +221 -0
- package/lib/components/FlowErrorFallback.d.ts +25 -0
- package/lib/components/FlowErrorFallback.js +264 -0
- package/lib/components/FlowModelRenderer.d.ts +64 -0
- package/lib/components/FlowModelRenderer.js +254 -0
- package/lib/components/FormItem.d.ts +18 -0
- package/lib/components/FormItem.js +147 -0
- package/lib/components/common/FlowSettingsButton.d.ts +11 -0
- package/lib/components/common/FlowSettingsButton.js +66 -0
- package/lib/components/common/index.d.ts +9 -0
- package/lib/components/common/index.js +30 -0
- package/lib/components/common/withFlowDesignMode.d.ts +26 -0
- package/lib/components/common/withFlowDesignMode.js +61 -0
- package/lib/components/dnd/getMousePositionOnElement.d.ts +50 -0
- package/lib/components/dnd/getMousePositionOnElement.js +95 -0
- package/lib/components/dnd/index.d.ts +24 -0
- package/lib/components/dnd/index.js +164 -0
- package/lib/components/dnd/moveBlock.d.ts +33 -0
- package/lib/components/dnd/moveBlock.js +302 -0
- package/lib/components/index.d.ts +18 -0
- package/lib/components/index.js +48 -0
- package/lib/components/settings/independents/dropdown/FlowsDropdownButton.d.ts +46 -0
- package/lib/components/settings/independents/dropdown/FlowsDropdownButton.js +225 -0
- package/lib/components/settings/independents/dropdown/index.d.ts +9 -0
- package/lib/components/settings/independents/dropdown/index.js +30 -0
- package/lib/components/settings/independents/index.d.ts +1 -0
- package/lib/components/settings/independents/index.js +30 -0
- package/lib/components/settings/index.d.ts +10 -0
- package/lib/components/settings/index.js +32 -0
- package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.d.ts +24 -0
- package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.js +501 -0
- package/lib/components/settings/wrappers/contextual/FlowsContextMenu.d.ts +45 -0
- package/lib/components/settings/wrappers/contextual/FlowsContextMenu.js +231 -0
- package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.d.ts +111 -0
- package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.js +484 -0
- package/lib/components/settings/wrappers/contextual/StepRequiredSettingsDialog.d.ts +26 -0
- package/lib/components/settings/wrappers/contextual/StepRequiredSettingsDialog.js +342 -0
- package/lib/components/settings/wrappers/contextual/StepSettings.d.ts +23 -0
- package/lib/components/settings/wrappers/contextual/StepSettings.js +110 -0
- package/lib/components/settings/wrappers/contextual/StepSettingsDialog.d.ts +20 -0
- package/lib/components/settings/wrappers/contextual/StepSettingsDialog.js +206 -0
- package/lib/components/settings/wrappers/contextual/StepSettingsDrawer.d.ts +20 -0
- package/lib/components/settings/wrappers/contextual/StepSettingsDrawer.js +47 -0
- package/lib/components/settings/wrappers/contextual/index.d.ts +14 -0
- package/lib/components/settings/wrappers/contextual/index.js +40 -0
- package/lib/components/settings/wrappers/embedded/FlowSettings.d.ts +33 -0
- package/lib/components/settings/wrappers/embedded/FlowSettings.js +207 -0
- package/lib/components/settings/wrappers/embedded/FlowsSettings.d.ts +41 -0
- package/lib/components/settings/wrappers/embedded/FlowsSettings.js +84 -0
- package/lib/components/settings/wrappers/embedded/FlowsSettingsContent.d.ts +16 -0
- package/lib/components/settings/wrappers/embedded/FlowsSettingsContent.js +88 -0
- package/lib/components/settings/wrappers/embedded/index.d.ts +10 -0
- package/lib/components/settings/wrappers/embedded/index.js +32 -0
- package/lib/components/settings/wrappers/index.d.ts +2 -0
- package/lib/components/settings/wrappers/index.js +32 -0
- package/lib/components/subModel/AddSubModelButton.d.ts +62 -0
- package/lib/components/subModel/AddSubModelButton.js +415 -0
- package/lib/components/subModel/LazyDropdown.d.ts +55 -0
- package/lib/components/subModel/LazyDropdown.js +524 -0
- package/lib/components/subModel/index.d.ts +10 -0
- package/lib/components/subModel/index.js +32 -0
- package/lib/components/subModel/utils.d.ts +34 -0
- package/lib/components/subModel/utils.js +287 -0
- package/lib/components/variables/InlineVariableTag.d.ts +21 -0
- package/lib/components/variables/InlineVariableTag.js +123 -0
- package/lib/components/variables/SlateVariableEditor.d.ts +46 -0
- package/lib/components/variables/SlateVariableEditor.js +302 -0
- package/lib/components/variables/VariableInput.d.ts +11 -0
- package/lib/components/variables/VariableInput.js +322 -0
- package/lib/components/variables/VariableTag.d.ts +11 -0
- package/lib/components/variables/VariableTag.js +148 -0
- package/lib/components/variables/VariableTrigger.d.ts +20 -0
- package/lib/components/variables/VariableTrigger.js +136 -0
- package/lib/components/variables/index.d.ts +15 -0
- package/lib/components/variables/index.js +53 -0
- package/lib/components/variables/types.d.ts +93 -0
- package/lib/components/variables/types.js +24 -0
- package/lib/components/variables/useResolvedMetaTree.d.ts +19 -0
- package/lib/components/variables/useResolvedMetaTree.js +91 -0
- package/lib/components/variables/utils.d.ts +22 -0
- package/lib/components/variables/utils.js +177 -0
- package/lib/data-source/index.d.ts +180 -0
- package/lib/data-source/index.js +733 -0
- package/lib/data-source/jioToJoiSchema.d.ts +19 -0
- package/lib/data-source/jioToJoiSchema.js +114 -0
- package/lib/decorators/index.d.ts +9 -0
- package/lib/decorators/index.js +36 -0
- package/lib/decorators/largeField.d.ts +9 -0
- package/lib/decorators/largeField.js +42 -0
- package/lib/emitter.d.ts +16 -0
- package/lib/emitter.js +58 -0
- package/lib/event-registry/BaseEventRegistry.d.ts +22 -0
- package/lib/event-registry/BaseEventRegistry.js +57 -0
- package/lib/event-registry/EngineEventRegistry.d.ts +19 -0
- package/lib/event-registry/EngineEventRegistry.js +47 -0
- package/lib/event-registry/ModelEventRegistry.d.ts +33 -0
- package/lib/event-registry/ModelEventRegistry.js +79 -0
- package/lib/executor/FlowExecutor.d.ts +26 -0
- package/lib/executor/FlowExecutor.js +262 -0
- package/lib/flow-registry/BaseFlowRegistry.d.ts +46 -0
- package/lib/flow-registry/BaseFlowRegistry.js +86 -0
- package/lib/flow-registry/GlobalFlowRegistry.d.ts +22 -0
- package/lib/flow-registry/GlobalFlowRegistry.js +95 -0
- package/lib/flow-registry/InstanceFlowRegistry.d.ts +21 -0
- package/lib/flow-registry/InstanceFlowRegistry.js +59 -0
- package/lib/flow-registry/index.d.ts +11 -0
- package/lib/flow-registry/index.js +34 -0
- package/lib/flowContext.d.ts +215 -0
- package/lib/flowContext.js +1266 -0
- package/lib/flowEngine.d.ts +340 -0
- package/lib/flowEngine.js +781 -0
- package/lib/flowI18n.d.ts +46 -0
- package/lib/flowI18n.js +117 -0
- package/lib/flowSettings.d.ts +266 -0
- package/lib/flowSettings.js +850 -0
- package/lib/hooks/index.d.ts +14 -0
- package/lib/hooks/index.js +40 -0
- package/lib/hooks/useApplyAutoFlows.d.ts +21 -0
- package/lib/hooks/useApplyAutoFlows.js +62 -0
- package/lib/hooks/useFlowModel.d.ts +29 -0
- package/lib/hooks/useFlowModel.js +72 -0
- package/lib/hooks/useFlowModelById.d.ts +11 -0
- package/lib/hooks/useFlowModelById.js +61 -0
- package/lib/hooks/useFlowSettingsContext.d.ts +20 -0
- package/lib/hooks/useFlowSettingsContext.js +61 -0
- package/lib/hooks/useFlowStep.d.ts +17 -0
- package/lib/hooks/useFlowStep.js +56 -0
- package/lib/hooks/useNiceDropdownMaxHeight.d.ts +13 -0
- package/lib/hooks/useNiceDropdownMaxHeight.js +52 -0
- package/lib/index.d.ts +27 -0
- package/lib/index.js +73 -0
- package/lib/locale/en-US.json +61 -0
- package/lib/locale/index.d.ts +141 -0
- package/lib/locale/index.js +70 -0
- package/lib/locale/zh-CN.json +61 -0
- package/lib/models/CollectionFieldModel.d.ts +50 -0
- package/lib/models/CollectionFieldModel.js +242 -0
- package/lib/models/DisplayItemModel.d.ts +12 -0
- package/lib/models/DisplayItemModel.js +41 -0
- package/lib/models/EditableItemModel.d.ts +12 -0
- package/lib/models/EditableItemModel.js +41 -0
- package/lib/models/FilterableItemModel.d.ts +12 -0
- package/lib/models/FilterableItemModel.js +41 -0
- package/lib/models/flowModel.d.ts +344 -0
- package/lib/models/flowModel.js +1133 -0
- package/lib/models/forkFlowModel.d.ts +83 -0
- package/lib/models/forkFlowModel.js +257 -0
- package/lib/models/index.d.ts +14 -0
- package/lib/models/index.js +40 -0
- package/lib/provider.d.ts +22 -0
- package/lib/provider.js +114 -0
- package/lib/resources/apiResource.d.ts +34 -0
- package/lib/resources/apiResource.js +153 -0
- package/lib/resources/baseRecordResource.d.ts +61 -0
- package/lib/resources/baseRecordResource.js +264 -0
- package/lib/resources/filterItem.d.ts +33 -0
- package/lib/resources/filterItem.js +93 -0
- package/lib/resources/flowResource.d.ts +45 -0
- package/lib/resources/flowResource.js +146 -0
- package/lib/resources/index.d.ts +15 -0
- package/lib/resources/index.js +42 -0
- package/lib/resources/multiRecordResource.d.ts +53 -0
- package/lib/resources/multiRecordResource.js +230 -0
- package/lib/resources/singleRecordResource.d.ts +23 -0
- package/lib/resources/singleRecordResource.js +111 -0
- package/lib/resources/sqlResource.d.ts +73 -0
- package/lib/resources/sqlResource.js +294 -0
- package/lib/runjs-context/contexts/FlowRunJSContext.d.ts +38 -0
- package/lib/runjs-context/contexts/FlowRunJSContext.js +217 -0
- package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.d.ts +16 -0
- package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.js +66 -0
- package/lib/runjs-context/contexts/JSBlockRunJSContext.d.ts +16 -0
- package/lib/runjs-context/contexts/JSBlockRunJSContext.js +78 -0
- package/lib/runjs-context/contexts/JSCollectionActionRunJSContext.d.ts +12 -0
- package/lib/runjs-context/contexts/JSCollectionActionRunJSContext.js +59 -0
- package/lib/runjs-context/contexts/JSFieldRunJSContext.d.ts +16 -0
- package/lib/runjs-context/contexts/JSFieldRunJSContext.js +70 -0
- package/lib/runjs-context/contexts/JSItemRunJSContext.d.ts +16 -0
- package/lib/runjs-context/contexts/JSItemRunJSContext.js +66 -0
- package/lib/runjs-context/contexts/JSRecordActionRunJSContext.d.ts +12 -0
- package/lib/runjs-context/contexts/JSRecordActionRunJSContext.js +61 -0
- package/lib/runjs-context/contexts/LinkageRunJSContext.d.ts +12 -0
- package/lib/runjs-context/contexts/LinkageRunJSContext.js +62 -0
- package/lib/runjs-context/helpers.d.ts +17 -0
- package/lib/runjs-context/helpers.js +79 -0
- package/lib/runjs-context/index.d.ts +19 -0
- package/lib/runjs-context/index.js +57 -0
- package/lib/runjs-context/registry.d.ts +17 -0
- package/lib/runjs-context/registry.js +93 -0
- package/lib/runjs-context/snippets/global/api-request-get.snippet.d.ts +16 -0
- package/lib/runjs-context/snippets/global/api-request-get.snippet.js +42 -0
- package/lib/runjs-context/snippets/global/api-request-post.snippet.d.ts +16 -0
- package/lib/runjs-context/snippets/global/api-request-post.snippet.js +42 -0
- package/lib/runjs-context/snippets/global/console-log-ctx.snippet.d.ts +16 -0
- package/lib/runjs-context/snippets/global/console-log-ctx.snippet.js +41 -0
- package/lib/runjs-context/snippets/global/copy-record-json.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/global/copy-record-json.snippet.js +42 -0
- package/lib/runjs-context/snippets/global/copy-to-clipboard.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/global/copy-to-clipboard.snippet.js +42 -0
- package/lib/runjs-context/snippets/global/log-json-record.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/global/log-json-record.snippet.js +42 -0
- package/lib/runjs-context/snippets/global/message-error.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/global/message-error.snippet.js +41 -0
- package/lib/runjs-context/snippets/global/message-success.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/global/message-success.snippet.js +41 -0
- package/lib/runjs-context/snippets/global/notification-open.snippet.d.ts +16 -0
- package/lib/runjs-context/snippets/global/notification-open.snippet.js +43 -0
- package/lib/runjs-context/snippets/global/open-view-dialog.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/global/open-view-dialog.snippet.js +47 -0
- package/lib/runjs-context/snippets/global/open-view-drawer.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/global/open-view-drawer.snippet.js +47 -0
- package/lib/runjs-context/snippets/global/requireAsync.snippet.d.ts +16 -0
- package/lib/runjs-context/snippets/global/requireAsync.snippet.js +46 -0
- package/lib/runjs-context/snippets/global/sleep.snippet.d.ts +16 -0
- package/lib/runjs-context/snippets/global/sleep.snippet.js +43 -0
- package/lib/runjs-context/snippets/global/try-catch-async.snippet.d.ts +16 -0
- package/lib/runjs-context/snippets/global/try-catch-async.snippet.js +44 -0
- package/lib/runjs-context/snippets/global/view-navigation-push.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/global/view-navigation-push.snippet.js +44 -0
- package/lib/runjs-context/snippets/global/window-open.snippet.d.ts +16 -0
- package/lib/runjs-context/snippets/global/window-open.snippet.js +41 -0
- package/lib/runjs-context/snippets/index.d.ts +11 -0
- package/lib/runjs-context/snippets/index.js +94 -0
- package/lib/runjs-context/snippets/libs/echarts-init.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/libs/echarts-init.snippet.js +46 -0
- package/lib/runjs-context/snippets/scene/actions/collection-selected-count.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/actions/collection-selected-count.snippet.js +44 -0
- package/lib/runjs-context/snippets/scene/actions/iterate-selected-rows.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/actions/iterate-selected-rows.snippet.js +43 -0
- package/lib/runjs-context/snippets/scene/actions/record-id-message.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/actions/record-id-message.snippet.js +43 -0
- package/lib/runjs-context/snippets/scene/actions/run-action-basic.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/actions/run-action-basic.snippet.js +40 -0
- package/lib/runjs-context/snippets/scene/jsblock/add-event-listener.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/jsblock/add-event-listener.snippet.js +46 -0
- package/lib/runjs-context/snippets/scene/jsblock/append-style.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/jsblock/append-style.snippet.js +42 -0
- package/lib/runjs-context/snippets/scene/jsblock/jsx-mount.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/jsblock/jsx-mount.snippet.js +46 -0
- package/lib/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.js +41 -0
- package/lib/runjs-context/snippets/scene/jsblock/render-basic.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/jsblock/render-basic.snippet.js +41 -0
- package/lib/runjs-context/snippets/scene/jsblock/render-button-handler.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/jsblock/render-button-handler.snippet.js +46 -0
- package/lib/runjs-context/snippets/scene/jsblock/render-card.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/jsblock/render-card.snippet.js +45 -0
- package/lib/runjs-context/snippets/scene/jsblock/render-react.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/jsblock/render-react.snippet.js +56 -0
- package/lib/runjs-context/snippets/scene/jsfield/color-by-value.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/jsfield/color-by-value.snippet.js +42 -0
- package/lib/runjs-context/snippets/scene/jsfield/format-number.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/jsfield/format-number.snippet.js +41 -0
- package/lib/runjs-context/snippets/scene/jsfield/innerHTML-value.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/jsfield/innerHTML-value.snippet.js +40 -0
- package/lib/runjs-context/snippets/scene/jsitem/render-basic.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/jsitem/render-basic.snippet.js +44 -0
- package/lib/runjs-context/snippets/scene/linkage/set-disabled.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/linkage/set-disabled.snippet.js +60 -0
- package/lib/runjs-context/snippets/scene/linkage/set-field-value.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/linkage/set-field-value.snippet.js +59 -0
- package/lib/runjs-context/snippets/scene/linkage/set-required.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/linkage/set-required.snippet.js +60 -0
- package/lib/runjs-context/snippets/scene/linkage/toggle-visible.snippet.d.ts +15 -0
- package/lib/runjs-context/snippets/scene/linkage/toggle-visible.snippet.js +60 -0
- package/lib/runjs-context/snippets/types.d.ts +16 -0
- package/lib/runjs-context/snippets/types.js +24 -0
- package/lib/types.d.ts +398 -0
- package/lib/types.js +43 -0
- package/lib/utils/autoFlowError.d.ts +16 -0
- package/lib/utils/autoFlowError.js +53 -0
- package/lib/utils/constants.d.ts +29 -0
- package/lib/utils/constants.js +77 -0
- package/lib/utils/context.d.ts +40 -0
- package/lib/utils/context.js +63 -0
- package/lib/utils/createCollectionContextMeta.d.ts +11 -0
- package/lib/utils/createCollectionContextMeta.js +117 -0
- package/lib/utils/exceptions.d.ts +22 -0
- package/lib/utils/exceptions.js +62 -0
- package/lib/utils/flow-definitions.d.ts +11 -0
- package/lib/utils/flow-definitions.js +40 -0
- package/lib/utils/index.d.ts +22 -0
- package/lib/utils/index.js +117 -0
- package/lib/utils/inheritance.d.ts +16 -0
- package/lib/utils/inheritance.js +53 -0
- package/lib/utils/params-resolvers.d.ts +51 -0
- package/lib/utils/params-resolvers.js +309 -0
- package/lib/utils/parsePathnameToViewParams.d.ts +34 -0
- package/lib/utils/parsePathnameToViewParams.js +84 -0
- package/lib/utils/safeGlobals.d.ts +16 -0
- package/lib/utils/safeGlobals.js +179 -0
- package/lib/utils/schema-utils.d.ts +40 -0
- package/lib/utils/schema-utils.js +161 -0
- package/lib/utils/serverContextParams.d.ts +28 -0
- package/lib/utils/serverContextParams.js +106 -0
- package/lib/utils/setupRuntimeContextSteps.d.ts +19 -0
- package/lib/utils/setupRuntimeContextSteps.js +88 -0
- package/lib/utils/translation.d.ts +18 -0
- package/lib/utils/translation.js +58 -0
- package/lib/utils/variablesParams.d.ts +51 -0
- package/lib/utils/variablesParams.js +150 -0
- package/lib/views/DialogComponent.d.ts +22 -0
- package/lib/views/DialogComponent.js +98 -0
- package/lib/views/DrawerComponent.d.ts +11 -0
- package/lib/views/DrawerComponent.js +101 -0
- package/lib/views/FlowView.d.ts +76 -0
- package/lib/views/FlowView.js +81 -0
- package/lib/views/PageComponent.d.ts +10 -0
- package/lib/views/PageComponent.js +167 -0
- package/lib/views/ViewNavigation.d.ts +45 -0
- package/lib/views/ViewNavigation.js +97 -0
- package/lib/views/createViewMeta.d.ts +16 -0
- package/lib/views/createViewMeta.js +171 -0
- package/lib/views/index.d.ts +13 -0
- package/lib/views/index.js +48 -0
- package/lib/views/useDialog.d.ts +32 -0
- package/lib/views/useDialog.js +199 -0
- package/lib/views/useDrawer.d.ts +33 -0
- package/lib/views/useDrawer.js +206 -0
- package/lib/views/usePage.d.ts +32 -0
- package/lib/views/usePage.js +193 -0
- package/lib/views/usePatchElement.d.ts +10 -0
- package/lib/views/usePatchElement.js +54 -0
- package/lib/views/usePopover.d.ts +17 -0
- package/lib/views/usePopover.js +159 -0
- package/package.json +37 -0
- package/src/ContextPathProxy.ts +45 -0
- package/src/ElementProxy.ts +69 -0
- package/src/FlowContextProvider.tsx +40 -0
- package/src/FlowDefinition.ts +275 -0
- package/src/JSRunner.ts +84 -0
- package/src/ReactView.tsx +104 -0
- package/src/ViewScopedFlowEngine.ts +75 -0
- package/src/__tests__/ElementProxy.test.ts +51 -0
- package/src/__tests__/JSRunner.test.ts +92 -0
- package/src/__tests__/ReactView.test.tsx +63 -0
- package/src/__tests__/context-path-proxy.test.ts +35 -0
- package/src/__tests__/flow-engine.test.ts +189 -0
- package/src/__tests__/flowContext.test.ts +2012 -0
- package/src/__tests__/flowEngine.saveModel.test.ts +171 -0
- package/src/__tests__/flowI18n.test.ts +28 -0
- package/src/__tests__/flowModel.getFlows.test.ts +61 -0
- package/src/__tests__/flowModel.openView.navigation.test.ts +78 -0
- package/src/__tests__/flowRuntimeContext.test.ts +187 -0
- package/src/__tests__/flowSettings.open.test.tsx +1920 -0
- package/src/__tests__/flowSettings.test.ts +566 -0
- package/src/__tests__/globalFlowRegistry.test.ts +77 -0
- package/src/__tests__/isFieldInterfaceMatch.test.ts +51 -0
- package/src/__tests__/metaTreeNodeCache.test.ts +234 -0
- package/src/__tests__/path-aggregation.test.ts +85 -0
- package/src/__tests__/provider.test.tsx +28 -0
- package/src/__tests__/renderHiddenInConfig.test.tsx +91 -0
- package/src/__tests__/runjsContext.test.ts +60 -0
- package/src/__tests__/viewScopedFlowEngine.test.ts +212 -0
- package/src/acl/Acl.tsx +109 -0
- package/src/acl/__tests__/Acl.test.tsx +72 -0
- package/src/action-registry/BaseActionRegistry.ts +46 -0
- package/src/action-registry/EngineActionRegistry.ts +32 -0
- package/src/action-registry/ModelActionRegistry.ts +75 -0
- package/src/action-registry/__tests__/engineActionRegistry.test.ts +43 -0
- package/src/action-registry/__tests__/modelActionRegistry.test.ts +107 -0
- package/src/components/DynamicFlowsEditor.tsx +318 -0
- package/src/components/FieldModelRenderer.tsx +62 -0
- package/src/components/FlowContextSelector.tsx +255 -0
- package/src/components/FlowErrorFallback.tsx +316 -0
- package/src/components/FlowModelRenderer.tsx +428 -0
- package/src/components/FormItem.tsx +130 -0
- package/src/components/__tests__/flow-model-render-error-fallback.test.tsx +226 -0
- package/src/components/common/FlowSettingsButton.tsx +30 -0
- package/src/components/common/index.ts +10 -0
- package/src/components/common/withFlowDesignMode.tsx +49 -0
- package/src/components/dnd/getMousePositionOnElement.ts +115 -0
- package/src/components/dnd/index.tsx +128 -0
- package/src/components/dnd/moveBlock.ts +379 -0
- package/src/components/index.ts +20 -0
- package/src/components/settings/independents/dropdown/FlowsDropdownButton.tsx +279 -0
- package/src/components/settings/independents/dropdown/index.ts +10 -0
- package/src/components/settings/independents/index.ts +2 -0
- package/src/components/settings/index.ts +11 -0
- package/src/components/settings/wrappers/contextual/DefaultSettingsIcon.tsx +617 -0
- package/src/components/settings/wrappers/contextual/FlowsContextMenu.tsx +292 -0
- package/src/components/settings/wrappers/contextual/FlowsFloatContextMenu.tsx +655 -0
- package/src/components/settings/wrappers/contextual/StepRequiredSettingsDialog.tsx +446 -0
- package/src/components/settings/wrappers/contextual/StepSettings.tsx +109 -0
- package/src/components/settings/wrappers/contextual/StepSettingsDialog.tsx +217 -0
- package/src/components/settings/wrappers/contextual/StepSettingsDrawer.tsx +32 -0
- package/src/components/settings/wrappers/contextual/index.ts +15 -0
- package/src/components/settings/wrappers/embedded/FlowSettings.tsx +258 -0
- package/src/components/settings/wrappers/embedded/FlowsSettings.tsx +111 -0
- package/src/components/settings/wrappers/embedded/FlowsSettingsContent.tsx +96 -0
- package/src/components/settings/wrappers/embedded/index.ts +11 -0
- package/src/components/settings/wrappers/index.ts +5 -0
- package/src/components/subModel/AddSubModelButton.tsx +575 -0
- package/src/components/subModel/LazyDropdown.tsx +714 -0
- package/src/components/subModel/__tests__/AddSubModelButton.test.tsx +1185 -0
- package/src/components/subModel/__tests__/buildWrapperFieldChildren.test.ts +192 -0
- package/src/components/subModel/__tests__/utils.test.ts +425 -0
- package/src/components/subModel/index.ts +12 -0
- package/src/components/subModel/utils.ts +278 -0
- package/src/components/variables/InlineVariableTag.tsx +97 -0
- package/src/components/variables/SlateVariableEditor.tsx +384 -0
- package/src/components/variables/VariableInput.tsx +342 -0
- package/src/components/variables/VariableTag.tsx +123 -0
- package/src/components/variables/VariableTrigger.tsx +116 -0
- package/src/components/variables/__tests__/FlowContextSelector.test.tsx +553 -0
- package/src/components/variables/__tests__/VariableInput.test.tsx +550 -0
- package/src/components/variables/__tests__/VariableTag.test.tsx +347 -0
- package/src/components/variables/__tests__/test-utils.tsx +62 -0
- package/src/components/variables/__tests__/utils.test.ts +310 -0
- package/src/components/variables/index.ts +16 -0
- package/src/components/variables/types.ts +100 -0
- package/src/components/variables/useResolvedMetaTree.ts +76 -0
- package/src/components/variables/utils.ts +192 -0
- package/src/data-source/__tests__/collection.test.ts +58 -0
- package/src/data-source/__tests__/index.test.ts +82 -0
- package/src/data-source/__tests__/jioToJoiSchema.test.ts +56 -0
- package/src/data-source/index.ts +812 -0
- package/src/data-source/jioToJoiSchema.ts +103 -0
- package/src/decorators/index.ts +10 -0
- package/src/decorators/largeField.ts +14 -0
- package/src/emitter.ts +33 -0
- package/src/event-registry/BaseEventRegistry.ts +40 -0
- package/src/event-registry/EngineEventRegistry.ts +26 -0
- package/src/event-registry/ModelEventRegistry.ts +69 -0
- package/src/event-registry/__tests__/engineEventRegistry.test.ts +48 -0
- package/src/executor/FlowExecutor.ts +256 -0
- package/src/executor/__tests__/eventStep.test.ts +157 -0
- package/src/executor/__tests__/flowExecutor.test.ts +163 -0
- package/src/flow-registry/BaseFlowRegistry.ts +91 -0
- package/src/flow-registry/GlobalFlowRegistry.ts +82 -0
- package/src/flow-registry/InstanceFlowRegistry.ts +39 -0
- package/src/flow-registry/__tests__/globalFlowRegistry.test.ts +141 -0
- package/src/flow-registry/__tests__/instance-and-global-registry.test.ts +67 -0
- package/src/flow-registry/__tests__/instanceFlowRegistry.test.ts +83 -0
- package/src/flow-registry/index.ts +12 -0
- package/src/flowContext.ts +1639 -0
- package/src/flowEngine.ts +905 -0
- package/src/flowI18n.ts +96 -0
- package/src/flowSettings.ts +1045 -0
- package/src/hooks/index.ts +15 -0
- package/src/hooks/useApplyAutoFlows.ts +51 -0
- package/src/hooks/useFlowModel.tsx +59 -0
- package/src/hooks/useFlowModelById.ts +37 -0
- package/src/hooks/useFlowSettingsContext.tsx +37 -0
- package/src/hooks/useFlowStep.tsx +19 -0
- package/src/hooks/useNiceDropdownMaxHeight.ts +34 -0
- package/src/index.ts +38 -0
- package/src/locale/en-US.json +61 -0
- package/src/locale/index.ts +38 -0
- package/src/locale/zh-CN.json +61 -0
- package/src/models/CollectionFieldModel.tsx +269 -0
- package/src/models/DisplayItemModel.tsx +13 -0
- package/src/models/EditableItemModel.tsx +13 -0
- package/src/models/FilterableItemModel.tsx +13 -0
- package/src/models/__tests__/CollectionFieldModel.test.ts +122 -0
- package/src/models/__tests__/defaultParams-on-create.test.ts +83 -0
- package/src/models/__tests__/flow-model-oninit.test.ts +44 -0
- package/src/models/__tests__/flowModel.actions.integration.test.ts +100 -0
- package/src/models/__tests__/flowModel.getFlows.sort.test.ts +100 -0
- package/src/models/__tests__/flowModel.test.ts +2746 -0
- package/src/models/__tests__/flowRegistry.test.ts +512 -0
- package/src/models/__tests__/forkFlowModel.test.ts +1047 -0
- package/src/models/__tests__/model-actions.test.ts +70 -0
- package/src/models/__tests__/model-events.test.ts +69 -0
- package/src/models/flowModel.tsx +1398 -0
- package/src/models/forkFlowModel.ts +287 -0
- package/src/models/index.ts +17 -0
- package/src/provider.tsx +101 -0
- package/src/resources/__tests__/apiResource.test.ts +201 -0
- package/src/resources/__tests__/baseRecordResource.test.ts +262 -0
- package/src/resources/__tests__/filterItem.test.ts +260 -0
- package/src/resources/__tests__/flowResource.test.ts +127 -0
- package/src/resources/apiResource.ts +148 -0
- package/src/resources/baseRecordResource.ts +279 -0
- package/src/resources/filterItem.ts +74 -0
- package/src/resources/flowResource.ts +143 -0
- package/src/resources/index.ts +17 -0
- package/src/resources/multiRecordResource.ts +219 -0
- package/src/resources/singleRecordResource.ts +83 -0
- package/src/resources/sqlResource.ts +299 -0
- package/src/runjs-context/contexts/FlowRunJSContext.ts +190 -0
- package/src/runjs-context/contexts/FormJSFieldItemRunJSContext.ts +39 -0
- package/src/runjs-context/contexts/JSBlockRunJSContext.ts +52 -0
- package/src/runjs-context/contexts/JSCollectionActionRunJSContext.ts +32 -0
- package/src/runjs-context/contexts/JSFieldRunJSContext.ts +43 -0
- package/src/runjs-context/contexts/JSItemRunJSContext.ts +39 -0
- package/src/runjs-context/contexts/JSRecordActionRunJSContext.ts +34 -0
- package/src/runjs-context/contexts/LinkageRunJSContext.ts +35 -0
- package/src/runjs-context/helpers.ts +56 -0
- package/src/runjs-context/index.ts +20 -0
- package/src/runjs-context/registry.ts +65 -0
- package/src/runjs-context/snippets/global/api-request-get.snippet.ts +20 -0
- package/src/runjs-context/snippets/global/api-request-post.snippet.ts +20 -0
- package/src/runjs-context/snippets/global/console-log-ctx.snippet.ts +19 -0
- package/src/runjs-context/snippets/global/copy-record-json.snippet.ts +21 -0
- package/src/runjs-context/snippets/global/copy-to-clipboard.snippet.ts +21 -0
- package/src/runjs-context/snippets/global/log-json-record.snippet.ts +21 -0
- package/src/runjs-context/snippets/global/message-error.snippet.ts +20 -0
- package/src/runjs-context/snippets/global/message-success.snippet.ts +20 -0
- package/src/runjs-context/snippets/global/notification-open.snippet.ts +21 -0
- package/src/runjs-context/snippets/global/open-view-dialog.snippet.ts +26 -0
- package/src/runjs-context/snippets/global/open-view-drawer.snippet.ts +26 -0
- package/src/runjs-context/snippets/global/requireAsync.snippet.ts +24 -0
- package/src/runjs-context/snippets/global/sleep.snippet.ts +21 -0
- package/src/runjs-context/snippets/global/try-catch-async.snippet.ts +22 -0
- package/src/runjs-context/snippets/global/view-navigation-push.snippet.ts +23 -0
- package/src/runjs-context/snippets/global/window-open.snippet.ts +19 -0
- package/src/runjs-context/snippets/index.ts +59 -0
- package/src/runjs-context/snippets/libs/echarts-init.snippet.ts +24 -0
- package/src/runjs-context/snippets/scene/actions/collection-selected-count.snippet.ts +22 -0
- package/src/runjs-context/snippets/scene/actions/iterate-selected-rows.snippet.ts +21 -0
- package/src/runjs-context/snippets/scene/actions/record-id-message.snippet.ts +21 -0
- package/src/runjs-context/snippets/scene/actions/run-action-basic.snippet.ts +18 -0
- package/src/runjs-context/snippets/scene/jsblock/add-event-listener.snippet.ts +29 -0
- package/src/runjs-context/snippets/scene/jsblock/append-style.snippet.ts +20 -0
- package/src/runjs-context/snippets/scene/jsblock/jsx-mount.snippet.ts +24 -0
- package/src/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.ts +19 -0
- package/src/runjs-context/snippets/scene/jsblock/render-basic.snippet.ts +24 -0
- package/src/runjs-context/snippets/scene/jsblock/render-button-handler.snippet.ts +24 -0
- package/src/runjs-context/snippets/scene/jsblock/render-card.snippet.ts +30 -0
- package/src/runjs-context/snippets/scene/jsblock/render-react.snippet.ts +34 -0
- package/src/runjs-context/snippets/scene/jsfield/color-by-value.snippet.ts +20 -0
- package/src/runjs-context/snippets/scene/jsfield/format-number.snippet.ts +19 -0
- package/src/runjs-context/snippets/scene/jsfield/innerHTML-value.snippet.ts +18 -0
- package/src/runjs-context/snippets/scene/jsitem/render-basic.snippet.ts +27 -0
- package/src/runjs-context/snippets/scene/linkage/set-disabled.snippet.ts +38 -0
- package/src/runjs-context/snippets/scene/linkage/set-field-value.snippet.ts +37 -0
- package/src/runjs-context/snippets/scene/linkage/set-required.snippet.ts +38 -0
- package/src/runjs-context/snippets/scene/linkage/toggle-visible.snippet.ts +38 -0
- package/src/runjs-context/snippets/types.ts +17 -0
- package/src/types.ts +474 -0
- package/src/utils/__tests__/context.test.ts +93 -0
- package/src/utils/__tests__/params-resolvers.test.ts +652 -0
- package/src/utils/__tests__/parsePathnameToViewParams.test.ts +104 -0
- package/src/utils/__tests__/safeGlobals.test.ts +29 -0
- package/src/utils/__tests__/utils.test.ts +1021 -0
- package/src/utils/__tests__/variablesParams.test.ts +52 -0
- package/src/utils/autoFlowError.ts +29 -0
- package/src/utils/constants.ts +60 -0
- package/src/utils/context.ts +70 -0
- package/src/utils/createCollectionContextMeta.ts +122 -0
- package/src/utils/exceptions.ts +36 -0
- package/src/utils/flow-definitions.ts +16 -0
- package/src/utils/index.ts +63 -0
- package/src/utils/inheritance.ts +39 -0
- package/src/utils/params-resolvers.ts +482 -0
- package/src/utils/parsePathnameToViewParams.ts +103 -0
- package/src/utils/safeGlobals.ts +188 -0
- package/src/utils/schema-utils.ts +201 -0
- package/src/utils/serverContextParams.ts +111 -0
- package/src/utils/setupRuntimeContextSteps.ts +89 -0
- package/src/utils/translation.ts +37 -0
- package/src/utils/variablesParams.ts +175 -0
- package/src/views/DialogComponent.tsx +79 -0
- package/src/views/DrawerComponent.tsx +72 -0
- package/src/views/FlowView.tsx +103 -0
- package/src/views/PageComponent.tsx +150 -0
- package/src/views/ViewNavigation.ts +122 -0
- package/src/views/__tests__/FlowView.test.ts +31 -0
- package/src/views/__tests__/ViewNavigation.test.ts +191 -0
- package/src/views/__tests__/usePatchElement.test.tsx +28 -0
- package/src/views/createViewMeta.ts +157 -0
- package/src/views/index.tsx +14 -0
- package/src/views/useDialog.tsx +192 -0
- package/src/views/useDrawer.tsx +205 -0
- package/src/views/usePage.tsx +182 -0
- package/src/views/usePatchElement.tsx +27 -0
- package/src/views/usePopover.tsx +131 -0
|
@@ -0,0 +1,652 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
|
11
|
+
import { Collection } from '../../data-source';
|
|
12
|
+
import { FlowRuntimeContext } from '../../flowContext';
|
|
13
|
+
import { FlowEngine } from '../../flowEngine';
|
|
14
|
+
import { FlowModel } from '../../models';
|
|
15
|
+
import { preprocessExpression, resolveExpressions } from '../params-resolvers';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* preprocessExpression 测试套件
|
|
19
|
+
*
|
|
20
|
+
* preprocessExpression 是表达式预处理器的核心函数,提供以下功能:
|
|
21
|
+
*
|
|
22
|
+
* 1. **路径解析与分类**
|
|
23
|
+
* - 识别单层路径(ctx.user)和多层路径(ctx.user.name)
|
|
24
|
+
* - 排除函数调用(ctx.method())避免误处理
|
|
25
|
+
* - 批量收集所有需要处理的路径表达式
|
|
26
|
+
*
|
|
27
|
+
* 2. **RecordProxy 检测**
|
|
28
|
+
* - 检测一层路径是否为 RecordProxy 实例
|
|
29
|
+
* - 对 RecordProxy 深层路径添加双重 await 优化数据库查询
|
|
30
|
+
* - 对普通对象路径仅在第一层添加 await
|
|
31
|
+
*
|
|
32
|
+
* 3. **字符串预处理与优化**
|
|
33
|
+
* - 在保持表达式计算顺序的前提下插入必要的 await
|
|
34
|
+
* - 使用精确的正则替换避免误替换类似路径
|
|
35
|
+
* - 支持复杂表达式中的混合路径处理
|
|
36
|
+
*
|
|
37
|
+
* 测试结构:
|
|
38
|
+
* - 基础路径处理: 单层、多层路径的 await 插入
|
|
39
|
+
* - RecordProxy 优化: RecordProxy 实例的双重 await 处理
|
|
40
|
+
* - 复杂表达式支持: 运算符、方法调用等混合场景
|
|
41
|
+
* - 边界情况处理: 函数调用排除、路径冲突处理
|
|
42
|
+
*/
|
|
43
|
+
describe('preprocessExpression', () => {
|
|
44
|
+
let engine: FlowEngine;
|
|
45
|
+
let model: FlowModel;
|
|
46
|
+
let ctx: FlowRuntimeContext;
|
|
47
|
+
let postsCollection: Collection;
|
|
48
|
+
let usersCollection: Collection;
|
|
49
|
+
let profilesCollection: Collection;
|
|
50
|
+
|
|
51
|
+
beforeEach(() => {
|
|
52
|
+
// 创建真实的流程引擎环境
|
|
53
|
+
engine = new FlowEngine();
|
|
54
|
+
model = new FlowModel({
|
|
55
|
+
uid: 'test-model',
|
|
56
|
+
flowEngine: engine,
|
|
57
|
+
});
|
|
58
|
+
ctx = new FlowRuntimeContext(model, 'test-flow', 'runtime');
|
|
59
|
+
|
|
60
|
+
// 获取数据源管理器并创建集合定义
|
|
61
|
+
const dataSourceManager = engine.context.dataSourceManager;
|
|
62
|
+
const dataSource = dataSourceManager.getDataSource('main');
|
|
63
|
+
|
|
64
|
+
// 创建完整的集合定义(参考 RecordProxy.test.ts)
|
|
65
|
+
postsCollection = new Collection({
|
|
66
|
+
name: 'posts',
|
|
67
|
+
filterTargetKey: 'id',
|
|
68
|
+
fields: [
|
|
69
|
+
{ name: 'id', type: 'integer' },
|
|
70
|
+
{ name: 'title', type: 'string' },
|
|
71
|
+
{ name: 'author', type: 'belongsTo', target: 'users' }, // to-one
|
|
72
|
+
{ name: 'comments', type: 'hasMany', target: 'comments' }, // to-many
|
|
73
|
+
],
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
usersCollection = new Collection({
|
|
77
|
+
name: 'users',
|
|
78
|
+
filterTargetKey: 'id',
|
|
79
|
+
fields: [
|
|
80
|
+
{ name: 'id', type: 'integer' },
|
|
81
|
+
{ name: 'name', type: 'string' },
|
|
82
|
+
{ name: 'profile', type: 'hasOne', target: 'profiles' }, // to-one
|
|
83
|
+
{ name: 'posts', type: 'hasMany', target: 'posts' }, // to-many
|
|
84
|
+
],
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
profilesCollection = new Collection({
|
|
88
|
+
name: 'profiles',
|
|
89
|
+
filterTargetKey: 'id',
|
|
90
|
+
fields: [
|
|
91
|
+
{ name: 'id', type: 'integer' },
|
|
92
|
+
{ name: 'bio', type: 'string' },
|
|
93
|
+
{ name: 'avatar', type: 'string' },
|
|
94
|
+
],
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// 将集合添加到数据源
|
|
98
|
+
dataSource.addCollection(postsCollection);
|
|
99
|
+
dataSource.addCollection(usersCollection);
|
|
100
|
+
dataSource.addCollection(profilesCollection);
|
|
101
|
+
|
|
102
|
+
// 设置测试上下文数据
|
|
103
|
+
ctx.defineProperty('user', {
|
|
104
|
+
value: {
|
|
105
|
+
id: 1,
|
|
106
|
+
name: 'John Doe',
|
|
107
|
+
email: 'john@example.com',
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
ctx.defineProperty('config', {
|
|
111
|
+
value: {
|
|
112
|
+
theme: 'dark',
|
|
113
|
+
debug: true,
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
ctx.defineProperty('count', { value: 42 });
|
|
117
|
+
ctx.defineProperty('items', {
|
|
118
|
+
value: [
|
|
119
|
+
{ name: 'Item 1', type: 'A' },
|
|
120
|
+
{ name: 'Item 2', type: 'B' },
|
|
121
|
+
],
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
const mockRecord = {
|
|
125
|
+
id: 1,
|
|
126
|
+
title: 'Test Post',
|
|
127
|
+
author: {
|
|
128
|
+
id: 10,
|
|
129
|
+
name: 'Author Name',
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// Mock APIClient request method
|
|
134
|
+
const mockApiRequest = vi.fn();
|
|
135
|
+
model.context.defineProperty('api', {
|
|
136
|
+
get: () => ({
|
|
137
|
+
request: mockApiRequest,
|
|
138
|
+
}),
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* 基础路径处理功能测试组
|
|
144
|
+
*
|
|
145
|
+
* 测试 preprocessExpression 的核心路径识别和 await 插入功能
|
|
146
|
+
* 验证单层和多层路径的正确处理
|
|
147
|
+
*/
|
|
148
|
+
describe('Basic path processing', () => {
|
|
149
|
+
/**
|
|
150
|
+
* 测试无 ctx 路径表达式的直接返回
|
|
151
|
+
* 场景:传入不包含 ctx 路径的纯计算表达式
|
|
152
|
+
* 预期:直接返回原表达式,不进行任何处理
|
|
153
|
+
*/
|
|
154
|
+
test('should directly return expressions without ctx paths', async () => {
|
|
155
|
+
const expression = '1 + 2 * 3';
|
|
156
|
+
const result = await preprocessExpression(expression, ctx);
|
|
157
|
+
|
|
158
|
+
expect(result).toBe('1 + 2 * 3');
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* 测试单层 ctx 路径的 await 插入
|
|
163
|
+
* 场景:处理 ctx.user、ctx.config 等单层属性访问
|
|
164
|
+
* 预期:在单层路径前添加 await,变成 await ctx.user
|
|
165
|
+
*/
|
|
166
|
+
test('should add await for single-layer ctx paths', async () => {
|
|
167
|
+
const expression = 'ctx.user';
|
|
168
|
+
const result = await preprocessExpression(expression, ctx);
|
|
169
|
+
|
|
170
|
+
expect(result).toBe('await ctx.user');
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* 测试多层 ctx 路径的分步 await 插入
|
|
175
|
+
* 场景:处理 ctx.user.name、ctx.config.theme 等多层属性访问
|
|
176
|
+
* 预期:在第一层添加 await,变成 (await ctx.user).name
|
|
177
|
+
*/
|
|
178
|
+
test('should add await to the first layer of multi-layer ctx paths', async () => {
|
|
179
|
+
// 多层路径 - 输入: 'ctx.user.name', 输出: '(await ctx.user).name'
|
|
180
|
+
const expression = 'ctx.user.name';
|
|
181
|
+
const result = await preprocessExpression(expression, ctx);
|
|
182
|
+
|
|
183
|
+
expect(result).toBe('(await ctx.user).name');
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* 测试深层嵌套路径的正确处理
|
|
188
|
+
* 场景:处理 ctx.user.profile.avatar 等深层嵌套访问
|
|
189
|
+
* 预期:仅在第一层添加 await,保持后续访问的同步性
|
|
190
|
+
*/
|
|
191
|
+
test('should correctly handle deeply nested paths', async () => {
|
|
192
|
+
// 深层嵌套 - 输入: 'ctx.user.profile.avatar', 输出: '(await ctx.user).profile.avatar'
|
|
193
|
+
const expression = 'ctx.user.profile.avatar';
|
|
194
|
+
const result = await preprocessExpression(expression, ctx);
|
|
195
|
+
|
|
196
|
+
expect(result).toBe('(await ctx.user).profile.avatar');
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* 复杂表达式支持功能测试组
|
|
202
|
+
*
|
|
203
|
+
* 测试在复杂 JavaScript 表达式中的路径处理能力
|
|
204
|
+
* 验证运算符、方法调用等场景下的正确处理
|
|
205
|
+
*/
|
|
206
|
+
describe('Complex expression support', () => {
|
|
207
|
+
/**
|
|
208
|
+
* 测试包含运算符的复杂表达式处理
|
|
209
|
+
* 场景:表达式包含算术运算符、比较运算符等
|
|
210
|
+
* 预期:正确识别并处理所有 ctx 路径,不影响运算符
|
|
211
|
+
*/
|
|
212
|
+
test('should correctly handle expressions containing operators', async () => {
|
|
213
|
+
// 运算符表达式 - 输入: 'ctx.user.age > 18 && ctx.config.debug', 正确处理所有ctx路径'
|
|
214
|
+
const expression = 'ctx.user.age > 18 && ctx.config.debug';
|
|
215
|
+
const result = await preprocessExpression(expression, ctx);
|
|
216
|
+
|
|
217
|
+
expect(result).toBe('(await ctx.user).age > 18 && (await ctx.config).debug');
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* 测试包含数组索引访问的表达式处理
|
|
222
|
+
* 场景:表达式包含数组索引语法,如 ctx.items[0]
|
|
223
|
+
* 预期:正确处理路径部分,保持数组索引语法不变
|
|
224
|
+
*/
|
|
225
|
+
test('should correctly handle expressions containing array indices', async () => {
|
|
226
|
+
const expression = 'ctx.items[0].name';
|
|
227
|
+
const result = await preprocessExpression(expression, ctx);
|
|
228
|
+
|
|
229
|
+
expect(result).toBe('(await ctx.items)[0].name');
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* 测试多个 ctx 路径的批量处理
|
|
234
|
+
* 场景:单个表达式中包含多个不同的 ctx 路径
|
|
235
|
+
* 预期:正确识别并处理所有路径,按长度排序避免冲突
|
|
236
|
+
*/
|
|
237
|
+
test('should correctly handle complex expressions with multiple ctx paths', async () => {
|
|
238
|
+
const expression = 'ctx.user.name + " - " + ctx.config.theme + " - " + ctx.count';
|
|
239
|
+
const result = await preprocessExpression(expression, ctx);
|
|
240
|
+
|
|
241
|
+
expect(result).toBe('(await ctx.user).name + " - " + (await ctx.config).theme + " - " + await ctx.count');
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* 测试路径长度排序的冲突避免机制
|
|
246
|
+
* 场景:表达式包含前缀相似的路径,如 ctx.user 和 ctx.user.name
|
|
247
|
+
* 预期:长路径优先处理,避免短路径替换影响长路径
|
|
248
|
+
*/
|
|
249
|
+
test('should sort by path length to avoid replacement conflicts', async () => {
|
|
250
|
+
const expression = 'ctx.user.name.length + ctx.user.age';
|
|
251
|
+
const result = await preprocessExpression(expression, ctx);
|
|
252
|
+
|
|
253
|
+
expect(result).toBe('(await ctx.user).name.length + (await ctx.user).age');
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* 边界情况处理功能测试组
|
|
259
|
+
*
|
|
260
|
+
* 测试各种边界情况和异常场景的处理能力
|
|
261
|
+
* 验证函数调用排除、错误处理等机制
|
|
262
|
+
*/
|
|
263
|
+
describe('Edge case handling', () => {
|
|
264
|
+
/**
|
|
265
|
+
* 测试函数调用的正确排除
|
|
266
|
+
* 场景:表达式包含 ctx.method() 形式的函数调用
|
|
267
|
+
* 预期:函数调用不被当作路径处理,保持原始形式
|
|
268
|
+
* 核心功能:验证函数调用识别和排除机制的准确性
|
|
269
|
+
*/
|
|
270
|
+
test('should exclude function calls and not perform path processing', async () => {
|
|
271
|
+
const expression = 'ctx.method() + ctx.user.name';
|
|
272
|
+
const result = await preprocessExpression(expression, ctx);
|
|
273
|
+
|
|
274
|
+
expect(result).toBe('ctx.method() + (await ctx.user).name');
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* 测试带空格的函数调用排除
|
|
279
|
+
* 场景:函数调用前有空格,如 ctx.method ()
|
|
280
|
+
* 预期:正确识别为函数调用并排除处理
|
|
281
|
+
* 核心功能:验证空格容忍的函数调用识别机制
|
|
282
|
+
*/
|
|
283
|
+
test('should exclude function calls with spaces', async () => {
|
|
284
|
+
const expression = 'ctx.method () + ctx.config.theme';
|
|
285
|
+
const result = await preprocessExpression(expression, ctx);
|
|
286
|
+
|
|
287
|
+
expect(result).toBe('ctx.method () + (await ctx.config).theme');
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* resolveExpressions 测试套件
|
|
294
|
+
*
|
|
295
|
+
* resolveExpressions 是参数表达式解析器,提供以下核心功能:
|
|
296
|
+
*
|
|
297
|
+
* 1. **表达式解析与求值**
|
|
298
|
+
* - 支持单表达式 `{{ ctx.user.name }}` 和多表达式模板字符串
|
|
299
|
+
* - 使用 SES (Secure ECMAScript) 沙箱环境安全执行 JavaScript 代码
|
|
300
|
+
* - 支持复杂表达式:运算符、方法调用、条件判断等
|
|
301
|
+
*
|
|
302
|
+
* 2. **RecordProxy**
|
|
303
|
+
* - 自动检测 RecordProxy 实例
|
|
304
|
+
* - 对 RecordProxy 深层路径使用整体 await,避免多次数据库请求
|
|
305
|
+
* - 普通对象使用分步解析,支持嵌套属性访问
|
|
306
|
+
*
|
|
307
|
+
* 3. **类型安全与错误处理**
|
|
308
|
+
* - 表达式执行失败时返回原始字符串,保证数据完整性
|
|
309
|
+
* - 支持各种数据类型:字符串、数字、对象、数组、null/undefined
|
|
310
|
+
* - 完善的边界情况处理和容错机制
|
|
311
|
+
*
|
|
312
|
+
* 测试结构:
|
|
313
|
+
* - 静态内容处理: 不包含表达式的参数原样返回
|
|
314
|
+
* - 单表达式解析: 基础的 `{{ }}` 表达式解析功能
|
|
315
|
+
* - 多表达式解析: 模板字符串中包含多个表达式
|
|
316
|
+
* - 对象和数组遍历: 复杂数据结构的递归解析
|
|
317
|
+
* - RecordProxy 支持: 数据库关联对象的智能处理
|
|
318
|
+
* - 复杂表达式支持: 运算符、方法调用等高级表达式
|
|
319
|
+
* - 边界情况和错误处理: 异常情况的容错处理
|
|
320
|
+
*/
|
|
321
|
+
describe('resolveExpressions', () => {
|
|
322
|
+
let engine: FlowEngine;
|
|
323
|
+
let model: FlowModel;
|
|
324
|
+
let ctx: FlowRuntimeContext;
|
|
325
|
+
|
|
326
|
+
beforeEach(() => {
|
|
327
|
+
// 创建真实的上下文环境
|
|
328
|
+
engine = new FlowEngine();
|
|
329
|
+
model = engine.createModel({ use: 'FlowModel' });
|
|
330
|
+
ctx = new FlowRuntimeContext(model, 'test-flow', 'runtime');
|
|
331
|
+
|
|
332
|
+
// 设置测试数据
|
|
333
|
+
ctx.defineProperty('user', {
|
|
334
|
+
value: {
|
|
335
|
+
name: 'John Doe',
|
|
336
|
+
age: 30,
|
|
337
|
+
profile: {
|
|
338
|
+
email: 'john@example.com',
|
|
339
|
+
role: 'admin',
|
|
340
|
+
},
|
|
341
|
+
},
|
|
342
|
+
});
|
|
343
|
+
ctx.defineProperty('config', {
|
|
344
|
+
value: {
|
|
345
|
+
theme: 'dark',
|
|
346
|
+
notifications: true,
|
|
347
|
+
},
|
|
348
|
+
});
|
|
349
|
+
ctx.defineProperty('items', {
|
|
350
|
+
value: [
|
|
351
|
+
{ id: 1, title: 'Item 1' },
|
|
352
|
+
{ id: 2, title: 'Item 2' },
|
|
353
|
+
],
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
// 设置数值数据用于运算测试
|
|
357
|
+
ctx.defineProperty('aa', {
|
|
358
|
+
value: {
|
|
359
|
+
bb: 10,
|
|
360
|
+
},
|
|
361
|
+
});
|
|
362
|
+
ctx.defineProperty('cc', { value: 5 });
|
|
363
|
+
|
|
364
|
+
// 设置方法用于方法调用测试
|
|
365
|
+
ctx.defineMethod('method1', (a, b) => {
|
|
366
|
+
return a + b;
|
|
367
|
+
});
|
|
368
|
+
ctx.defineMethod('multiply', (x, y) => {
|
|
369
|
+
return x * y;
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
// 获取数据源管理器并创建集合定义
|
|
373
|
+
const dataSourceManager = engine.context.dataSourceManager;
|
|
374
|
+
const dataSource = dataSourceManager.getDataSource('main');
|
|
375
|
+
|
|
376
|
+
// 创建完整的集合定义
|
|
377
|
+
const usersCollection = new Collection({
|
|
378
|
+
name: 'users',
|
|
379
|
+
filterTargetKey: 'id',
|
|
380
|
+
fields: [
|
|
381
|
+
{ name: 'id', type: 'integer' },
|
|
382
|
+
{ name: 'name', type: 'string' },
|
|
383
|
+
{ name: 'posts', type: 'hasMany', target: 'posts' },
|
|
384
|
+
],
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
const postsCollection = new Collection({
|
|
388
|
+
name: 'posts',
|
|
389
|
+
filterTargetKey: 'id',
|
|
390
|
+
fields: [
|
|
391
|
+
{ name: 'id', type: 'integer' },
|
|
392
|
+
{ name: 'title', type: 'string' },
|
|
393
|
+
{ name: 'content', type: 'string' },
|
|
394
|
+
],
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
// 将集合添加到数据源
|
|
398
|
+
dataSource.addCollection(usersCollection);
|
|
399
|
+
dataSource.addCollection(postsCollection);
|
|
400
|
+
|
|
401
|
+
// Mock APIClient request method
|
|
402
|
+
const mockApiRequest = vi.fn();
|
|
403
|
+
model.context.defineProperty('api', {
|
|
404
|
+
get: () => ({
|
|
405
|
+
request: mockApiRequest,
|
|
406
|
+
}),
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
const mockRecord = {
|
|
410
|
+
id: 1,
|
|
411
|
+
name: 'John Doe',
|
|
412
|
+
posts: [
|
|
413
|
+
{ id: 1, title: 'Post 1', content: 'Content 1' },
|
|
414
|
+
{ id: 2, title: 'Post 2', content: 'Content 2' },
|
|
415
|
+
],
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
// 创建 RecordProxy 实例
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
// 测试核心功能:单表达式解析
|
|
422
|
+
// 验证 {{ }} 表达式的解析能力,包括简单属性访问和嵌套路径访问
|
|
423
|
+
describe('Single expression resolution', () => {
|
|
424
|
+
// 简单表达式 - 输入: {{ctx.user.name}}, 输出: 'John Doe'
|
|
425
|
+
test('should resolve simple context property access', async () => {
|
|
426
|
+
const params = '{{ctx.user.name}}';
|
|
427
|
+
|
|
428
|
+
const result = await resolveExpressions(params, ctx);
|
|
429
|
+
|
|
430
|
+
expect(result).toEqual('John Doe');
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
// 简单表达式 - 输入: {{ctx.user.name}}, 输出: 'John Doe'
|
|
434
|
+
test('should resolve simple context property access', async () => {
|
|
435
|
+
const params = {
|
|
436
|
+
userName: '{{ctx.user.name}}',
|
|
437
|
+
};
|
|
438
|
+
|
|
439
|
+
const result = await resolveExpressions(params, ctx);
|
|
440
|
+
|
|
441
|
+
expect(result).toEqual({
|
|
442
|
+
userName: 'John Doe',
|
|
443
|
+
});
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
// 深层属性 - 输入: {{ctx.user.profile.email}}, 输出: 'john@example.com'
|
|
447
|
+
test('should resolve deeply nested property paths', async () => {
|
|
448
|
+
const params = {
|
|
449
|
+
email: '{{ctx.user.profile.email}}',
|
|
450
|
+
};
|
|
451
|
+
|
|
452
|
+
const result = await resolveExpressions(params, ctx);
|
|
453
|
+
|
|
454
|
+
expect(result).toEqual({
|
|
455
|
+
email: 'john@example.com',
|
|
456
|
+
});
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
// 复杂对象 - 输入: {{ctx.user}}, 输出: 完整用户对象
|
|
460
|
+
test('should resolve expressions returning complex objects', async () => {
|
|
461
|
+
const params = {
|
|
462
|
+
userData: '{{ctx.user}}',
|
|
463
|
+
};
|
|
464
|
+
|
|
465
|
+
const result = await resolveExpressions(params, ctx);
|
|
466
|
+
|
|
467
|
+
expect(result).toEqual({
|
|
468
|
+
userData: {
|
|
469
|
+
name: 'John Doe',
|
|
470
|
+
age: 30,
|
|
471
|
+
profile: {
|
|
472
|
+
email: 'john@example.com',
|
|
473
|
+
role: 'admin',
|
|
474
|
+
},
|
|
475
|
+
},
|
|
476
|
+
});
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
// 数组类型 - 输入: {{ctx.items}}, 输出: 数组对象
|
|
480
|
+
test('should resolve array type expressions', async () => {
|
|
481
|
+
const params = {
|
|
482
|
+
itemList: '{{ctx.items}}',
|
|
483
|
+
};
|
|
484
|
+
|
|
485
|
+
const result = await resolveExpressions(params, ctx);
|
|
486
|
+
|
|
487
|
+
expect(result).toEqual({
|
|
488
|
+
itemList: [
|
|
489
|
+
{ id: 1, title: 'Item 1' },
|
|
490
|
+
{ id: 2, title: 'Item 2' },
|
|
491
|
+
],
|
|
492
|
+
});
|
|
493
|
+
});
|
|
494
|
+
});
|
|
495
|
+
|
|
496
|
+
// 测试高级功能:多表达式模板字符串
|
|
497
|
+
// 验证在单个字符串中包含多个 {{ }} 表达式的解析和替换能力
|
|
498
|
+
describe('Multiple expressions in template strings', () => {
|
|
499
|
+
/**
|
|
500
|
+
* 测试多表达式模板字符串的解析
|
|
501
|
+
* 场景:解析包含多个 {{ }} 表达式的模板字符串
|
|
502
|
+
* 预期:正确识别并替换所有表达式,生成最终的文本内容
|
|
503
|
+
* 核心功能:验证模板字符串处理能力和表达式批量替换功能
|
|
504
|
+
*/
|
|
505
|
+
test('should resolve multiple expressions in template strings', async () => {
|
|
506
|
+
const params = {
|
|
507
|
+
message: 'User: {{ctx.user.name}}, Age: {{ctx.user.age}}',
|
|
508
|
+
profileInfo: 'Profile: {{ctx.user.profile}}',
|
|
509
|
+
welcomeMessage: 'Welcome {{ctx.user.name}}! Your theme is {{ctx.config.theme}}.',
|
|
510
|
+
};
|
|
511
|
+
|
|
512
|
+
const result = await resolveExpressions(params, ctx);
|
|
513
|
+
|
|
514
|
+
expect(result).toEqual({
|
|
515
|
+
message: 'User: John Doe, Age: 30',
|
|
516
|
+
profileInfo: 'Profile: {"email":"john@example.com","role":"admin"}',
|
|
517
|
+
welcomeMessage: 'Welcome John Doe! Your theme is dark.',
|
|
518
|
+
});
|
|
519
|
+
});
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
describe('Expression resolution in objects', () => {
|
|
523
|
+
test('should recursively resolve expressions in objects and preserve types', async () => {
|
|
524
|
+
const params = {
|
|
525
|
+
greeting: 'Hello {{ctx.user.name}}',
|
|
526
|
+
userInfo: {
|
|
527
|
+
email: '{{ctx.user.profile.email}}',
|
|
528
|
+
role: '{{ctx.user.profile.role}}',
|
|
529
|
+
},
|
|
530
|
+
static: 'No expressions here',
|
|
531
|
+
// 测试单个表达式的类型保持
|
|
532
|
+
user: '{{ctx.user}}',
|
|
533
|
+
age: '{{ctx.user.age}}',
|
|
534
|
+
config: '{{ctx.config}}',
|
|
535
|
+
};
|
|
536
|
+
|
|
537
|
+
const result = await resolveExpressions(params, ctx);
|
|
538
|
+
|
|
539
|
+
expect(result).toEqual({
|
|
540
|
+
greeting: 'Hello John Doe',
|
|
541
|
+
userInfo: {
|
|
542
|
+
email: 'john@example.com',
|
|
543
|
+
role: 'admin',
|
|
544
|
+
},
|
|
545
|
+
static: 'No expressions here',
|
|
546
|
+
user: {
|
|
547
|
+
name: 'John Doe',
|
|
548
|
+
age: 30,
|
|
549
|
+
profile: {
|
|
550
|
+
email: 'john@example.com',
|
|
551
|
+
role: 'admin',
|
|
552
|
+
},
|
|
553
|
+
},
|
|
554
|
+
age: 30,
|
|
555
|
+
config: {
|
|
556
|
+
theme: 'dark',
|
|
557
|
+
notifications: true,
|
|
558
|
+
},
|
|
559
|
+
});
|
|
560
|
+
});
|
|
561
|
+
});
|
|
562
|
+
|
|
563
|
+
describe('Expression resolution in arrays and complex structures', () => {
|
|
564
|
+
test('should recursively resolve expressions in arrays and nested structures', async () => {
|
|
565
|
+
const params = {
|
|
566
|
+
simpleArray: [
|
|
567
|
+
'Hello {{ctx.user.name}}',
|
|
568
|
+
'{{ctx.user.age}}',
|
|
569
|
+
{
|
|
570
|
+
email: '{{ctx.user.profile.email}}',
|
|
571
|
+
static: 'unchanged',
|
|
572
|
+
},
|
|
573
|
+
],
|
|
574
|
+
complexStructure: {
|
|
575
|
+
users: [
|
|
576
|
+
{ name: '{{ctx.user.name}}', role: 'static-role' },
|
|
577
|
+
{ name: 'Static User', role: '{{ctx.user.profile.role}}' },
|
|
578
|
+
],
|
|
579
|
+
config: ['{{ctx.config.theme}}', 'static-value'],
|
|
580
|
+
},
|
|
581
|
+
};
|
|
582
|
+
|
|
583
|
+
const result = await resolveExpressions(params, ctx);
|
|
584
|
+
|
|
585
|
+
expect(result).toEqual({
|
|
586
|
+
simpleArray: [
|
|
587
|
+
'Hello John Doe',
|
|
588
|
+
30,
|
|
589
|
+
{
|
|
590
|
+
email: 'john@example.com',
|
|
591
|
+
static: 'unchanged',
|
|
592
|
+
},
|
|
593
|
+
],
|
|
594
|
+
complexStructure: {
|
|
595
|
+
users: [
|
|
596
|
+
{ name: 'John Doe', role: 'static-role' },
|
|
597
|
+
{ name: 'Static User', role: 'admin' },
|
|
598
|
+
],
|
|
599
|
+
config: ['dark', 'static-value'],
|
|
600
|
+
},
|
|
601
|
+
});
|
|
602
|
+
});
|
|
603
|
+
});
|
|
604
|
+
|
|
605
|
+
describe('Edge case handling', () => {
|
|
606
|
+
test('should handle non-existent property paths', async () => {
|
|
607
|
+
const params = {
|
|
608
|
+
value: '{{ctx.nonexistent.property}}',
|
|
609
|
+
};
|
|
610
|
+
|
|
611
|
+
const result = await resolveExpressions(params, ctx);
|
|
612
|
+
|
|
613
|
+
// 不存在的属性应该返回 undefined
|
|
614
|
+
expect(result).toEqual({
|
|
615
|
+
value: undefined,
|
|
616
|
+
});
|
|
617
|
+
});
|
|
618
|
+
|
|
619
|
+
test('should handle expressions with various space formats', async () => {
|
|
620
|
+
const params = {
|
|
621
|
+
noSpace: '{{ctx.user.name}}',
|
|
622
|
+
leftSpace: '{{ ctx.user.name}}',
|
|
623
|
+
rightSpace: '{{ctx.user.name }}',
|
|
624
|
+
bothSpace: '{{ ctx.user.name }}',
|
|
625
|
+
};
|
|
626
|
+
|
|
627
|
+
const result = await resolveExpressions(params, ctx);
|
|
628
|
+
|
|
629
|
+
expect(result).toEqual({
|
|
630
|
+
noSpace: 'John Doe',
|
|
631
|
+
leftSpace: 'John Doe',
|
|
632
|
+
rightSpace: 'John Doe',
|
|
633
|
+
bothSpace: 'John Doe',
|
|
634
|
+
});
|
|
635
|
+
});
|
|
636
|
+
|
|
637
|
+
test('should handle null and undefined values', async () => {
|
|
638
|
+
ctx.defineProperty('nullValue', { value: null });
|
|
639
|
+
ctx.defineProperty('undefinedValue', { value: undefined });
|
|
640
|
+
|
|
641
|
+
const params = {
|
|
642
|
+
nullTest: '{{ctx.nullValue}}',
|
|
643
|
+
undefinedTest: '{{ctx.undefinedValue}}',
|
|
644
|
+
};
|
|
645
|
+
|
|
646
|
+
const result = await resolveExpressions(params, ctx);
|
|
647
|
+
|
|
648
|
+
expect(result.nullTest).toBe(null);
|
|
649
|
+
expect(result.undefinedTest).toBe(undefined);
|
|
650
|
+
});
|
|
651
|
+
});
|
|
652
|
+
});
|