@nocobase/flow-engine 2.0.0-alpha.7 → 2.0.0-alpha.71
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/lib/BlockScopedFlowEngine.d.ts +23 -0
- package/lib/BlockScopedFlowEngine.js +91 -0
- package/lib/FlowContextProvider.d.ts +2 -2
- package/lib/FlowContextProvider.js +3 -3
- package/lib/FlowDefinition.d.ts +6 -4
- package/lib/JSRunner.d.ts +6 -0
- package/lib/JSRunner.js +27 -1
- package/lib/ViewScopedFlowEngine.d.ts +1 -1
- package/lib/ViewScopedFlowEngine.js +18 -1
- package/lib/acl/Acl.d.ts +12 -12
- package/lib/acl/Acl.js +88 -30
- package/lib/components/DynamicFlowsEditor.js +2 -4
- package/lib/components/FieldModelRenderer.js +17 -9
- package/lib/components/FieldSkeleton.d.ts +10 -0
- package/lib/components/FieldSkeleton.js +64 -0
- package/lib/components/FlowContextSelector.js +19 -3
- package/lib/components/FlowModelRenderer.d.ts +4 -6
- package/lib/components/FlowModelRenderer.js +35 -53
- package/lib/components/FormItem.js +5 -1
- package/lib/components/MobilePopup.d.ts +20 -0
- package/lib/components/MobilePopup.js +102 -0
- package/lib/components/MobilePopup.style.d.ts +17 -0
- package/lib/components/MobilePopup.style.js +186 -0
- package/lib/components/common/withFlowDesignMode.d.ts +1 -1
- package/lib/components/common/withFlowDesignMode.js +5 -5
- package/lib/components/dnd/gridDragPlanner.d.ts +1 -0
- package/lib/components/dnd/gridDragPlanner.js +53 -1
- package/lib/components/index.d.ts +1 -0
- package/lib/components/index.js +3 -1
- package/lib/components/settings/independents/dropdown/FlowsDropdownButton.js +71 -53
- package/lib/components/settings/wrappers/component/SelectWithTitle.d.ts +19 -0
- package/lib/components/settings/wrappers/component/SelectWithTitle.js +136 -0
- package/lib/components/settings/wrappers/component/SwitchWithTitle.d.ts +10 -0
- package/lib/components/settings/wrappers/component/SwitchWithTitle.js +111 -0
- package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.js +233 -97
- package/lib/components/settings/wrappers/contextual/FlowsContextMenu.js +71 -54
- package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.d.ts +2 -2
- package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.js +63 -23
- package/lib/components/settings/wrappers/contextual/StepSettingsDialog.js +13 -2
- package/lib/components/settings/wrappers/embedded/FlowSettings.js +42 -28
- package/lib/components/settings/wrappers/embedded/FlowsSettings.js +3 -3
- package/lib/components/settings/wrappers/embedded/FlowsSettingsContent.js +52 -32
- package/lib/components/subModel/AddSubModelButton.d.ts +7 -0
- package/lib/components/subModel/AddSubModelButton.js +78 -8
- package/lib/components/subModel/LazyDropdown.js +14 -15
- package/lib/components/subModel/utils.d.ts +1 -1
- package/lib/components/subModel/utils.js +21 -11
- package/lib/components/variables/VariableInput.js +26 -6
- package/lib/components/variables/VariableTag.js +43 -2
- package/lib/components/variables/types.d.ts +2 -0
- package/lib/components/variables/utils.js +4 -2
- package/lib/data-source/index.d.ts +23 -4
- package/lib/data-source/index.js +135 -14
- package/lib/data-source/jioToJoiSchema.js +1 -0
- package/lib/emitter.d.ts +6 -0
- package/lib/emitter.js +12 -0
- package/lib/executor/FlowExecutor.d.ts +6 -6
- package/lib/executor/FlowExecutor.js +302 -99
- package/lib/flow-registry/GlobalFlowRegistry.d.ts +1 -0
- package/lib/flow-registry/GlobalFlowRegistry.js +3 -0
- package/lib/flow-registry/InstanceFlowRegistry.d.ts +1 -0
- package/lib/flow-registry/InstanceFlowRegistry.js +3 -0
- package/lib/flowContext.d.ts +105 -6
- package/lib/flowContext.js +447 -139
- package/lib/flowEngine.d.ts +71 -1
- package/lib/flowEngine.js +319 -16
- package/lib/flowSettings.d.ts +4 -3
- package/lib/flowSettings.js +45 -21
- package/lib/hooks/useApplyAutoFlows.d.ts +1 -0
- package/lib/hooks/useApplyAutoFlows.js +3 -2
- package/lib/index.d.ts +14 -3
- package/lib/index.js +54 -7
- package/lib/locale/de-DE.json +62 -0
- package/lib/locale/en-US.json +57 -45
- package/lib/locale/es-ES.json +62 -0
- package/lib/locale/fr-FR.json +62 -0
- package/lib/locale/hu-HU.json +62 -0
- package/lib/locale/id-ID.json +62 -0
- package/lib/locale/index.d.ts +114 -90
- package/lib/locale/it-IT.json +62 -0
- package/lib/locale/ja-JP.json +62 -0
- package/lib/locale/ko-KR.json +62 -0
- package/lib/locale/nl-NL.json +62 -0
- package/lib/locale/pt-BR.json +62 -0
- package/lib/locale/ru-RU.json +62 -0
- package/lib/locale/tr-TR.json +62 -0
- package/lib/locale/uk-UA.json +62 -0
- package/lib/locale/vi-VN.json +62 -0
- package/lib/locale/zh-CN.json +58 -46
- package/lib/locale/zh-TW.json +62 -0
- package/lib/models/CollectionFieldModel.d.ts +7 -2
- package/lib/models/CollectionFieldModel.js +63 -16
- package/lib/models/flowModel.d.ts +76 -32
- package/lib/models/flowModel.js +300 -112
- package/lib/models/forkFlowModel.d.ts +8 -4
- package/lib/models/forkFlowModel.js +38 -8
- package/lib/provider.d.ts +3 -1
- package/lib/provider.js +14 -11
- package/lib/reactive/index.d.ts +10 -0
- package/lib/{runjs-context/snippets/global/api-request-post.snippet.js → reactive/index.js} +14 -15
- package/lib/reactive/observer.d.ts +19 -0
- package/lib/reactive/observer.js +109 -0
- package/lib/resources/baseRecordResource.d.ts +6 -0
- package/lib/resources/baseRecordResource.js +38 -3
- package/lib/resources/multiRecordResource.d.ts +5 -2
- package/lib/resources/multiRecordResource.js +26 -10
- package/lib/resources/singleRecordResource.js +8 -3
- package/lib/resources/sqlResource.d.ts +5 -3
- package/lib/resources/sqlResource.js +30 -28
- package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.d.ts +1 -6
- package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.js +37 -20
- package/lib/runjs-context/contexts/JSBlockRunJSContext.d.ts +1 -6
- package/lib/runjs-context/contexts/JSBlockRunJSContext.js +46 -33
- package/lib/runjs-context/contexts/JSCollectionActionRunJSContext.d.ts +1 -2
- package/lib/runjs-context/contexts/JSCollectionActionRunJSContext.js +14 -15
- package/lib/runjs-context/contexts/{LinkageRunJSContext.d.ts → JSColumnRunJSContext.d.ts} +6 -3
- package/lib/runjs-context/contexts/JSColumnRunJSContext.js +78 -0
- package/lib/runjs-context/contexts/JSEditableFieldRunJSContext.d.ts +16 -0
- package/lib/runjs-context/contexts/JSEditableFieldRunJSContext.js +125 -0
- package/lib/runjs-context/contexts/JSFieldRunJSContext.d.ts +1 -6
- package/lib/runjs-context/contexts/JSFieldRunJSContext.js +28 -24
- package/lib/runjs-context/contexts/JSItemRunJSContext.d.ts +1 -6
- package/lib/runjs-context/contexts/JSItemRunJSContext.js +34 -20
- package/lib/runjs-context/contexts/JSRecordActionRunJSContext.d.ts +1 -2
- package/lib/runjs-context/contexts/JSRecordActionRunJSContext.js +16 -17
- package/lib/runjs-context/contexts/base.d.ts +9 -0
- package/lib/runjs-context/contexts/base.js +879 -0
- package/lib/runjs-context/contributions.d.ts +33 -0
- package/lib/runjs-context/contributions.js +88 -0
- package/lib/runjs-context/helpers.d.ts +5 -2
- package/lib/runjs-context/helpers.js +36 -27
- package/lib/runjs-context/registry.d.ts +7 -4
- package/lib/runjs-context/registry.js +10 -42
- package/lib/runjs-context/setup.d.ts +9 -0
- package/lib/runjs-context/setup.js +88 -0
- package/lib/runjs-context/snippets/global/{copy-record-json.snippet.js → api-request.snippet.js} +25 -10
- package/lib/runjs-context/snippets/global/clipboard-copy-text.snippet.js +61 -0
- package/lib/runjs-context/snippets/global/{view-navigation-push.snippet.js → import-esm.snippet.js} +26 -12
- package/lib/runjs-context/snippets/global/message-error.snippet.js +6 -0
- package/lib/runjs-context/snippets/global/message-success.snippet.js +6 -0
- package/lib/runjs-context/snippets/global/notification-open.snippet.d.ts +3 -8
- package/lib/runjs-context/snippets/global/notification-open.snippet.js +8 -1
- package/lib/runjs-context/snippets/global/open-view-dialog.snippet.js +10 -3
- package/lib/runjs-context/snippets/global/open-view-drawer.snippet.js +10 -3
- package/lib/runjs-context/snippets/global/query-selector.snippet.js +53 -0
- package/lib/runjs-context/snippets/global/require-amd.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/global/{requireAsync.snippet.js → require-amd.snippet.js} +16 -13
- package/lib/runjs-context/snippets/global/window-open.snippet.d.ts +3 -8
- package/lib/runjs-context/snippets/global/window-open.snippet.js +8 -1
- package/lib/runjs-context/snippets/index.d.ts +24 -3
- package/lib/runjs-context/snippets/index.js +183 -40
- package/lib/runjs-context/snippets/scene/block/add-event-listener.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{jsblock → block}/add-event-listener.snippet.js +11 -2
- package/lib/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.js +64 -0
- package/lib/runjs-context/snippets/scene/block/chartjs-bar.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/chartjs-bar.snippet.js +99 -0
- package/lib/runjs-context/snippets/{libs → scene/block}/echarts-init.snippet.js +24 -7
- package/lib/runjs-context/snippets/scene/block/render-antd-icons.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/render-antd-icons.snippet.js +65 -0
- package/lib/runjs-context/snippets/scene/block/render-button-handler.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{jsblock → block}/render-button-handler.snippet.js +17 -9
- package/lib/runjs-context/snippets/scene/block/render-iframe.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/render-iframe.snippet.js +57 -0
- package/lib/runjs-context/snippets/scene/block/render-info-card.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/render-info-card.snippet.js +71 -0
- package/lib/runjs-context/snippets/scene/block/render-react-jsx.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{jsblock/render-card.snippet.js → block/render-react-jsx.snippet.js} +26 -13
- package/lib/runjs-context/snippets/scene/block/render-react.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{jsblock → block}/render-react.snippet.js +18 -17
- package/lib/runjs-context/snippets/scene/block/render-statistics.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/render-statistics.snippet.js +95 -0
- package/lib/runjs-context/snippets/scene/block/render-timeline.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/render-timeline.snippet.js +84 -0
- package/lib/runjs-context/snippets/scene/block/resource-example.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/resource-example.snippet.js +60 -0
- package/lib/runjs-context/snippets/scene/block/three-users-orbit.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/three-users-orbit.snippet.js +283 -0
- package/lib/runjs-context/snippets/scene/block/vue-component.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/vue-component.snippet.js +124 -0
- package/lib/runjs-context/snippets/scene/detail/color-by-value.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{jsfield → detail}/color-by-value.snippet.js +13 -3
- package/lib/runjs-context/snippets/scene/detail/copy-to-clipboard.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/{global → scene/detail}/copy-to-clipboard.snippet.js +28 -6
- package/lib/runjs-context/snippets/scene/detail/format-number.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{jsfield → detail}/format-number.snippet.js +13 -3
- package/lib/runjs-context/snippets/scene/detail/innerHTML-value.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{jsfield → detail}/innerHTML-value.snippet.js +13 -3
- package/lib/runjs-context/snippets/scene/detail/percentage-bar.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/detail/percentage-bar.snippet.js +82 -0
- package/lib/runjs-context/snippets/scene/detail/relative-time.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/detail/relative-time.snippet.js +80 -0
- package/lib/runjs-context/snippets/scene/detail/status-tag.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/detail/status-tag.snippet.js +74 -0
- package/lib/runjs-context/snippets/scene/form/calculate-total.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/form/calculate-total.snippet.js +63 -0
- package/lib/runjs-context/snippets/scene/form/cascade-select.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/form/cascade-select.snippet.js +81 -0
- package/lib/runjs-context/snippets/scene/form/conditional-required.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/form/conditional-required.snippet.js +64 -0
- package/lib/runjs-context/snippets/scene/form/copy-field-values.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/form/copy-field-values.snippet.js +74 -0
- package/lib/runjs-context/snippets/scene/form/render-basic.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{jsitem → form}/render-basic.snippet.js +11 -2
- package/lib/runjs-context/snippets/scene/form/set-disabled.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{linkage → form}/set-disabled.snippet.js +12 -3
- package/lib/runjs-context/snippets/scene/form/set-field-value.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{linkage → form}/set-field-value.snippet.js +12 -3
- package/lib/runjs-context/snippets/scene/form/set-required.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{linkage → form}/set-required.snippet.js +12 -3
- package/lib/runjs-context/snippets/scene/form/toggle-multiple-fields.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/form/toggle-multiple-fields.snippet.js +67 -0
- package/lib/runjs-context/snippets/scene/form/toggle-visible.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{linkage → form}/toggle-visible.snippet.js +12 -3
- package/lib/runjs-context/snippets/scene/table/cell-open-dialog.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/table/cell-open-dialog.snippet.js +64 -0
- package/lib/runjs-context/snippets/scene/table/collection-selected-count.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{actions → table}/collection-selected-count.snippet.js +11 -2
- package/lib/runjs-context/snippets/scene/table/concat-fields.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/table/concat-fields.snippet.js +79 -0
- package/lib/runjs-context/snippets/scene/table/destroy-selected.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/{global/log-json-record.snippet.js → scene/table/destroy-selected.snippet.js} +24 -11
- package/lib/runjs-context/snippets/scene/table/export-selected-json.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/table/export-selected-json.snippet.js +64 -0
- package/lib/runjs-context/snippets/scene/table/iterate-selected-rows.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{actions → table}/iterate-selected-rows.snippet.js +11 -2
- package/lib/runjs-context/snippets/types.d.ts +9 -1
- package/lib/runjsLibs.d.ts +28 -0
- package/lib/runjsLibs.js +532 -0
- package/lib/scheduler/ModelOperationScheduler.d.ts +53 -0
- package/lib/scheduler/ModelOperationScheduler.js +262 -0
- package/lib/types.d.ts +66 -7
- package/lib/types.js +4 -3
- package/lib/utils/associationObjectVariable.d.ts +32 -0
- package/lib/utils/associationObjectVariable.js +157 -0
- package/lib/utils/createCollectionContextMeta.d.ts +1 -1
- package/lib/utils/createCollectionContextMeta.js +9 -4
- package/lib/utils/createEphemeralContext.d.ts +13 -0
- package/lib/utils/createEphemeralContext.js +140 -0
- package/lib/utils/flows.d.ts +10 -0
- package/lib/{runjs-context/snippets/global/console-log-ctx.snippet.js → utils/flows.js} +21 -14
- package/lib/utils/index.d.ts +9 -3
- package/lib/utils/index.js +30 -2
- package/lib/utils/jsxTransform.d.ts +15 -0
- package/lib/utils/jsxTransform.js +68 -0
- package/lib/utils/params-resolvers.js +19 -12
- package/lib/utils/parsePathnameToViewParams.d.ts +1 -1
- package/lib/utils/parsePathnameToViewParams.js +41 -5
- package/lib/utils/pruneFilter.d.ts +21 -0
- package/lib/{runjs-context/snippets/global/try-catch-async.snippet.js → utils/pruneFilter.js} +24 -16
- package/lib/utils/resolveModuleUrl.d.ts +58 -0
- package/lib/utils/resolveModuleUrl.js +65 -0
- package/lib/utils/runjsModuleLoader.d.ts +58 -0
- package/lib/utils/runjsModuleLoader.js +422 -0
- package/lib/utils/runjsTemplateCompat.d.ts +35 -0
- package/lib/utils/runjsTemplateCompat.js +743 -0
- package/lib/utils/safeGlobals.d.ts +6 -8
- package/lib/utils/safeGlobals.js +169 -14
- package/lib/utils/schema-utils.d.ts +6 -0
- package/lib/utils/schema-utils.js +71 -6
- package/lib/utils/serverContextParams.d.ts +4 -0
- package/lib/utils/serverContextParams.js +2 -0
- package/lib/utils/translation.d.ts +4 -1
- package/lib/utils/translation.js +6 -2
- package/lib/utils/variablesParams.d.ts +22 -5
- package/lib/utils/variablesParams.js +141 -61
- package/lib/views/DialogComponent.js +1 -5
- package/lib/views/DrawerComponent.js +18 -9
- package/lib/views/PageComponent.js +5 -5
- package/lib/views/ViewNavigation.d.ts +11 -15
- package/lib/views/ViewNavigation.js +37 -19
- package/lib/views/createViewMeta.d.ts +27 -5
- package/lib/views/createViewMeta.js +338 -72
- package/lib/views/index.d.ts +1 -1
- package/lib/views/index.js +4 -0
- package/lib/views/useDialog.d.ts +10 -9
- package/lib/views/useDialog.js +46 -34
- package/lib/views/useDrawer.d.ts +10 -9
- package/lib/views/useDrawer.js +74 -48
- package/lib/views/usePage.d.ts +14 -9
- package/lib/views/usePage.js +82 -33
- package/lib/views/usePopover.js +4 -1
- package/lib/views/viewEvents.d.ts +17 -0
- package/lib/views/viewEvents.js +90 -0
- package/package.json +6 -3
- package/src/BlockScopedFlowEngine.ts +85 -0
- package/src/FlowContextProvider.tsx +4 -2
- package/src/JSRunner.ts +39 -1
- package/src/ViewScopedFlowEngine.ts +21 -1
- package/src/__tests__/JSRunner.test.ts +125 -52
- package/src/__tests__/blockScopedFlowEngine.test.ts +154 -0
- package/src/__tests__/createViewMeta.popup.test.ts +203 -0
- package/src/__tests__/flow-engine.test.ts +3 -0
- package/src/__tests__/flowContext.test.ts +160 -0
- package/src/__tests__/flowContextCreateJSRunner.test.ts +163 -0
- package/src/__tests__/flowEngine.dataSourceDirty.test.ts +63 -0
- package/src/__tests__/flowEngine.destroyModel.test.ts +74 -0
- package/src/__tests__/flowEngine.moveModel.test.ts +43 -0
- package/src/__tests__/flowEngine.removeModel.test.ts +72 -0
- package/src/__tests__/flowEngine.saveModel.test.ts +4 -0
- package/src/__tests__/flowModel.openView.navigation.test.ts +31 -2
- package/src/__tests__/flowRunJSContextDefine.test.ts +508 -0
- package/src/__tests__/flowSettings.open.test.tsx +71 -15
- package/src/__tests__/flowSettings.test.ts +2 -0
- package/src/__tests__/globalFlowRegistry.test.ts +1 -1
- package/src/__tests__/modelOperationScheduler.test.ts +346 -0
- package/src/__tests__/objectVariable.test.ts +464 -0
- package/src/__tests__/provider.test.tsx +0 -5
- package/src/__tests__/runjsContext.test.ts +219 -35
- package/src/__tests__/runjsContextImplementations.test.ts +217 -0
- package/src/__tests__/runjsContextRuntime.test.ts +269 -0
- package/src/__tests__/runjsEdgeCases.test.ts +281 -0
- package/src/__tests__/runjsExternalLibs.test.ts +242 -0
- package/src/__tests__/runjsLibsLazyLoading.test.ts +44 -0
- package/src/__tests__/runjsLocales.test.ts +39 -0
- package/src/__tests__/runjsPreprocessDefault.test.ts +49 -0
- package/src/__tests__/runjsRuntimeFeatures.test.ts +461 -0
- package/src/__tests__/runjsSnippets.test.ts +140 -0
- package/src/__tests__/viewScopedFlowEngine.test.ts +101 -3
- package/src/acl/Acl.tsx +85 -31
- package/src/acl/__tests__/Acl.test.tsx +43 -1
- package/src/components/DynamicFlowsEditor.tsx +0 -10
- package/src/components/FieldModelRenderer.tsx +22 -9
- package/src/components/FieldSkeleton.tsx +27 -0
- package/src/components/FlowContextSelector.tsx +20 -2
- package/src/components/FlowModelRenderer.tsx +52 -84
- package/src/components/FormItem.tsx +8 -1
- package/src/components/MobilePopup.style.ts +220 -0
- package/src/components/MobilePopup.tsx +86 -0
- package/src/components/__tests__/FlowModelRenderer.test.tsx +89 -0
- package/src/components/__tests__/flow-model-render-error-fallback.test.tsx +6 -6
- package/src/components/__tests__/gridDragPlanner.test.ts +141 -1
- package/src/components/common/withFlowDesignMode.tsx +5 -5
- package/src/components/dnd/gridDragPlanner.ts +60 -0
- package/src/components/index.ts +1 -0
- package/src/components/settings/independents/dropdown/FlowsDropdownButton.tsx +34 -17
- package/src/components/settings/wrappers/component/SelectWithTitle.tsx +110 -0
- package/src/components/settings/wrappers/component/SwitchWithTitle.tsx +83 -0
- package/src/components/settings/wrappers/component/__tests__/InlineControls.test.tsx +74 -0
- package/src/components/settings/wrappers/contextual/DefaultSettingsIcon.tsx +272 -125
- package/src/components/settings/wrappers/contextual/FlowsContextMenu.tsx +34 -18
- package/src/components/settings/wrappers/contextual/FlowsFloatContextMenu.tsx +56 -18
- package/src/components/settings/wrappers/contextual/StepSettings.tsx +1 -2
- package/src/components/settings/wrappers/contextual/StepSettingsDialog.tsx +13 -1
- package/src/components/settings/wrappers/contextual/__tests__/DefaultSettingsIcon.test.tsx +624 -0
- package/src/components/settings/wrappers/embedded/FlowSettings.tsx +47 -35
- package/src/components/settings/wrappers/embedded/FlowsSettings.tsx +1 -1
- package/src/components/settings/wrappers/embedded/FlowsSettingsContent.tsx +64 -42
- package/src/components/subModel/AddSubModelButton.tsx +104 -9
- package/src/components/subModel/LazyDropdown.tsx +14 -14
- package/src/components/subModel/__tests__/AddSubModelButton.test.tsx +168 -7
- package/src/components/subModel/__tests__/utils.test.ts +12 -12
- package/src/components/subModel/utils.ts +25 -6
- package/src/components/variables/VariableInput.tsx +32 -6
- package/src/components/variables/VariableTag.tsx +54 -2
- package/src/components/variables/types.ts +2 -0
- package/src/components/variables/utils.ts +7 -3
- package/src/data-source/index.ts +143 -12
- package/src/data-source/jioToJoiSchema.ts +1 -0
- package/src/emitter.ts +14 -0
- package/src/executor/FlowExecutor.ts +383 -119
- package/src/executor/__tests__/ctx-defs-injection.test.ts +197 -0
- package/src/executor/__tests__/flowExecutor.test.ts +217 -5
- package/src/flow-registry/GlobalFlowRegistry.ts +1 -0
- package/src/flow-registry/InstanceFlowRegistry.ts +1 -0
- package/src/flow-registry/__tests__/globalFlowRegistry.test.ts +54 -0
- package/src/flowContext.ts +646 -158
- package/src/flowEngine.ts +385 -14
- package/src/flowSettings.ts +59 -30
- package/src/hooks/useApplyAutoFlows.ts +5 -3
- package/src/index.ts +26 -3
- package/src/locale/de-DE.json +62 -0
- package/src/locale/en-US.json +57 -45
- package/src/locale/es-ES.json +62 -0
- package/src/locale/fr-FR.json +62 -0
- package/src/locale/hu-HU.json +62 -0
- package/src/locale/id-ID.json +62 -0
- package/src/locale/it-IT.json +62 -0
- package/src/locale/ja-JP.json +62 -0
- package/src/locale/ko-KR.json +62 -0
- package/src/locale/nl-NL.json +62 -0
- package/src/locale/pt-BR.json +62 -0
- package/src/locale/ru-RU.json +62 -0
- package/src/locale/tr-TR.json +62 -0
- package/src/locale/uk-UA.json +62 -0
- package/src/locale/vi-VN.json +62 -0
- package/src/locale/zh-CN.json +58 -46
- package/src/locale/zh-TW.json +62 -0
- package/src/models/CollectionFieldModel.tsx +82 -18
- package/src/models/__tests__/dispatchEvent.behavior.test.ts +169 -0
- package/src/models/__tests__/dispatchEvent.when.test.ts +356 -0
- package/src/models/__tests__/flowEngine.resolveUse.test.ts +170 -0
- package/src/models/__tests__/flowModel.clone.test.ts +416 -0
- package/src/models/__tests__/flowModel.getFlows.sort.test.ts +33 -9
- package/src/models/__tests__/flowModel.scheduleModelOperation.test.tsx +129 -0
- package/src/models/__tests__/flowModel.test.ts +296 -119
- package/src/models/__tests__/forkFlowModel.test.ts +40 -7
- package/src/models/flowModel.tsx +426 -148
- package/src/models/forkFlowModel.ts +48 -8
- package/src/provider.tsx +18 -14
- package/src/reactive/__tests__/observer.test.tsx +211 -0
- package/src/reactive/index.ts +11 -0
- package/src/reactive/observer.tsx +101 -0
- package/src/resources/__tests__/multiRecordResource.test.ts +44 -0
- package/src/resources/__tests__/sqlResource.test.ts +60 -0
- package/src/resources/baseRecordResource.ts +46 -3
- package/src/resources/multiRecordResource.ts +28 -12
- package/src/resources/singleRecordResource.ts +9 -3
- package/src/resources/sqlResource.ts +33 -32
- package/src/runjs-context/contexts/FormJSFieldItemRunJSContext.ts +38 -21
- package/src/runjs-context/contexts/JSBlockRunJSContext.ts +50 -34
- package/src/runjs-context/contexts/JSCollectionActionRunJSContext.ts +15 -16
- package/src/runjs-context/contexts/JSColumnRunJSContext.ts +58 -0
- package/src/runjs-context/contexts/JSEditableFieldRunJSContext.ts +106 -0
- package/src/runjs-context/contexts/JSFieldRunJSContext.ts +30 -25
- package/src/runjs-context/contexts/JSItemRunJSContext.ts +35 -21
- package/src/runjs-context/contexts/JSRecordActionRunJSContext.ts +17 -18
- package/src/runjs-context/contexts/base.ts +871 -0
- package/src/runjs-context/contributions.ts +88 -0
- package/src/runjs-context/helpers.ts +32 -30
- package/src/runjs-context/registry.ts +16 -47
- package/src/runjs-context/setup.ts +57 -0
- package/src/runjs-context/snippets/global/api-request.snippet.ts +38 -0
- package/src/runjs-context/snippets/global/clipboard-copy-text.snippet.ts +42 -0
- package/src/runjs-context/snippets/global/import-esm.snippet.ts +39 -0
- package/src/runjs-context/snippets/global/message-error.snippet.ts +6 -0
- package/src/runjs-context/snippets/global/message-success.snippet.ts +6 -0
- package/src/runjs-context/snippets/global/notification-open.snippet.ts +11 -1
- package/src/runjs-context/snippets/global/open-view-dialog.snippet.ts +10 -3
- package/src/runjs-context/snippets/global/open-view-drawer.snippet.ts +10 -3
- package/src/runjs-context/snippets/global/query-selector.snippet.ts +34 -0
- package/src/runjs-context/snippets/global/require-amd.snippet.ts +30 -0
- package/src/runjs-context/snippets/global/window-open.snippet.ts +11 -1
- package/src/runjs-context/snippets/index.ts +212 -39
- package/src/runjs-context/snippets/scene/{jsblock → block}/add-event-listener.snippet.ts +14 -2
- package/src/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.ts +45 -0
- package/src/runjs-context/snippets/scene/block/chartjs-bar.snippet.ts +80 -0
- package/src/runjs-context/snippets/scene/block/echarts-init.snippet.ts +44 -0
- package/src/runjs-context/snippets/scene/block/render-antd-icons.snippet.ts +46 -0
- package/src/runjs-context/snippets/scene/block/render-button-handler.snippet.ts +35 -0
- package/src/runjs-context/snippets/scene/block/render-iframe.snippet.ts +38 -0
- package/src/runjs-context/snippets/scene/block/render-info-card.snippet.ts +52 -0
- package/src/runjs-context/snippets/scene/block/render-react-jsx.snippet.ts +39 -0
- package/src/runjs-context/snippets/scene/block/render-react.snippet.ts +38 -0
- package/src/runjs-context/snippets/scene/block/render-statistics.snippet.ts +76 -0
- package/src/runjs-context/snippets/scene/block/render-timeline.snippet.ts +65 -0
- package/src/runjs-context/snippets/scene/block/resource-example.snippet.ts +46 -0
- package/src/runjs-context/snippets/scene/block/three-users-orbit.snippet.ts +264 -0
- package/src/runjs-context/snippets/scene/block/vue-component.snippet.ts +105 -0
- package/src/runjs-context/snippets/scene/detail/color-by-value.snippet.ts +33 -0
- package/src/runjs-context/snippets/scene/detail/copy-to-clipboard.snippet.ts +45 -0
- package/src/runjs-context/snippets/scene/detail/format-number.snippet.ts +32 -0
- package/src/runjs-context/snippets/scene/detail/innerHTML-value.snippet.ts +31 -0
- package/src/runjs-context/snippets/scene/detail/percentage-bar.snippet.ts +63 -0
- package/src/runjs-context/snippets/scene/detail/relative-time.snippet.ts +61 -0
- package/src/runjs-context/snippets/scene/detail/status-tag.snippet.ts +55 -0
- package/src/runjs-context/snippets/scene/form/calculate-total.snippet.ts +44 -0
- package/src/runjs-context/snippets/scene/form/cascade-select.snippet.ts +62 -0
- package/src/runjs-context/snippets/scene/form/conditional-required.snippet.ts +45 -0
- package/src/runjs-context/snippets/scene/form/copy-field-values.snippet.ts +55 -0
- package/src/runjs-context/snippets/scene/{jsitem → form}/render-basic.snippet.ts +14 -2
- package/src/runjs-context/snippets/scene/{linkage → form}/set-disabled.snippet.ts +15 -3
- package/src/runjs-context/snippets/scene/{linkage → form}/set-field-value.snippet.ts +15 -3
- package/src/runjs-context/snippets/scene/{linkage → form}/set-required.snippet.ts +15 -3
- package/src/runjs-context/snippets/scene/form/toggle-multiple-fields.snippet.ts +48 -0
- package/src/runjs-context/snippets/scene/{linkage → form}/toggle-visible.snippet.ts +15 -3
- package/src/runjs-context/snippets/scene/table/cell-open-dialog.snippet.ts +45 -0
- package/src/runjs-context/snippets/scene/{actions → table}/collection-selected-count.snippet.ts +14 -2
- package/src/runjs-context/snippets/scene/table/concat-fields.snippet.ts +60 -0
- package/src/runjs-context/snippets/scene/table/destroy-selected.snippet.ts +36 -0
- package/src/runjs-context/snippets/scene/table/export-selected-json.snippet.ts +45 -0
- package/src/runjs-context/snippets/scene/{actions → table}/iterate-selected-rows.snippet.ts +14 -2
- package/src/runjs-context/snippets/types.ts +5 -1
- package/src/runjsLibs.ts +622 -0
- package/src/scheduler/ModelOperationScheduler.ts +306 -0
- package/src/types.ts +86 -5
- package/src/utils/__tests__/createCollectionContextMeta.test.ts +51 -0
- package/src/utils/__tests__/flows.test.ts +65 -0
- package/src/utils/__tests__/jsxTransform.test.ts +38 -0
- package/src/utils/__tests__/params-resolvers.test.ts +40 -0
- package/src/utils/__tests__/parsePathnameToViewParams.test.ts +25 -0
- package/src/utils/__tests__/pruneFilter.test.ts +38 -0
- package/src/utils/__tests__/runjsRequireAsyncAutoWhitelist.test.ts +38 -0
- package/src/utils/__tests__/runjsTemplateCompat.test.ts +159 -0
- package/src/utils/__tests__/safeGlobals.test.ts +79 -2
- package/src/utils/__tests__/utils.test.ts +114 -15
- package/src/utils/__tests__/variablesParams.test.ts +120 -0
- package/src/utils/associationObjectVariable.ts +180 -0
- package/src/utils/createCollectionContextMeta.ts +9 -3
- package/src/utils/createEphemeralContext.ts +142 -0
- package/src/utils/flows.ts +23 -0
- package/src/utils/index.ts +17 -3
- package/src/utils/jsxTransform.ts +39 -0
- package/src/utils/params-resolvers.ts +25 -11
- package/src/utils/parsePathnameToViewParams.ts +50 -6
- package/src/utils/pruneFilter.ts +41 -0
- package/src/utils/resolveModuleUrl.ts +91 -0
- package/src/utils/runjsModuleLoader.ts +553 -0
- package/src/utils/runjsTemplateCompat.ts +828 -0
- package/src/utils/safeGlobals.ts +181 -15
- package/src/utils/schema-utils.ts +81 -3
- package/src/utils/serverContextParams.ts +6 -0
- package/src/utils/translation.ts +7 -2
- package/src/utils/variablesParams.ts +164 -72
- package/src/views/DialogComponent.tsx +1 -4
- package/src/views/DrawerComponent.tsx +19 -7
- package/src/views/PageComponent.tsx +3 -5
- package/src/views/ViewNavigation.ts +49 -43
- package/src/views/__tests__/FlowView.usePage.test.tsx +186 -0
- package/src/views/__tests__/ViewNavigation.test.ts +54 -34
- package/src/views/__tests__/useDialog.closeDestroy.test.tsx +159 -0
- package/src/views/__tests__/viewEvents.resolveOpenerEngine.test.ts +28 -0
- package/src/views/createViewMeta.ts +402 -73
- package/src/views/index.tsx +1 -1
- package/src/views/useDialog.tsx +52 -31
- package/src/views/useDrawer.tsx +99 -55
- package/src/views/usePage.tsx +101 -33
- package/src/views/usePopover.tsx +4 -1
- package/src/views/viewEvents.ts +55 -0
- package/lib/runjs-context/contexts/FlowRunJSContext.d.ts +0 -38
- package/lib/runjs-context/contexts/FlowRunJSContext.js +0 -217
- package/lib/runjs-context/contexts/LinkageRunJSContext.js +0 -62
- package/lib/runjs-context/index.d.ts +0 -19
- package/lib/runjs-context/index.js +0 -57
- package/lib/runjs-context/snippets/global/api-request-get.snippet.d.ts +0 -16
- package/lib/runjs-context/snippets/global/api-request-get.snippet.js +0 -42
- package/lib/runjs-context/snippets/global/api-request-post.snippet.d.ts +0 -16
- package/lib/runjs-context/snippets/global/console-log-ctx.snippet.d.ts +0 -16
- package/lib/runjs-context/snippets/global/requireAsync.snippet.d.ts +0 -16
- package/lib/runjs-context/snippets/global/sleep.snippet.d.ts +0 -16
- package/lib/runjs-context/snippets/global/sleep.snippet.js +0 -43
- package/lib/runjs-context/snippets/global/try-catch-async.snippet.d.ts +0 -16
- package/lib/runjs-context/snippets/libs/echarts-init.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/actions/collection-selected-count.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/actions/iterate-selected-rows.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/actions/record-id-message.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/actions/record-id-message.snippet.js +0 -43
- package/lib/runjs-context/snippets/scene/actions/run-action-basic.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/actions/run-action-basic.snippet.js +0 -40
- package/lib/runjs-context/snippets/scene/jsblock/add-event-listener.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsblock/append-style.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsblock/append-style.snippet.js +0 -42
- package/lib/runjs-context/snippets/scene/jsblock/jsx-mount.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsblock/jsx-mount.snippet.js +0 -46
- package/lib/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.js +0 -41
- package/lib/runjs-context/snippets/scene/jsblock/render-basic.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsblock/render-basic.snippet.js +0 -41
- package/lib/runjs-context/snippets/scene/jsblock/render-button-handler.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsblock/render-react.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsfield/color-by-value.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsfield/format-number.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsfield/innerHTML-value.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsitem/render-basic.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/linkage/set-disabled.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/linkage/set-field-value.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/linkage/set-required.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/linkage/toggle-visible.snippet.d.ts +0 -15
- package/src/runjs-context/contexts/FlowRunJSContext.ts +0 -190
- package/src/runjs-context/contexts/LinkageRunJSContext.ts +0 -35
- package/src/runjs-context/index.ts +0 -20
- package/src/runjs-context/snippets/global/api-request-get.snippet.ts +0 -20
- package/src/runjs-context/snippets/global/api-request-post.snippet.ts +0 -20
- package/src/runjs-context/snippets/global/console-log-ctx.snippet.ts +0 -19
- package/src/runjs-context/snippets/global/copy-record-json.snippet.ts +0 -21
- package/src/runjs-context/snippets/global/copy-to-clipboard.snippet.ts +0 -21
- package/src/runjs-context/snippets/global/log-json-record.snippet.ts +0 -21
- package/src/runjs-context/snippets/global/requireAsync.snippet.ts +0 -24
- package/src/runjs-context/snippets/global/sleep.snippet.ts +0 -21
- package/src/runjs-context/snippets/global/try-catch-async.snippet.ts +0 -22
- package/src/runjs-context/snippets/global/view-navigation-push.snippet.ts +0 -23
- package/src/runjs-context/snippets/libs/echarts-init.snippet.ts +0 -24
- package/src/runjs-context/snippets/scene/actions/record-id-message.snippet.ts +0 -21
- package/src/runjs-context/snippets/scene/actions/run-action-basic.snippet.ts +0 -18
- package/src/runjs-context/snippets/scene/jsblock/append-style.snippet.ts +0 -20
- package/src/runjs-context/snippets/scene/jsblock/jsx-mount.snippet.ts +0 -24
- package/src/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.ts +0 -19
- package/src/runjs-context/snippets/scene/jsblock/render-basic.snippet.ts +0 -24
- package/src/runjs-context/snippets/scene/jsblock/render-button-handler.snippet.ts +0 -24
- package/src/runjs-context/snippets/scene/jsblock/render-card.snippet.ts +0 -30
- package/src/runjs-context/snippets/scene/jsblock/render-react.snippet.ts +0 -34
- package/src/runjs-context/snippets/scene/jsfield/color-by-value.snippet.ts +0 -20
- package/src/runjs-context/snippets/scene/jsfield/format-number.snippet.ts +0 -19
- package/src/runjs-context/snippets/scene/jsfield/innerHTML-value.snippet.ts +0 -18
- /package/lib/runjs-context/snippets/global/{copy-record-json.snippet.d.ts → api-request.snippet.d.ts} +0 -0
- /package/lib/runjs-context/snippets/global/{copy-to-clipboard.snippet.d.ts → clipboard-copy-text.snippet.d.ts} +0 -0
- /package/lib/runjs-context/snippets/global/{log-json-record.snippet.d.ts → import-esm.snippet.d.ts} +0 -0
- /package/lib/runjs-context/snippets/global/{view-navigation-push.snippet.d.ts → query-selector.snippet.d.ts} +0 -0
- /package/lib/runjs-context/snippets/scene/{jsblock/render-card.snippet.d.ts → block/echarts-init.snippet.d.ts} +0 -0
package/src/utils/safeGlobals.ts
CHANGED
|
@@ -8,12 +8,73 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
* 统一的安全全局对象代理:window/document
|
|
12
|
-
* -
|
|
13
|
-
* - document
|
|
11
|
+
* 统一的安全全局对象代理:window/document/navigator
|
|
12
|
+
* - window:仅允许常用的定时器、console、Math、Date、FormData、Blob、URL、addEventListener、open(安全包装)、location(安全代理)
|
|
13
|
+
* - document:仅允许 createElement/querySelector/querySelectorAll
|
|
14
|
+
* - navigator:仅提供极少量低风险能力(clipboard.writeText、onLine、language、languages)
|
|
14
15
|
* - 不允许随意访问未声明的属性,最小权限原则
|
|
15
16
|
*/
|
|
16
17
|
|
|
18
|
+
type RunJSSafeGlobalsRegistry = {
|
|
19
|
+
windowAllow: Set<string>;
|
|
20
|
+
documentAllow: Set<string>;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
function getRunJSSafeGlobalsRegistry(): RunJSSafeGlobalsRegistry {
|
|
24
|
+
const g: any = globalThis as any;
|
|
25
|
+
if (g.__nocobaseRunJSSafeGlobalsRegistry?.windowAllow && g.__nocobaseRunJSSafeGlobalsRegistry?.documentAllow) {
|
|
26
|
+
return g.__nocobaseRunJSSafeGlobalsRegistry as RunJSSafeGlobalsRegistry;
|
|
27
|
+
}
|
|
28
|
+
const reg: RunJSSafeGlobalsRegistry = {
|
|
29
|
+
windowAllow: new Set<string>(),
|
|
30
|
+
documentAllow: new Set<string>(),
|
|
31
|
+
};
|
|
32
|
+
g.__nocobaseRunJSSafeGlobalsRegistry = reg;
|
|
33
|
+
return reg;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function registerRunJSSafeWindowGlobals(keys: Iterable<string> | null | undefined): void {
|
|
37
|
+
if (!keys) return;
|
|
38
|
+
const reg = getRunJSSafeGlobalsRegistry();
|
|
39
|
+
for (const k of keys) {
|
|
40
|
+
if (typeof k !== 'string') continue;
|
|
41
|
+
const key = k.trim();
|
|
42
|
+
if (!key) continue;
|
|
43
|
+
reg.windowAllow.add(key);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function registerRunJSSafeDocumentGlobals(keys: Iterable<string> | null | undefined): void {
|
|
48
|
+
if (!keys) return;
|
|
49
|
+
const reg = getRunJSSafeGlobalsRegistry();
|
|
50
|
+
for (const k of keys) {
|
|
51
|
+
if (typeof k !== 'string') continue;
|
|
52
|
+
const key = k.trim();
|
|
53
|
+
if (!key) continue;
|
|
54
|
+
reg.documentAllow.add(key);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function __resetRunJSSafeGlobalsRegistryForTests(): void {
|
|
59
|
+
const g: any = globalThis as any;
|
|
60
|
+
if (g.__nocobaseRunJSSafeGlobalsRegistry) {
|
|
61
|
+
try {
|
|
62
|
+
g.__nocobaseRunJSSafeGlobalsRegistry.windowAllow?.clear?.();
|
|
63
|
+
g.__nocobaseRunJSSafeGlobalsRegistry.documentAllow?.clear?.();
|
|
64
|
+
} catch {
|
|
65
|
+
// ignore
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function isAllowedDynamicWindowKey(key: string): boolean {
|
|
71
|
+
return getRunJSSafeGlobalsRegistry().windowAllow.has(key);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function isAllowedDynamicDocumentKey(key: string): boolean {
|
|
75
|
+
return getRunJSSafeGlobalsRegistry().documentAllow.has(key);
|
|
76
|
+
}
|
|
77
|
+
|
|
17
78
|
export function createSafeWindow(extra?: Record<string, any>) {
|
|
18
79
|
// 解析相对 URL 使用脱敏 base(不含 query/hash),避免在解析时泄露敏感信息
|
|
19
80
|
const getSafeBaseHref = () => `${window.location.origin}${window.location.pathname}`;
|
|
@@ -123,7 +184,7 @@ export function createSafeWindow(extra?: Record<string, any>) {
|
|
|
123
184
|
case 'replace':
|
|
124
185
|
return (u: string) => guardedNavigate(u, { replace: true });
|
|
125
186
|
case 'reload':
|
|
126
|
-
|
|
187
|
+
return window.location.reload.bind(window.location);
|
|
127
188
|
case 'href':
|
|
128
189
|
throw new Error('Reading location.href is not allowed.');
|
|
129
190
|
default:
|
|
@@ -149,6 +210,9 @@ export function createSafeWindow(extra?: Record<string, any>) {
|
|
|
149
210
|
console,
|
|
150
211
|
Math,
|
|
151
212
|
Date,
|
|
213
|
+
FormData,
|
|
214
|
+
...(typeof Blob !== 'undefined' ? { Blob } : {}),
|
|
215
|
+
...(typeof URL !== 'undefined' ? { URL } : {}),
|
|
152
216
|
// 事件侦听仅绑定到真实 window,便于少量需要的全局监听
|
|
153
217
|
addEventListener: addEventListener.bind(window),
|
|
154
218
|
// 安全的 window.open 代理
|
|
@@ -158,15 +222,44 @@ export function createSafeWindow(extra?: Record<string, any>) {
|
|
|
158
222
|
...(extra || {}),
|
|
159
223
|
};
|
|
160
224
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
}
|
|
225
|
+
const target: Record<string, any> = Object.create(null);
|
|
226
|
+
|
|
227
|
+
return new Proxy(target, {
|
|
228
|
+
get(t, prop: string | symbol) {
|
|
229
|
+
if (typeof prop !== 'string') {
|
|
230
|
+
return Reflect.get(t, prop);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (prop in allowedGlobals) return allowedGlobals[prop];
|
|
234
|
+
if (Object.prototype.hasOwnProperty.call(t, prop)) return (t as any)[prop];
|
|
235
|
+
if (isAllowedDynamicWindowKey(prop)) {
|
|
236
|
+
const v = (window as any)[prop];
|
|
237
|
+
// Bind functions to the real window to avoid Illegal invocation
|
|
238
|
+
if (typeof v === 'function') return v.bind(window);
|
|
239
|
+
return v;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
throw new Error(`Access to global property "${prop}" is not allowed.`);
|
|
168
243
|
},
|
|
169
|
-
|
|
244
|
+
set(t, prop: string | symbol, value: any) {
|
|
245
|
+
if (typeof prop !== 'string') {
|
|
246
|
+
Reflect.set(t, prop, value);
|
|
247
|
+
return true;
|
|
248
|
+
}
|
|
249
|
+
if (prop in allowedGlobals) {
|
|
250
|
+
throw new Error(`Mutation of global property "${prop}" is not allowed.`);
|
|
251
|
+
}
|
|
252
|
+
(t as any)[prop] = value;
|
|
253
|
+
return true;
|
|
254
|
+
},
|
|
255
|
+
has(t, prop: string | symbol) {
|
|
256
|
+
if (typeof prop !== 'string') return Reflect.has(t, prop);
|
|
257
|
+
if (prop in allowedGlobals) return true;
|
|
258
|
+
if (Object.prototype.hasOwnProperty.call(t, prop)) return true;
|
|
259
|
+
if (isAllowedDynamicWindowKey(prop)) return true;
|
|
260
|
+
return false;
|
|
261
|
+
},
|
|
262
|
+
});
|
|
170
263
|
}
|
|
171
264
|
|
|
172
265
|
export function createSafeDocument(extra?: Record<string, any>) {
|
|
@@ -176,12 +269,85 @@ export function createSafeDocument(extra?: Record<string, any>) {
|
|
|
176
269
|
querySelectorAll: document.querySelectorAll.bind(document),
|
|
177
270
|
...(extra || {}),
|
|
178
271
|
};
|
|
272
|
+
const target: Record<string, any> = Object.create(null);
|
|
273
|
+
return new Proxy(target, {
|
|
274
|
+
get(t, prop: string | symbol) {
|
|
275
|
+
if (typeof prop !== 'string') {
|
|
276
|
+
return Reflect.get(t, prop);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (prop in allowed) return allowed[prop];
|
|
280
|
+
if (Object.prototype.hasOwnProperty.call(t, prop)) return (t as any)[prop];
|
|
281
|
+
if (isAllowedDynamicDocumentKey(prop)) {
|
|
282
|
+
const v = (document as any)[prop];
|
|
283
|
+
// Bind functions to the real document to avoid Illegal invocation
|
|
284
|
+
if (typeof v === 'function') return v.bind(document);
|
|
285
|
+
return v;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
throw new Error(`Access to document property "${prop}" is not allowed.`);
|
|
289
|
+
},
|
|
290
|
+
set(t, prop: string | symbol, value: any) {
|
|
291
|
+
if (typeof prop !== 'string') {
|
|
292
|
+
Reflect.set(t, prop, value);
|
|
293
|
+
return true;
|
|
294
|
+
}
|
|
295
|
+
if (prop in allowed) {
|
|
296
|
+
throw new Error(`Mutation of document property "${prop}" is not allowed.`);
|
|
297
|
+
}
|
|
298
|
+
(t as any)[prop] = value;
|
|
299
|
+
return true;
|
|
300
|
+
},
|
|
301
|
+
has(t, prop: string | symbol) {
|
|
302
|
+
if (typeof prop !== 'string') return Reflect.has(t, prop);
|
|
303
|
+
if (prop in allowed) return true;
|
|
304
|
+
if (Object.prototype.hasOwnProperty.call(t, prop)) return true;
|
|
305
|
+
if (isAllowedDynamicDocumentKey(prop)) return true;
|
|
306
|
+
return false;
|
|
307
|
+
},
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
export function createSafeNavigator(extra?: Record<string, any>) {
|
|
312
|
+
const nav: any = (typeof window !== 'undefined' && window.navigator) || undefined;
|
|
313
|
+
|
|
314
|
+
// 始终提供 clipboard 对象,避免可选链访问时抛错
|
|
315
|
+
const clipboard: Record<string, any> = {};
|
|
316
|
+
const writeText = nav?.clipboard?.writeText;
|
|
317
|
+
if (typeof writeText === 'function') {
|
|
318
|
+
clipboard.writeText = writeText.bind(nav.clipboard);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
const allowed: Record<string, any> = {
|
|
322
|
+
clipboard,
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
// 只读常用标识,避免泄露更多指纹信息
|
|
326
|
+
Object.defineProperty(allowed, 'onLine', {
|
|
327
|
+
get: () => !!nav?.onLine,
|
|
328
|
+
enumerable: true,
|
|
329
|
+
configurable: false,
|
|
330
|
+
});
|
|
331
|
+
Object.defineProperty(allowed, 'language', {
|
|
332
|
+
get: () => nav?.language,
|
|
333
|
+
enumerable: true,
|
|
334
|
+
configurable: false,
|
|
335
|
+
});
|
|
336
|
+
Object.defineProperty(allowed, 'languages', {
|
|
337
|
+
get: () => (nav?.languages ? [...nav.languages] : undefined),
|
|
338
|
+
enumerable: true,
|
|
339
|
+
configurable: false,
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
// 允许额外注入(例如自定义能力的受控暴露)
|
|
343
|
+
Object.assign(allowed, extra || {});
|
|
344
|
+
|
|
179
345
|
return new Proxy(
|
|
180
346
|
{},
|
|
181
347
|
{
|
|
182
|
-
get(
|
|
183
|
-
if (prop in allowed) return allowed[prop];
|
|
184
|
-
throw new Error(`Access to
|
|
348
|
+
get(_t, prop: string) {
|
|
349
|
+
if (prop in allowed) return (allowed as any)[prop];
|
|
350
|
+
throw new Error(`Access to navigator property "${String(prop)}" is not allowed.`);
|
|
185
351
|
},
|
|
186
352
|
},
|
|
187
353
|
);
|
|
@@ -76,6 +76,29 @@ export async function resolveUiMode<TModel extends FlowModel = FlowModel>(
|
|
|
76
76
|
// 模块级全局缓存,与 useCompile 保持一致
|
|
77
77
|
const compileCache = {};
|
|
78
78
|
|
|
79
|
+
const hasFunctionValue = (source: any): boolean => {
|
|
80
|
+
if (typeof source === 'function') return true;
|
|
81
|
+
if (!source || typeof source !== 'object') return false;
|
|
82
|
+
const seen = new WeakSet<object>();
|
|
83
|
+
const walk = (val: any): boolean => {
|
|
84
|
+
if (typeof val === 'function') return true;
|
|
85
|
+
if (!val || typeof val !== 'object') return false;
|
|
86
|
+
if (seen.has(val)) return false;
|
|
87
|
+
seen.add(val);
|
|
88
|
+
if (Array.isArray(val)) {
|
|
89
|
+
for (const it of val) {
|
|
90
|
+
if (walk(it)) return true;
|
|
91
|
+
}
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
for (const k of Object.keys(val)) {
|
|
95
|
+
if (walk((val as any)[k])) return true;
|
|
96
|
+
}
|
|
97
|
+
return false;
|
|
98
|
+
};
|
|
99
|
+
return walk(source);
|
|
100
|
+
};
|
|
101
|
+
|
|
79
102
|
/**
|
|
80
103
|
* 编译 UI Schema 中的表达式
|
|
81
104
|
*
|
|
@@ -110,8 +133,18 @@ export function compileUiSchema(scope: Record<string, any>, uiSchema: any, optio
|
|
|
110
133
|
console.warn('Failed to stringify:', e);
|
|
111
134
|
return source;
|
|
112
135
|
}
|
|
113
|
-
if (compileCache[cacheKey]) return compileCache[cacheKey];
|
|
114
136
|
shouldCompile = hasVariable(cacheKey);
|
|
137
|
+
// schema 中包含函数(如 x-reactions 的闭包)时,缓存会导致跨上下文复用旧闭包,必须禁用缓存
|
|
138
|
+
const hasFn = shouldCompile && !noCache ? hasFunctionValue(source) : false;
|
|
139
|
+
if (compileCache[cacheKey] && !noCache && !hasFn) return compileCache[cacheKey];
|
|
140
|
+
if (hasFn) {
|
|
141
|
+
try {
|
|
142
|
+
return Schema.compile(source, scope);
|
|
143
|
+
} catch (error) {
|
|
144
|
+
console.warn('Failed to compile with Formily Schema.compile:', error);
|
|
145
|
+
return source;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
115
148
|
}
|
|
116
149
|
|
|
117
150
|
// source is Array, for example: [{ 'title': "{{ t('Admin') }}", name: 'admin' }, { 'title': "{{ t('Root') }}", name: 'root' }]
|
|
@@ -122,8 +155,17 @@ export function compileUiSchema(scope: Record<string, any>, uiSchema: any, optio
|
|
|
122
155
|
console.warn('Failed to stringify:', e);
|
|
123
156
|
return source;
|
|
124
157
|
}
|
|
125
|
-
if (compileCache[cacheKey]) return compileCache[cacheKey];
|
|
126
158
|
shouldCompile = hasVariable(cacheKey);
|
|
159
|
+
const hasFn = shouldCompile && !noCache ? hasFunctionValue(source) : false;
|
|
160
|
+
if (compileCache[cacheKey] && !noCache && !hasFn) return compileCache[cacheKey];
|
|
161
|
+
if (hasFn) {
|
|
162
|
+
try {
|
|
163
|
+
return Schema.compile(source, scope);
|
|
164
|
+
} catch (error) {
|
|
165
|
+
console.warn('Failed to compile with Formily Schema.compile:', error);
|
|
166
|
+
return source;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
127
169
|
}
|
|
128
170
|
|
|
129
171
|
if (shouldCompile) {
|
|
@@ -181,7 +223,7 @@ export async function resolveStepUiSchema<TModel extends FlowModel = FlowModel>(
|
|
|
181
223
|
|
|
182
224
|
if (step.use) {
|
|
183
225
|
try {
|
|
184
|
-
const action = model.
|
|
226
|
+
const action = model.getAction?.(step.use);
|
|
185
227
|
if (action && action.uiSchema) {
|
|
186
228
|
stepUiSchema = stepUiSchema || action.uiSchema;
|
|
187
229
|
}
|
|
@@ -199,3 +241,39 @@ export async function resolveStepUiSchema<TModel extends FlowModel = FlowModel>(
|
|
|
199
241
|
|
|
200
242
|
return resolvedStepUiSchema;
|
|
201
243
|
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* 判断步骤在设置菜单中是否应被隐藏。
|
|
247
|
+
* - 支持 StepDefinition.hideInSettings 与 ActionDefinition.hideInSettings(step 优先)。
|
|
248
|
+
* - hideInSettings 可为布尔值或函数(接收 FlowRuntimeContext)。
|
|
249
|
+
*/
|
|
250
|
+
export async function shouldHideStepInSettings<TModel extends FlowModel = FlowModel>(
|
|
251
|
+
model: TModel,
|
|
252
|
+
flow: any,
|
|
253
|
+
step: StepDefinition,
|
|
254
|
+
): Promise<boolean> {
|
|
255
|
+
if (!step) return true;
|
|
256
|
+
|
|
257
|
+
// 优先使用 step.hideInSettings,其次回退到 action.hideInSettings
|
|
258
|
+
let hideInSettings = step.hideInSettings;
|
|
259
|
+
|
|
260
|
+
if (typeof hideInSettings === 'undefined' && step.use) {
|
|
261
|
+
const action = model.getAction?.(step.use);
|
|
262
|
+
hideInSettings = action?.hideInSettings;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (typeof hideInSettings === 'function') {
|
|
266
|
+
try {
|
|
267
|
+
const ctx = new FlowRuntimeContext(model, flow.key, 'settings');
|
|
268
|
+
setupRuntimeContextSteps(ctx, flow.steps, model, flow.key);
|
|
269
|
+
ctx.defineProperty('currentStep', { value: step });
|
|
270
|
+
const result = await hideInSettings(ctx as any);
|
|
271
|
+
return !!result;
|
|
272
|
+
} catch (error) {
|
|
273
|
+
console.warn(`Error evaluating hideInSettings for step '${step.key || ''}' in flow '${flow.key}':`, error);
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return !!hideInSettings;
|
|
279
|
+
}
|
|
@@ -14,6 +14,8 @@ export type RecordRef = {
|
|
|
14
14
|
id?: any; // primary key value
|
|
15
15
|
filterByTk?: any; // alias for id
|
|
16
16
|
dataSourceKey?: string;
|
|
17
|
+
associationName?: string;
|
|
18
|
+
sourceId?: any;
|
|
17
19
|
fields?: string[];
|
|
18
20
|
appends?: string[];
|
|
19
21
|
record?: any; // full record object (try to infer pk from it)
|
|
@@ -27,6 +29,8 @@ export type NormalizedRecordParams = {
|
|
|
27
29
|
collection: string;
|
|
28
30
|
filterByTk: any;
|
|
29
31
|
dataSourceKey?: string;
|
|
32
|
+
associationName?: string;
|
|
33
|
+
sourceId?: any;
|
|
30
34
|
fields?: string[];
|
|
31
35
|
appends?: string[];
|
|
32
36
|
};
|
|
@@ -63,6 +67,8 @@ function normalizeOne(ctx: FlowContext, ref?: RecordRef): NormalizedRecordParams
|
|
|
63
67
|
collection,
|
|
64
68
|
filterByTk,
|
|
65
69
|
dataSourceKey,
|
|
70
|
+
associationName: ref.associationName,
|
|
71
|
+
sourceId: ref.sourceId,
|
|
66
72
|
fields: ref.fields,
|
|
67
73
|
appends: ref.appends,
|
|
68
74
|
});
|
package/src/utils/translation.ts
CHANGED
|
@@ -27,11 +27,16 @@ export function getT(model: FlowModel): (key: string, options?: any) => string {
|
|
|
27
27
|
return (key: string) => key;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
export function
|
|
30
|
+
export function tExpr(text: TFuncKey | TFuncKey[], options?: TOptions) {
|
|
31
31
|
if (options) {
|
|
32
32
|
return `{{t(${JSON.stringify(text)}, ${JSON.stringify(options)})}}`;
|
|
33
33
|
}
|
|
34
34
|
return `{{t(${JSON.stringify(text)})}}`;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
/**
|
|
38
|
+
* @deprecated use tExpr from `@nocobase/flow-engine` instead
|
|
39
|
+
*/
|
|
40
|
+
export function escapeT(text: TFuncKey | TFuncKey[], options?: TOptions) {
|
|
41
|
+
return tExpr(text, options);
|
|
42
|
+
}
|
|
@@ -7,51 +7,27 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import type { FlowContext, PropertyMeta, PropertyMetaFactory } from '../flowContext';
|
|
11
|
-
import type { JSONValue } from './params-resolvers';
|
|
12
|
-
import type { Collection } from '../data-source';
|
|
13
|
-
import { createCollectionContextMeta } from './createCollectionContextMeta';
|
|
14
|
-
import { buildServerContextParams, type RecordRef, type ServerContextParams } from '../utils/serverContextParams';
|
|
15
10
|
import {
|
|
16
11
|
extractUsedVariableNames as _extractUsedVariableNames,
|
|
17
12
|
extractUsedVariablePaths as _extractUsedVariablePaths,
|
|
18
|
-
} from '@nocobase/
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
type
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
function isObject(value: unknown): value is Record<string, unknown> {
|
|
29
|
-
return typeof value === 'object' && value !== null;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function getResource(ctx: FlowContext): ResourceLike | undefined {
|
|
33
|
-
const r = (ctx as FlowContext)['resource'];
|
|
34
|
-
return isObject(r) ? (r as ResourceLike) : undefined;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
type CollectionShape = { name?: string; dataSourceKey?: string };
|
|
38
|
-
|
|
39
|
-
function getCollection(ctx: FlowContext): CollectionShape | undefined {
|
|
40
|
-
const c = (ctx as FlowContext)['collection'] as unknown;
|
|
41
|
-
if (isObject(c)) {
|
|
42
|
-
const mc = c as Partial<CollectionShape>;
|
|
43
|
-
return { name: mc.name, dataSourceKey: mc.dataSourceKey };
|
|
44
|
-
}
|
|
45
|
-
return undefined;
|
|
46
|
-
}
|
|
13
|
+
} from '@nocobase/shared';
|
|
14
|
+
import type { Collection } from '../data-source';
|
|
15
|
+
import type { FlowContext, PropertyMeta, PropertyMetaFactory } from '../flowContext';
|
|
16
|
+
import { buildServerContextParams, type RecordRef, type ServerContextParams } from '../utils/serverContextParams';
|
|
17
|
+
import { createCollectionContextMeta } from './createCollectionContextMeta';
|
|
18
|
+
import { createAssociationSubpathResolver } from './associationObjectVariable';
|
|
19
|
+
import type { JSONValue } from './params-resolvers';
|
|
20
|
+
import _ from 'lodash';
|
|
47
21
|
|
|
22
|
+
// 从 FlowContext 中推断当前记录的 context params 信息
|
|
48
23
|
export function inferRecordRef(ctx: FlowContext): RecordRef | undefined {
|
|
49
|
-
const resource =
|
|
50
|
-
const collectionObj =
|
|
24
|
+
const resource = ctx.resource;
|
|
25
|
+
const collectionObj = ctx.collection;
|
|
26
|
+
const recordValue = ctx.record;
|
|
51
27
|
|
|
52
28
|
const resourceName = collectionObj?.name || resource?.getResourceName?.();
|
|
53
29
|
const dataSourceKey = collectionObj?.dataSourceKey || resource?.getDataSourceKey?.();
|
|
54
|
-
const filterByTk = resource?.getFilterByTk?.();
|
|
30
|
+
const filterByTk = resource?.getFilterByTk?.() ?? collectionObj?.getFilterByTK?.(recordValue);
|
|
55
31
|
|
|
56
32
|
if (!resourceName || typeof filterByTk === 'undefined' || filterByTk === null) return undefined;
|
|
57
33
|
const parts = String(resourceName).split('.');
|
|
@@ -59,13 +35,131 @@ export function inferRecordRef(ctx: FlowContext): RecordRef | undefined {
|
|
|
59
35
|
return { collection, dataSourceKey, filterByTk };
|
|
60
36
|
}
|
|
61
37
|
|
|
38
|
+
// 从 FlowContext.view 中推断记录的 context params 信息
|
|
39
|
+
export function inferViewRecordRef(ctx: FlowContext): RecordRef | undefined {
|
|
40
|
+
const view = ctx.view;
|
|
41
|
+
if (!view) return undefined;
|
|
42
|
+
const inputArgs = (view as any)?.inputArgs || {};
|
|
43
|
+
const collection = inputArgs?.collectionName || (view as any)?.record?.collection;
|
|
44
|
+
const dataSourceKey = inputArgs?.dataSourceKey || (view as any)?.record?.dataSourceKey || 'main';
|
|
45
|
+
const filterByTk = inputArgs?.filterByTk || (view as any)?.record?.filterByTk;
|
|
46
|
+
const associationName = inputArgs?.associationName;
|
|
47
|
+
const sourceId = inputArgs?.sourceId;
|
|
48
|
+
if (!collection || typeof filterByTk === 'undefined' || filterByTk === null) return undefined;
|
|
49
|
+
return { collection, dataSourceKey, filterByTk, sourceId, associationName };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// 统一视图场景中“视图记录”的本地复用逻辑:
|
|
53
|
+
// - 当视图 inputArgs.filterByTk 与父 FlowContext.record.filterByTk 一致时,
|
|
54
|
+
// 认为视图正在查看同一条记录,此时返回父记录的深拷贝作为 view.record;
|
|
55
|
+
// - 否则视为不同记录,不复用父记录(返回 undefined,让后续逻辑走服务端解析)。
|
|
56
|
+
|
|
57
|
+
export function getViewRecordFromParent(flowContext: FlowContext, viewContext: FlowContext): unknown {
|
|
58
|
+
const parentRecord = flowContext.inputArgs?.record;
|
|
59
|
+
const parentTk = flowContext.collection?.filterTargetKey;
|
|
60
|
+
if (!parentRecord || !parentTk) return undefined;
|
|
61
|
+
|
|
62
|
+
const view = viewContext.view;
|
|
63
|
+
const viewFilterByTk = view?.inputArgs?.filterByTk;
|
|
64
|
+
const recordFilterByTk = parentRecord[parentTk];
|
|
65
|
+
|
|
66
|
+
// 仅当视图的 filterByTk 与父记录的 filterByTk 一致时,才复用父记录,
|
|
67
|
+
// 否则视为不同记录,不返回本地记录(统一走服务端解析)。
|
|
68
|
+
if (viewFilterByTk == null || recordFilterByTk == null) return undefined;
|
|
69
|
+
if (viewFilterByTk !== recordFilterByTk) return undefined;
|
|
70
|
+
|
|
71
|
+
return _.cloneDeep(parentRecord);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// 针对视图场景(Page/Dialog/Drawer),创建用于 view.resolveOnServer 的判定函数
|
|
75
|
+
export function createViewRecordResolveOnServer(
|
|
76
|
+
ctx: FlowContext,
|
|
77
|
+
getLocalRecord: () => unknown,
|
|
78
|
+
): (subPath: string) => boolean {
|
|
79
|
+
return (p: string) => {
|
|
80
|
+
if (!(p === 'record' || p.startsWith('record.'))) return false;
|
|
81
|
+
const local = getLocalRecord();
|
|
82
|
+
// 前端没有可用记录数据:统一走服务端
|
|
83
|
+
if (!local) return true;
|
|
84
|
+
|
|
85
|
+
// 直接访问整个 record 对象,使用前端值
|
|
86
|
+
if (p === 'record') return false;
|
|
87
|
+
|
|
88
|
+
// 仅在访问关联字段子路径时走服务端;非关联字段使用前端值
|
|
89
|
+
const ref = inferViewRecordRef(ctx);
|
|
90
|
+
const colName = ref?.collection;
|
|
91
|
+
const dsKey = ref?.dataSourceKey || 'main';
|
|
92
|
+
if (!colName) return true; // 未能推断集合,保守起见走服务端
|
|
93
|
+
const ds = (
|
|
94
|
+
ctx as FlowContext & { dataSourceManager?: { getDataSource?: (key: string) => any } }
|
|
95
|
+
).dataSourceManager?.getDataSource?.(dsKey);
|
|
96
|
+
const collection = ds?.collectionManager?.getCollection?.(colName);
|
|
97
|
+
if (!collection) return true; // 未找到集合定义,保守走服务端
|
|
98
|
+
|
|
99
|
+
const resolver = createAssociationSubpathResolver(
|
|
100
|
+
() => collection as Collection,
|
|
101
|
+
() => local,
|
|
102
|
+
);
|
|
103
|
+
const subPath = p.startsWith('record.') ? p.slice('record.'.length) : '';
|
|
104
|
+
if (!subPath) return false;
|
|
105
|
+
return resolver(subPath);
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* 创建一个用于 “ctx.record” 变量的 resolveOnServer 判定函数:
|
|
111
|
+
* - 若本地 record 不存在:统一走服务端;
|
|
112
|
+
* - 若本地 record 存在:
|
|
113
|
+
* - 访问空子路径("{{ ctx.record }}")时使用本地值,不走服务端;
|
|
114
|
+
* - 访问非关联字段(如 id/title):使用本地值;
|
|
115
|
+
* - 访问关联字段:
|
|
116
|
+
* - 若本地该字段无值(undefined/null),则交给服务端解析(无论是 "author" 还是 "author.name");
|
|
117
|
+
* - 若本地已有值,则仅在访问子属性且本地缺少该子属性值时交给服务端。
|
|
118
|
+
*/
|
|
119
|
+
export function createRecordResolveOnServerWithLocal(
|
|
120
|
+
collectionAccessor: () => Collection | null,
|
|
121
|
+
valueAccessor: () => unknown,
|
|
122
|
+
): (subPath: string) => boolean {
|
|
123
|
+
const assocSubpathResolver = createAssociationSubpathResolver(collectionAccessor, () => valueAccessor());
|
|
124
|
+
return (p: string) => {
|
|
125
|
+
const local = valueAccessor();
|
|
126
|
+
if (!local) return true;
|
|
127
|
+
if (!p) return false;
|
|
128
|
+
|
|
129
|
+
const collection = collectionAccessor() as any;
|
|
130
|
+
|
|
131
|
+
// 访问关联字段整体:当本地该字段无值时,统一交给服务端
|
|
132
|
+
if (!p.includes('.')) {
|
|
133
|
+
const name = p;
|
|
134
|
+
let field: any;
|
|
135
|
+
if (collection) {
|
|
136
|
+
if (typeof collection.getField === 'function') {
|
|
137
|
+
field = collection.getField(name);
|
|
138
|
+
}
|
|
139
|
+
if (!field && typeof collection.getFields === 'function') {
|
|
140
|
+
const fields = collection.getFields() || [];
|
|
141
|
+
field = fields.find((f: any) => f?.name === name);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
const isAssoc = !!field?.isAssociationField?.();
|
|
145
|
+
if (!isAssoc) return false;
|
|
146
|
+
const value = (local as any)?.[name];
|
|
147
|
+
if (value === undefined || value === null) return true;
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// 访问关联字段子属性:复用 associationSubpathResolver 的“本地优先 + 关联字段才走服务端”逻辑
|
|
152
|
+
return assocSubpathResolver(p);
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
62
156
|
export function inferParentRecordRef(ctx: FlowContext): RecordRef | undefined {
|
|
63
|
-
const resource =
|
|
64
|
-
const dataSourceKey =
|
|
65
|
-
const
|
|
157
|
+
const resource = ctx.resource;
|
|
158
|
+
const dataSourceKey = ctx.collection?.dataSourceKey || resource?.getDataSourceKey?.();
|
|
159
|
+
const resourceName = resource?.getResourceName?.();
|
|
66
160
|
const sourceId = resource?.getSourceId?.();
|
|
67
|
-
if (!
|
|
68
|
-
const parts = String(
|
|
161
|
+
if (!resourceName || typeof sourceId === 'undefined' || sourceId === null) return undefined;
|
|
162
|
+
const parts = String(resourceName).split('.');
|
|
69
163
|
if (parts.length < 2) return undefined;
|
|
70
164
|
return { collection: parts[0], dataSourceKey, filterByTk: sourceId };
|
|
71
165
|
}
|
|
@@ -80,7 +174,7 @@ export async function buildRecordMeta(
|
|
|
80
174
|
title?: string,
|
|
81
175
|
paramsBuilder?: RecordParamsBuilder,
|
|
82
176
|
): Promise<PropertyMeta | null> {
|
|
83
|
-
const base = await createCollectionContextMeta(collectionAccessor, title)();
|
|
177
|
+
const base = await createCollectionContextMeta(collectionAccessor, title, true)();
|
|
84
178
|
if (!base) return null;
|
|
85
179
|
return {
|
|
86
180
|
...base,
|
|
@@ -110,8 +204,11 @@ export function createRecordMetaFactory(
|
|
|
110
204
|
export function createCurrentRecordMetaFactory(
|
|
111
205
|
ctx: FlowContext,
|
|
112
206
|
collectionAccessor: () => Collection | null,
|
|
207
|
+
options?: { title?: string },
|
|
113
208
|
): PropertyMetaFactory {
|
|
114
|
-
const title =
|
|
209
|
+
const title = options?.title
|
|
210
|
+
? ctx.t?.(options.title) || options.title
|
|
211
|
+
: ctx.t?.('Current record') || 'Current record';
|
|
115
212
|
return createRecordMetaFactory(collectionAccessor, title, (c) => inferRecordRef(c));
|
|
116
213
|
}
|
|
117
214
|
|
|
@@ -141,35 +238,30 @@ export async function collectContextParamsForTemplate(
|
|
|
141
238
|
ctx: FlowContext,
|
|
142
239
|
template: JSONValue,
|
|
143
240
|
): Promise<ServerContextParams | undefined> {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
built = await builder(ctx);
|
|
160
|
-
}
|
|
161
|
-
} catch (err) {
|
|
162
|
-
// 忽略构建变量参数时的异常,继续处理其他变量
|
|
163
|
-
// 使用 void 引用以避免 no-unused-vars,同时避免空代码块触发 no-empty
|
|
164
|
-
void err;
|
|
165
|
-
continue;
|
|
166
|
-
}
|
|
167
|
-
if (built) {
|
|
168
|
-
input[key] = built;
|
|
241
|
+
const usage = _extractUsedVariablePaths(template) || {};
|
|
242
|
+
const varNames = Object.keys(usage);
|
|
243
|
+
if (!varNames.length) return undefined;
|
|
244
|
+
|
|
245
|
+
const input: Record<string, any> = {};
|
|
246
|
+
for (const key of varNames) {
|
|
247
|
+
const opt = ctx.getPropertyOptions?.(key);
|
|
248
|
+
const meta: PropertyMeta | (() => Promise<PropertyMeta | null> | PropertyMeta | null) | undefined = opt?.meta;
|
|
249
|
+
if (!meta) continue;
|
|
250
|
+
let built: any;
|
|
251
|
+
try {
|
|
252
|
+
const resolvedMeta = typeof meta === 'function' ? await (meta as any)() : (meta as any);
|
|
253
|
+
const builder = resolvedMeta?.buildVariablesParams;
|
|
254
|
+
if (typeof builder === 'function') {
|
|
255
|
+
built = await builder(ctx);
|
|
169
256
|
}
|
|
257
|
+
} catch (err) {
|
|
258
|
+
// 忽略构建变量参数时的异常,继续处理其他变量
|
|
259
|
+
void err;
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
if (built) {
|
|
263
|
+
input[key] = built;
|
|
170
264
|
}
|
|
171
|
-
return buildServerContextParams(ctx, input);
|
|
172
|
-
} catch (_) {
|
|
173
|
-
return undefined;
|
|
174
265
|
}
|
|
266
|
+
return buildServerContextParams(ctx, input);
|
|
175
267
|
}
|