Kaynağa Gözat

feat(material): infer loop outputs key (#802)

Yiwei Mao 4 ay önce
ebeveyn
işleme
28159c1617

+ 1 - 1
apps/demo-free-layout/src/nodes/loop/form-meta.tsx

@@ -92,5 +92,5 @@ export const formMeta: FormMeta = {
   effect: {
     loopFor: provideBatchInputEffect,
   },
-  plugins: [createBatchOutputsFormPlugin({ outputKey: 'loopOutputs' })],
+  plugins: [createBatchOutputsFormPlugin({ outputKey: 'loopOutputs', inferTargetKey: 'outputs' })],
 };

+ 63 - 44
packages/materials/form-materials/src/form-plugins/batch-outputs-plugin/index.ts

@@ -3,6 +3,8 @@
  * SPDX-License-Identifier: MIT
  */
 
+import { set } from 'lodash-es';
+import { JsonSchemaUtils } from '@flowgram.ai/json-schema';
 import {
   ASTFactory,
   createEffectFromVariableProvider,
@@ -46,59 +48,76 @@ export const provideBatchOutputsEffect: EffectOptions[] = createEffectFromVariab
 /**
  * Free Layout only right now
  */
-export const createBatchOutputsFormPlugin: FormPluginCreator<{ outputKey: string }> =
-  defineFormPluginCreator({
-    name: 'batch-outputs-plugin',
-    onSetupFormMeta({ mergeEffect }, { outputKey }) {
-      mergeEffect({
-        [outputKey]: provideBatchOutputsEffect,
+export const createBatchOutputsFormPlugin: FormPluginCreator<{
+  outputKey: string;
+  /**
+   * if set, infer json schema to inferTargetKey when submit
+   */
+  inferTargetKey?: string;
+}> = defineFormPluginCreator({
+  name: 'batch-outputs-plugin',
+  onSetupFormMeta({ mergeEffect, addFormatOnSubmit }, { outputKey, inferTargetKey }) {
+    mergeEffect({
+      [outputKey]: provideBatchOutputsEffect,
+    });
+
+    if (inferTargetKey) {
+      addFormatOnSubmit((formData, ctx) => {
+        const outputVariable = getNodeScope(ctx.node).output.variables?.[0];
+
+        if (outputVariable?.type) {
+          set(formData, inferTargetKey, JsonSchemaUtils.astToSchema(outputVariable?.type));
+        }
+
+        return formData;
       });
-    },
-    onInit(ctx, { outputKey }) {
-      const chainTransformService = ctx.node.getService(ScopeChainTransformService);
+    }
+  },
+  onInit(ctx, { outputKey }) {
+    const chainTransformService = ctx.node.getService(ScopeChainTransformService);
 
-      const batchNodeType = ctx.node.flowNodeType;
+    const batchNodeType = ctx.node.flowNodeType;
 
-      const transformerId = `${batchNodeType}-outputs`;
+    const transformerId = `${batchNodeType}-outputs`;
 
-      if (chainTransformService.hasTransformer(transformerId)) {
-        return;
-      }
+    if (chainTransformService.hasTransformer(transformerId)) {
+      return;
+    }
 
-      chainTransformService.registerTransformer(transformerId, {
-        transformCovers: (covers, ctx) => {
-          const node = ctx.scope.meta?.node;
+    chainTransformService.registerTransformer(transformerId, {
+      transformCovers: (covers, ctx) => {
+        const node = ctx.scope.meta?.node;
 
-          // Child Node's variable can cover parent
-          if (node?.parent?.flowNodeType === batchNodeType) {
-            return [...covers, getNodeScope(node.parent)];
-          }
+        // Child Node's variable can cover parent
+        if (node?.parent?.flowNodeType === batchNodeType) {
+          return [...covers, getNodeScope(node.parent)];
+        }
 
-          return covers;
-        },
-        transformDeps(scopes, ctx) {
-          const scopeMeta = ctx.scope.meta;
+        return covers;
+      },
+      transformDeps(scopes, ctx) {
+        const scopeMeta = ctx.scope.meta;
 
-          if (scopeMeta?.type === FlowNodeScopeType.private) {
-            return scopes;
-          }
+        if (scopeMeta?.type === FlowNodeScopeType.private) {
+          return scopes;
+        }
 
-          const node = scopeMeta?.node;
+        const node = scopeMeta?.node;
 
-          // Public of Loop Node depends on child Node
-          if (node?.flowNodeType === batchNodeType) {
-            // Get all child blocks
-            const childBlocks = node.blocks;
+        // Public of Loop Node depends on child Node
+        if (node?.flowNodeType === batchNodeType) {
+          // Get all child blocks
+          const childBlocks = node.blocks;
 
-            // public scope of all child blocks
-            return [
-              getNodePrivateScope(node),
-              ...childBlocks.map((_childBlock) => getNodeScope(_childBlock)),
-            ];
-          }
+          // public scope of all child blocks
+          return [
+            getNodePrivateScope(node),
+            ...childBlocks.map((_childBlock) => getNodeScope(_childBlock)),
+          ];
+        }
 
-          return scopes;
-        },
-      });
-    },
-  });
+        return scopes;
+      },
+    });
+  },
+});