@flowgram.ai/node 0.2.16 → 0.2.17
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/dist/esm/index.js +52 -14
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.mts +44 -10
- package/dist/index.d.ts +44 -10
- package/dist/index.js +52 -14
- package/dist/index.js.map +1 -1
- package/package.json +9 -9
package/dist/esm/index.js
CHANGED
|
@@ -67,11 +67,6 @@ function convertGlobPath(path) {
|
|
|
67
67
|
}
|
|
68
68
|
return path;
|
|
69
69
|
}
|
|
70
|
-
function mergeEffectMap(origin, source) {
|
|
71
|
-
return mergeWith(origin, source, function(objValue, srcValue) {
|
|
72
|
-
return (objValue || []).concat(srcValue);
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
70
|
|
|
76
71
|
// src/form-render.tsx
|
|
77
72
|
import React from "react";
|
|
@@ -144,7 +139,7 @@ var FormModelV2 = class extends FormModel {
|
|
|
144
139
|
return this._formControl;
|
|
145
140
|
}
|
|
146
141
|
get formMeta() {
|
|
147
|
-
return this.node.getNodeRegistry().formMeta;
|
|
142
|
+
return this._formMeta || this.node.getNodeRegistry().formMeta;
|
|
148
143
|
}
|
|
149
144
|
get values() {
|
|
150
145
|
return this.nativeFormModel?.values;
|
|
@@ -188,9 +183,6 @@ var FormModelV2 = class extends FormModel {
|
|
|
188
183
|
this.plugins = plugins;
|
|
189
184
|
plugins.forEach((plugin) => {
|
|
190
185
|
plugin.init(this);
|
|
191
|
-
if (plugin.config?.effect) {
|
|
192
|
-
mergeEffectMap(this.effectMap, plugin.config.effect);
|
|
193
|
-
}
|
|
194
186
|
});
|
|
195
187
|
}
|
|
196
188
|
init(formMeta, rawInitialValues) {
|
|
@@ -199,6 +191,12 @@ var FormModelV2 = class extends FormModel {
|
|
|
199
191
|
this._valid = null;
|
|
200
192
|
formData.fireChange();
|
|
201
193
|
});
|
|
194
|
+
(formMeta.plugins || [])?.forEach((_plugin) => {
|
|
195
|
+
if (_plugin.setupFormMeta) {
|
|
196
|
+
formMeta = _plugin.setupFormMeta(formMeta, this.nodeContext);
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
this._formMeta = formMeta;
|
|
202
200
|
const { validateTrigger, validate, effect } = formMeta;
|
|
203
201
|
if (effect) {
|
|
204
202
|
this.effectMap = effect;
|
|
@@ -512,9 +510,9 @@ function useWatchFormWarnings(node) {
|
|
|
512
510
|
// src/form-plugin.ts
|
|
513
511
|
import { nanoid } from "nanoid";
|
|
514
512
|
var FormPlugin = class {
|
|
515
|
-
constructor(
|
|
516
|
-
this.name = name;
|
|
517
|
-
this.pluginId = `${name}__${nanoid()}`;
|
|
513
|
+
constructor(config, opts) {
|
|
514
|
+
this.name = config?.name || "";
|
|
515
|
+
this.pluginId = `${this.name}__${nanoid()}`;
|
|
518
516
|
this.config = config;
|
|
519
517
|
this.opts = opts;
|
|
520
518
|
}
|
|
@@ -528,6 +526,46 @@ var FormPlugin = class {
|
|
|
528
526
|
playgroundContext: this.formModel.nodeContext.playgroundContext
|
|
529
527
|
};
|
|
530
528
|
}
|
|
529
|
+
setupFormMeta(formMeta, nodeContext) {
|
|
530
|
+
const nextFormMeta = {
|
|
531
|
+
...formMeta
|
|
532
|
+
};
|
|
533
|
+
this.config.onSetupFormMeta?.(
|
|
534
|
+
{
|
|
535
|
+
mergeEffect: (effect) => {
|
|
536
|
+
nextFormMeta.effect = {
|
|
537
|
+
...nextFormMeta.effect || {},
|
|
538
|
+
...effect
|
|
539
|
+
};
|
|
540
|
+
},
|
|
541
|
+
mergeValidate: (validate) => {
|
|
542
|
+
nextFormMeta.validate = {
|
|
543
|
+
...nextFormMeta.validate || {},
|
|
544
|
+
...validate
|
|
545
|
+
};
|
|
546
|
+
},
|
|
547
|
+
addFormatOnInit: (formatOnInit) => {
|
|
548
|
+
if (!nextFormMeta.formatOnInit) {
|
|
549
|
+
nextFormMeta.formatOnInit = formatOnInit;
|
|
550
|
+
return;
|
|
551
|
+
}
|
|
552
|
+
const legacyFormatOnInit = nextFormMeta.formatOnInit;
|
|
553
|
+
nextFormMeta.formatOnInit = (v, c) => formatOnInit?.(legacyFormatOnInit(v, c), c);
|
|
554
|
+
},
|
|
555
|
+
addFormatOnSubmit: (formatOnSubmit) => {
|
|
556
|
+
if (!nextFormMeta.formatOnSubmit) {
|
|
557
|
+
nextFormMeta.formatOnSubmit = formatOnSubmit;
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
const legacyFormatOnSubmit = nextFormMeta.formatOnSubmit;
|
|
561
|
+
nextFormMeta.formatOnSubmit = (v, c) => formatOnSubmit?.(legacyFormatOnSubmit(v, c), c);
|
|
562
|
+
},
|
|
563
|
+
...nodeContext
|
|
564
|
+
},
|
|
565
|
+
this.opts
|
|
566
|
+
);
|
|
567
|
+
return nextFormMeta;
|
|
568
|
+
}
|
|
531
569
|
init(formModel) {
|
|
532
570
|
this._formModel = formModel;
|
|
533
571
|
this.config?.onInit?.(this.ctx, this.opts);
|
|
@@ -538,9 +576,9 @@ var FormPlugin = class {
|
|
|
538
576
|
}
|
|
539
577
|
}
|
|
540
578
|
};
|
|
541
|
-
function defineFormPluginCreator(
|
|
579
|
+
function defineFormPluginCreator(config) {
|
|
542
580
|
return function(opts) {
|
|
543
|
-
return new FormPlugin(
|
|
581
|
+
return new FormPlugin(config, opts);
|
|
544
582
|
};
|
|
545
583
|
}
|
|
546
584
|
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/types.ts","../../src/form-model-v2.ts","../../src/utils.ts","../../src/form-render.tsx","../../src/helpers.ts","../../src/hooks.ts","../../src/form-plugin.ts","../../src/get-node-form.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { FormModel, IFormMeta, NodeFormContext } from '@flowgram.ai/form-core';\nimport { FieldName, FieldValue } from '@flowgram.ai/form/src/types';\nimport {\n FormRenderProps,\n IForm,\n Validate as FormValidate,\n ValidateTrigger,\n} from '@flowgram.ai/form';\n\nimport { FormPlugin } from './form-plugin';\nimport { FormModelV2 } from './form-model-v2';\n\nexport interface Node {}\n\nexport interface Flow {}\n\n/**\n * NodeContext contains\n * - node: the Editor's node entity.\n * - playgroundContext: the Editor's playgroundContext injected when initiate the Editor.\n */\ntype NodeContext = NodeFormContext;\n\nexport type Validate<TFieldValue = any, TFormValues = any> = (props: {\n value: TFieldValue;\n formValues: TFormValues;\n context: NodeContext;\n name: FieldName;\n}) => ReturnType<FormValidate<TFieldValue, TFormValues>>;\n\nexport enum DataEvent {\n /* When value change */\n onValueChange = 'onValueChange',\n /**\n * When value Init,it triggers when\n * - defaultValue is configured in formMeta, it will trigger when form is initializing.\n * - defaultValue is configured in Field, it will trigger when this Field is initializing if no initial value is set to this field.\n */\n onValueInit = 'onValueInit',\n /**\n * When Value Init or change\n */\n onValueInitOrChange = 'onValueInitOrChange',\n /* It will trigger when ArrayField.append is called. It relies on ArrayField's rendering. If ArrayField is possibly not rendered in your case, please avoid using this event */\n onArrayAppend = 'onArrayAppend',\n /* It will trigger when ArrayField.delete is called. It relies on ArrayField's rendering. If ArrayField is possibly not rendered in your case, please avoid using this event */\n onArrayDelete = 'onArrayDelete',\n}\n\nexport type EffectReturn = () => void;\n\nexport interface EffectFuncProps<TFieldValue = any, TFormValues = any> {\n name: FieldName;\n value: TFieldValue;\n prevValue?: TFieldValue;\n formValues: TFormValues;\n form: IForm;\n context: NodeContext;\n}\n\nexport type Effect<TFieldValue = any, TFormValues = any> = (\n props: EffectFuncProps<TFieldValue, TFormValues>\n) => void | EffectReturn;\n\nexport type ArrayAppendEffect<TFieldValue = any, TFormValues = any> = (props: {\n index: number;\n value: TFieldValue;\n arrayValues: Array<TFieldValue>;\n formValues: TFormValues;\n form: IForm;\n context: NodeContext;\n}) => void | EffectReturn;\n\nexport type ArrayDeleteEffect<TFieldValue = any, TFormValues = any> = (props: {\n index: number;\n arrayValue: Array<TFieldValue>;\n formValues: TFormValues;\n form: IForm;\n context: NodeContext;\n}) => void | EffectReturn;\n\nexport type EffectOptions =\n | { effect: Effect; event: DataEvent }\n | { effect: ArrayAppendEffect; event: DataEvent }\n | { effect: ArrayDeleteEffect; event: DataEvent };\n\nexport interface FormMeta<TValues = any> {\n /**\n * The render method of the node form content. <Form /> is already integrated, so you don't need to wrap your components with <Form />\n * @param props\n */\n render: (props: FormRenderProps<any>) => React.ReactElement;\n /**\n * When to trigger the validation.\n */\n validateTrigger?: ValidateTrigger;\n /**\n * Form data's validation rules. It's a key value map, where the key is a pattern of data's path (or field name), the value is a validate function.\n */\n validate?: Record<FieldName, Validate>;\n /**\n * Form data's effects. It's a key value map, where the key is a pattern of data's path (or field name), the value is an array of effect configuration.\n */\n effect?: Record<FieldName, EffectOptions[]>;\n /**\n * Form data's complete default value. it will not be sent to formatOnInit, but used directly as form's value when needed.\n */\n defaultValues?: TValues | ((context: NodeContext) => TValues);\n /**\n * This function is to format the value when initiate the form, the returned value will be used as the initial value of the form.\n * @param value value input to node as initialValue.\n * @param context\n */\n formatOnInit?: (value: any, context: NodeContext) => any;\n /**\n * This function is to format the value when FormModel.toJSON is called, the returned value will be used as the final value to be saved .\n * @param value value sent by form before format.\n * @param context\n */\n formatOnSubmit?: (value: any, context: NodeContext) => any;\n /**\n * Form's plugins\n */\n plugins?: FormPlugin[];\n}\n\nexport function isFormModelV2(fm: FormModel | FormModelV2): fm is FormModelV2 {\n return 'onFormValuesChange' in fm;\n}\n\nexport function isFormMetaV2(formMeta: IFormMeta | FormMeta) {\n return 'render' in formMeta;\n}\n\nexport type FormPluginCtx = {\n formModel: FormModelV2;\n} & NodeContext;\n\nexport interface onFormValueChangeInPayload<TValue = FieldValue, TFormValues = FieldValue> {\n value: TValue;\n prevValue: TValue;\n formValues: TFormValues;\n prevFormValues: TFormValues;\n}\n","import { get, groupBy, isEmpty, mapKeys } from 'lodash';\nimport { Disposable, DisposableCollection, Emitter } from '@flowgram.ai/utils';\nimport {\n FlowNodeFormData,\n FormFeedback,\n FormItem,\n FormManager,\n FormModel,\n FormModelValid,\n IFormItem,\n OnFormValuesChangePayload,\n} from '@flowgram.ai/form-core';\nimport {\n createForm,\n FieldArrayModel,\n FieldName,\n FieldValue,\n type FormControl,\n FormModel as NativeFormModel,\n FormValidateReturn,\n Glob,\n IField,\n IFieldArray,\n toForm,\n} from '@flowgram.ai/form';\nimport { FlowNodeEntity } from '@flowgram.ai/document';\nimport { PlaygroundContext, PluginContext } from '@flowgram.ai/core';\n\nimport {\n convertGlobPath,\n findMatchedInMap,\n formFeedbacksToNodeCoreFormFeedbacks,\n mergeEffectMap,\n} from './utils';\nimport {\n DataEvent,\n Effect,\n EffectOptions,\n EffectReturn,\n FormMeta,\n onFormValueChangeInPayload,\n} from './types';\nimport { renderForm } from './form-render';\nimport { FormPlugin } from './form-plugin';\n\nconst DEFAULT = {\n // Different formModel should have different reference\n EFFECT_MAP: () => ({}),\n EFFECT_RETURN_MAP: () =>\n new Map([\n [DataEvent.onValueInitOrChange, {}],\n [DataEvent.onValueChange, {}],\n [DataEvent.onValueInit, {}],\n [DataEvent.onArrayAppend, {}],\n [DataEvent.onArrayDelete, {}],\n ]),\n FORM_FEEDBACKS: () => [],\n VALID: null,\n};\n\nexport class FormModelV2 extends FormModel implements Disposable {\n protected effectMap: Record<string, EffectOptions[]> = DEFAULT.EFFECT_MAP();\n\n protected effectReturnMap: Map<DataEvent, Record<string, EffectReturn>> =\n DEFAULT.EFFECT_RETURN_MAP();\n\n protected plugins: FormPlugin[] = [];\n\n protected node: FlowNodeEntity;\n\n protected formFeedbacks: FormValidateReturn | undefined = DEFAULT.FORM_FEEDBACKS();\n\n protected onInitializedEmitter = new Emitter<FormModel>();\n\n protected onValidateEmitter = new Emitter<FormModel>();\n\n readonly onValidate = this.onValidateEmitter.event;\n\n readonly onInitialized = this.onInitializedEmitter.event;\n\n protected onDisposeEmitter = new Emitter<void>();\n\n readonly onDispose = this.onDisposeEmitter.event;\n\n protected toDispose = new DisposableCollection();\n\n protected onFormValuesChangeEmitter = new Emitter<OnFormValuesChangePayload>();\n\n readonly onFormValuesChange = this.onFormValuesChangeEmitter.event;\n\n protected onValidChangeEmitter = new Emitter<FormModelValid>();\n\n readonly onValidChange = this.onValidChangeEmitter.event;\n\n protected onFeedbacksChangeEmitter = new Emitter<FormFeedback[]>();\n\n readonly onFeedbacksChange = this.onFeedbacksChangeEmitter.event;\n\n constructor(node: FlowNodeEntity) {\n super();\n this.node = node;\n this.toDispose.pushAll([\n this.onInitializedEmitter,\n this.onValidateEmitter,\n this.onValidChangeEmitter,\n this.onFeedbacksChangeEmitter,\n this.onFormValuesChangeEmitter,\n ]);\n }\n\n protected _valid: FormModelValid = DEFAULT.VALID;\n\n get valid(): FormModelValid {\n return this._valid;\n }\n\n private set valid(valid: FormModelValid) {\n this._valid = valid;\n this.onValidChangeEmitter.fire(valid);\n }\n\n get flowNodeEntity() {\n return this.node;\n }\n\n get formManager() {\n return this.node.getService(FormManager);\n }\n\n protected _formControl?: FormControl<any>;\n\n get formControl() {\n return this._formControl;\n }\n\n get formMeta() {\n return this.node.getNodeRegistry().formMeta;\n }\n\n get values() {\n return this.nativeFormModel?.values;\n }\n\n protected _feedbacks: FormFeedback[] = [];\n\n get feedbacks(): FormFeedback[] {\n return this._feedbacks;\n }\n\n updateFormValues(value: any) {\n if (this.nativeFormModel) {\n const finalValue = this.formMeta.formatOnInit\n ? this.formMeta.formatOnInit(value, this.nodeContext)\n : value;\n this.nativeFormModel.values = finalValue;\n }\n }\n\n private set feedbacks(feedbacks: FormFeedback[]) {\n this._feedbacks = feedbacks;\n this.onFeedbacksChangeEmitter.fire(feedbacks);\n }\n\n get formItemPathMap(): Map<string, IFormItem> {\n return new Map<string, IFormItem>();\n }\n\n protected _initialized: boolean = false;\n\n get initialized(): boolean {\n return this._initialized;\n }\n\n get nodeContext() {\n return {\n node: this.node,\n playgroundContext: this.node.getService(PlaygroundContext),\n clientContext: this.node.getService(PluginContext),\n };\n }\n\n get nativeFormModel(): NativeFormModel | undefined {\n return this._formControl?._formModel;\n }\n\n render() {\n return renderForm(this);\n }\n\n initPlugins(plugins: FormPlugin[]) {\n if (!plugins.length) {\n return;\n }\n\n this.plugins = plugins;\n plugins.forEach((plugin) => {\n plugin.init(this);\n if (plugin.config?.effect) {\n mergeEffectMap(this.effectMap, plugin.config.effect);\n }\n });\n }\n\n init(formMeta: FormMeta, rawInitialValues?: any) {\n /* 透传 onFormValuesChange 事件给 FlowNodeFormData */\n const formData = this.node.getData<FlowNodeFormData>(FlowNodeFormData);\n this.onFormValuesChange(() => {\n this._valid = null;\n formData.fireChange();\n });\n\n const { validateTrigger, validate, effect } = formMeta;\n if (effect) {\n this.effectMap = effect;\n }\n\n // 计算初始值: defaultValues 是默认表单值,不需要被format, 而rawInitialValues 是用户创建form 时传入的初始值,可能不同于表单数据格式,需要被format\n const defaultValues =\n typeof formMeta.defaultValues === 'function'\n ? formMeta.defaultValues(this.nodeContext)\n : formMeta.defaultValues;\n\n const initialValues = formMeta.formatOnInit\n ? formMeta.formatOnInit(rawInitialValues, this.nodeContext)\n : rawInitialValues;\n\n // 初始化底层表单\n const { control } = createForm({\n initialValues: initialValues || defaultValues,\n validateTrigger,\n context: this.nodeContext,\n validate: validate,\n disableAutoInit: true,\n });\n\n this._formControl = control;\n const nativeFormModel = control._formModel;\n this.toDispose.push(nativeFormModel);\n\n // forward onFormValuesChange event\n nativeFormModel.onFormValuesChange((props) => {\n this.onFormValuesChangeEmitter.fire(props);\n });\n\n if (formMeta.plugins) {\n this.initPlugins(formMeta.plugins);\n }\n\n // Form 数据变更时触发对应的effect\n nativeFormModel.onFormValuesChange(({ values, prevValues, name }) => {\n // 找到所有路径匹配的副作用,包括父亲路径\n const effectKeys = Object.keys(this.effectMap).filter((pattern) =>\n Glob.isMatchOrParent(pattern, name)\n );\n\n effectKeys.forEach((effectKey) => {\n const effectOptionsArr = this.effectMap[effectKey];\n // 执行该事件配置下所有 onValueChange 事件的 effect\n effectOptionsArr.forEach(({ effect, event }: EffectOptions) => {\n if (event === DataEvent.onValueChange || event === DataEvent.onValueInitOrChange) {\n // 对于冒泡的事件,需要获取 parent 的 name\n const currentName = Glob.getParentPathByPattern(effectKey, name);\n\n // 执行上一次effect 的 return\n const prevEffectReturn = this.effectReturnMap.get(event)?.[currentName];\n if (prevEffectReturn) {\n prevEffectReturn();\n }\n\n // 执行effect\n const effectReturn = (effect as Effect)({\n name: currentName,\n value: get(values, currentName),\n prevValue: get(prevValues, currentName),\n formValues: values,\n form: toForm(this.nativeFormModel!),\n context: this.nodeContext,\n });\n\n // 更新 effect return\n if (\n effectReturn &&\n typeof effectReturn === 'function' &&\n this.effectReturnMap.has(event)\n ) {\n const eventMap = this.effectReturnMap.get(event) as Record<string, EffectReturn>;\n eventMap[currentName] = effectReturn;\n }\n }\n });\n });\n });\n\n // Form 数据初始化时触发对应的effect\n nativeFormModel.onFormValuesInit(({ values, name, prevValues }) => {\n Object.keys(this.effectMap).forEach((pattern) => {\n // 找到匹配 pattern 的数据路径\n const paths = Glob.findMatchPaths(values, pattern);\n\n // 获取配置在该 pattern上的所有effect配置\n const effectOptionsArr = this.effectMap[pattern];\n\n effectOptionsArr.forEach(({ event, effect }: EffectOptions) => {\n if (event === DataEvent.onValueInit || event === DataEvent.onValueInitOrChange) {\n paths.forEach((path) => {\n // 对触发 init 事件的 name 或他的字 path 触发effect\n if (Glob.isMatchOrParent(name, path) || name === path) {\n // 执行上一次effect 的 return\n const prevEffectReturn = this.effectReturnMap.get(event)?.[path];\n if (prevEffectReturn) {\n prevEffectReturn();\n }\n\n const effectReturn = (effect as Effect)({\n name: path,\n value: get(values, path),\n formValues: values,\n prevValue: get(prevValues, path),\n form: toForm(this.nativeFormModel!),\n context: this.nodeContext,\n });\n\n // 更新 effect return\n if (\n effectReturn &&\n typeof effectReturn === 'function' &&\n this.effectReturnMap.has(event)\n ) {\n const eventMap = this.effectReturnMap.get(event) as Record<string, EffectReturn>;\n eventMap[path] = effectReturn;\n }\n }\n });\n }\n });\n });\n });\n\n // 为 Field 添加 effect, 主要针对array\n nativeFormModel.onFieldModelCreate((field) => {\n // register effect\n const effectOptionsArr = findMatchedInMap<EffectOptions[]>(field, this.effectMap);\n if (effectOptionsArr?.length) {\n // 按事件聚合\n const eventMap = groupBy(effectOptionsArr, 'event');\n\n mapKeys(eventMap, (optionsArr, event) => {\n const combinedEffect = (props: any) => {\n // 该事件下执行所有effect\n optionsArr.forEach(({ effect }) =>\n effect({\n ...props,\n formValues: nativeFormModel.values,\n form: toForm(this.nativeFormModel!),\n context: this.nodeContext,\n })\n );\n };\n\n switch (event) {\n case DataEvent.onArrayAppend:\n if (field instanceof FieldArrayModel) {\n (field as FieldArrayModel).onAppend(combinedEffect);\n }\n break;\n case DataEvent.onArrayDelete:\n if (field instanceof FieldArrayModel) {\n (field as FieldArrayModel).onDelete(combinedEffect);\n }\n break;\n }\n });\n }\n });\n\n // 手动初始化form\n this._formControl.init();\n\n this._initialized = true;\n\n this.onInitializedEmitter.fire(this);\n\n this.onDispose(() => {\n this._initialized = false;\n this.effectMap = {};\n nativeFormModel.dispose();\n });\n }\n\n toJSON() {\n if (this.formMeta.formatOnSubmit) {\n return this.formMeta.formatOnSubmit(this.nativeFormModel?.values, this.nodeContext);\n }\n return this.nativeFormModel?.values;\n }\n\n clearValid() {\n if (this.valid !== null) {\n this.valid = null;\n }\n }\n\n async validate() {\n this.formFeedbacks = await this.nativeFormModel?.validate();\n this.valid = isEmpty(this.formFeedbacks?.filter((f) => f.level === 'error'));\n this.onValidateEmitter.fire(this);\n return this.valid;\n }\n\n getValues<T = any>(): T | undefined {\n return this._formControl?._formModel.values;\n }\n\n getField<\n TValue = FieldValue,\n TField extends IFieldArray<TValue> | IField<TValue> = IField<TValue>\n >(name: FieldName): TField | undefined {\n let finalName = name.includes('/') ? convertGlobPath(name) : name;\n\n return this.formControl?.getField<TValue, TField>(finalName) as TField;\n }\n\n getValueIn<TValue>(name: FieldName): TValue | undefined {\n let finalName = name.includes('/') ? convertGlobPath(name) : name;\n\n return this.nativeFormModel?.getValueIn(finalName);\n }\n\n setValueIn(name: FieldName, value: any) {\n let finalName = name.includes('/') ? convertGlobPath(name) : name;\n\n this.nativeFormModel?.setValueIn(finalName, value);\n }\n\n /**\n * 监听表单某个路径下的值变化\n * @param name 路径\n * @param callback 回调函数\n */\n onFormValueChangeIn<TValue = FieldValue, TFormValue = FieldValue>(\n name: FieldName,\n callback: (payload: onFormValueChangeInPayload<TValue, TFormValue>) => void\n ): Disposable {\n if (!this._initialized) {\n throw new Error(\n `[NodeEngine] FormModel Error: onFormValueChangeIn can not be called before initialized`\n );\n }\n\n return this.formControl!._formModel.onFormValuesChange(\n ({ name: changedName, values, prevValues }) => {\n if (changedName === name) {\n callback({\n value: get(values, name),\n prevValue: get(prevValues, name),\n formValues: values,\n prevFormValues: prevValues,\n });\n }\n }\n );\n }\n\n /**\n * @deprecated 该方法用于兼容 V1 版本 FormModel接口,如果确定是FormModelV2 请使用 FormModel.getValueIn\n * @param path glob path\n */\n getFormItemValueByPath(globPath: string) {\n if (!globPath) {\n return;\n }\n if (globPath === '/') {\n return this._formControl?._formModel.values;\n }\n const name = convertGlobPath(globPath);\n return this.getValueIn(name!);\n }\n\n async validateWithFeedbacks(): Promise<FormFeedback[]> {\n await this.validate();\n return formFeedbacksToNodeCoreFormFeedbacks(this.formFeedbacks!);\n }\n\n /**\n * @deprecated 该方法用于兼容 V1 版本 FormModel接口,如果确定是FormModelV2, 请使用FormModel.getValueIn 和 FormModel.setValueIn\n * @param path glob path\n */\n getFormItemByPath(path: string): FormItem | undefined {\n if (!this.nativeFormModel) {\n return;\n }\n\n const that = this;\n\n if (path === '/') {\n return {\n get value() {\n return that.nativeFormModel!.values;\n },\n set value(v) {\n that.nativeFormModel!.values = v;\n },\n } as FormItem;\n }\n\n const name = convertGlobPath(path);\n const formItemValue = that.getValueIn(name!);\n return {\n get value() {\n return formItemValue;\n },\n set value(v) {\n that.setValueIn(name, v);\n },\n } as FormItem;\n }\n\n dispose(): void {\n this.onDisposeEmitter.fire();\n\n // 执行所有effect return\n this.effectReturnMap.forEach((eventMap) => {\n Object.values(eventMap).forEach((effectReturn) => {\n effectReturn();\n });\n });\n\n this.effectMap = DEFAULT.EFFECT_MAP();\n this.effectReturnMap = DEFAULT.EFFECT_RETURN_MAP();\n\n this.plugins.forEach((p) => {\n p.dispose();\n });\n\n this.plugins = [];\n\n this.formFeedbacks = DEFAULT.FORM_FEEDBACKS();\n this._valid = DEFAULT.VALID;\n\n this._formControl = undefined;\n this._initialized = false;\n this.toDispose.dispose();\n }\n}\n","import { find, mergeWith } from 'lodash';\nimport { FormFeedback, FormPathService } from '@flowgram.ai/form-core';\nimport { FormValidateReturn } from '@flowgram.ai/form/src/types';\nimport { type FieldModel, FieldName } from '@flowgram.ai/form';\n\nimport { EffectOptions } from './types';\n\nexport function findMatchedInMap<T = any>(\n field: FieldModel<any>,\n validateMap: Record<FieldName, T> | undefined\n): T | undefined {\n if (!validateMap) {\n return;\n }\n if (validateMap[field.name]) {\n return validateMap[field.name];\n }\n\n const found = find(Object.keys(validateMap), (key) => {\n if (key.startsWith('regex:')) {\n const regex = RegExp(key.split(':')[1]);\n return regex.test(field.name);\n }\n return false;\n });\n\n if (found) {\n return validateMap[found];\n }\n}\n\nexport function formFeedbacksToNodeCoreFormFeedbacks(\n formFeedbacks: FormValidateReturn\n): FormFeedback[] {\n return formFeedbacks.map(\n (f) =>\n ({\n feedbackStatus: f.level,\n feedbackText: f.message,\n path: f.name,\n } as FormFeedback)\n );\n}\n\nexport function convertGlobPath(path: string) {\n if (path.startsWith('/')) {\n const parts = FormPathService.normalize(path).slice(1).split('/');\n return parts.join('.');\n }\n return path;\n}\n\nexport function mergeEffectMap(\n origin: Record<string, EffectOptions[]>,\n source: Record<string, EffectOptions[]>\n) {\n return mergeWith(origin, source, function (objValue: EffectOptions[], srcValue: EffectOptions[]) {\n return (objValue || []).concat(srcValue);\n });\n}\n","import React from 'react';\n\nimport { Form } from '@flowgram.ai/form';\n\nimport { FormModelV2 } from './form-model-v2';\n\ninterface FormRenderProps {\n formModel: FormModelV2;\n}\n\nconst FormRender = ({ formModel }: FormRenderProps) =>\n formModel?.formControl ? (\n <>\n <Form control={formModel?.formControl} keepModelOnUnMount>\n {formModel.formMeta.render}\n </Form>\n </>\n ) : null;\n\nexport function renderForm(formModel: FormModelV2) {\n return <FormRender formModel={formModel} />;\n}\n","import { FlowNodeFormData } from '@flowgram.ai/form-core';\nimport { FlowNodeEntity } from '@flowgram.ai/document';\n\nimport { DataEvent } from './types';\nimport { FormModelV2 } from './form-model-v2';\n\nexport function getFormModel(node: FlowNodeEntity) {\n // @ts-ignore\n return node.getData<FlowNodeFormData>(FlowNodeFormData)?.formModel as FormModelV2;\n}\n\nexport function isFormV2(node: FlowNodeEntity) {\n return !!node.getNodeRegistry().formMeta?.render;\n}\n\nexport function createEffectOptions<T>(\n event: DataEvent,\n effect: T\n): { effect: T; event: DataEvent } {\n return {\n event,\n effect,\n };\n}\n","import { useEffect } from 'react';\n\nimport { useRefresh } from '@flowgram.ai/utils';\nimport { FlowNodeFormData } from '@flowgram.ai/form-core';\nimport { Errors, Warnings } from '@flowgram.ai/form/src/types';\nimport { FormState, useFormErrors, useFormState, useFormWarnings } from '@flowgram.ai/form';\nimport { FlowNodeEntity } from '@flowgram.ai/document';\n\nimport { FormModelV2 } from './form-model-v2';\n\n/**\n * Listen to Form's values and refresh the React component.\n * By providing related node, you can use this hook outside the Form Component.\n * @param node\n */\nexport function useWatchFormValues<T = any>(node: FlowNodeEntity): T | undefined {\n const formModel = node.getData(FlowNodeFormData).getFormModel<FormModelV2>();\n const refresh = useRefresh();\n\n useEffect(() => {\n const disposable = formModel.nativeFormModel?.onFormValuesChange(() => {\n refresh();\n });\n return () => disposable?.dispose();\n }, [formModel.nativeFormModel]);\n\n return formModel.getValues<T>();\n}\n\n/**\n * Listen to Form's value in a certain path and refresh the React component.\n * By providing related node, you can use this hook outside the Form Component.\n * @param node\n */\nexport function useWatchFormValueIn<T = any>(node: FlowNodeEntity, name: string): T | undefined {\n const formModel = node.getData(FlowNodeFormData).getFormModel<FormModelV2>();\n const refresh = useRefresh();\n\n useEffect(() => {\n const disposable = formModel.nativeFormModel?.onFormValuesChange(({ name: changedName }) => {\n if (name === changedName) {\n refresh();\n }\n });\n\n return () => disposable?.dispose();\n }, []);\n\n return formModel.getValueIn<T>(name);\n}\n\n/**\n * Listen to FormModel's initialization and refresh React component.\n * By providing related node, you can use this hook outside the Form Component.\n * @param node\n */\nexport function useInitializedFormModel(node: FlowNodeEntity) {\n const formModel = node.getData(FlowNodeFormData).getFormModel<FormModelV2>();\n const refresh = useRefresh();\n\n useEffect(() => {\n const disposable = formModel.onInitialized(() => {\n refresh();\n });\n return () => disposable.dispose();\n }, [formModel]);\n\n return formModel;\n}\n\n/**\n * Get Form's state, Form State is a proxy, it will refresh the React component when the value you accessed changed\n * By providing related node, you can use this hook outside the Form Component.\n * @param node\n */\nexport function useWatchFormState(node: FlowNodeEntity): FormState | undefined {\n const formModel = useInitializedFormModel(node);\n return useFormState(formModel.formControl);\n}\n\n/**\n * Get Form's errors, Form errors is a proxy, it will refresh the React component when the value you accessed changed\n * By providing related node, you can use this hook outside the Form Component.\n * @param node\n */\nexport function useWatchFormErrors(node: FlowNodeEntity): Errors | undefined {\n const formModel = useInitializedFormModel(node);\n return useFormErrors(formModel.formControl);\n}\n\n/**\n * Get Form's warnings, Form warnings is a proxy, it will refresh the React component when the value you accessed changed\n * By providing related node, you can use this hook outside the Form Component.\n * @param node\n */\nexport function useWatchFormWarnings(node: FlowNodeEntity): Warnings | undefined {\n const formModel = useInitializedFormModel(node);\n return useFormWarnings(formModel.formControl);\n}\n","import { nanoid } from 'nanoid';\nimport { Disposable } from '@flowgram.ai/utils';\n\nimport { EffectOptions, FormPluginCtx } from './types';\nimport { FormModelV2 } from './form-model-v2';\n\nexport interface FormPluginConfig<Opts = any> {\n /**\n * FormModel 初始化时执行\n * @param ctx\n */\n onInit?: (ctx: FormPluginCtx, opts: Opts) => void;\n\n /**\n * 同 FormMeta 中的effects 会与 FormMeta 中的effects 合并\n */\n effect?: Record<string, EffectOptions[]>;\n /**\n * FormModel 销毁时执行\n * @param ctx\n */\n onDispose?: (ctx: FormPluginCtx, opts: Opts) => void;\n}\n\nexport class FormPlugin<Opts = any> implements Disposable {\n readonly name: string;\n\n readonly pluginId: string;\n\n readonly config: FormPluginConfig;\n\n readonly opts?: Opts;\n\n protected _formModel: FormModelV2;\n\n constructor(name: string, config: FormPluginConfig, opts?: Opts) {\n this.name = name;\n this.pluginId = `${name}__${nanoid()}`;\n this.config = config;\n this.opts = opts;\n }\n\n get formModel(): FormModelV2 {\n return this._formModel;\n }\n\n get ctx() {\n return {\n formModel: this.formModel,\n node: this.formModel.nodeContext.node,\n playgroundContext: this.formModel.nodeContext.playgroundContext,\n };\n }\n\n init(formModel: FormModelV2) {\n this._formModel = formModel;\n this.config?.onInit?.(this.ctx, this.opts);\n }\n\n dispose() {\n if (this.config?.onDispose) {\n this.config?.onDispose(this.ctx, this.opts);\n }\n }\n}\n\nexport function defineFormPluginCreator<Opts>(name: string, config: FormPluginConfig) {\n return function (opts: Opts) {\n return new FormPlugin(name, config, opts);\n };\n}\n","import React from 'react';\n\nimport { Disposable, Event } from '@flowgram.ai/utils';\nimport { FlowNodeFormData, NodeRender, OnFormValuesChangePayload } from '@flowgram.ai/form-core';\nimport { FieldName, FieldValue, FormState } from '@flowgram.ai/form';\nimport { FlowNodeEntity } from '@flowgram.ai/document';\n\nimport { onFormValueChangeInPayload } from './types';\nimport { FormModelV2 } from './form-model-v2';\n\nexport interface NodeFormProps<TValues> {\n /**\n * The initialValues of the form.\n */\n initialValues: TValues;\n /**\n * Form values. Returns a deep copy of the data in the store.\n */\n values: TValues;\n /**\n * Form state\n */\n state: FormState;\n /**\n * Get value in certain path\n * @param name path\n */\n getValueIn<TValue = FieldValue>(name: FieldName): TValue;\n\n /**\n * Set value in certain path.\n * It will trigger the re-rendering of the Field Component if a Field is related to this path\n * @param name path\n */\n setValueIn<TValue>(name: FieldName, value: TValue): void;\n /**\n * set form values\n */\n updateFormValues(values: any): void;\n /**\n * Render form\n */\n render: () => React.ReactNode;\n /**\n * Form value change event\n */\n onFormValuesChange: Event<OnFormValuesChangePayload>;\n /**\n * Trigger form validate\n */\n validate: () => Promise<boolean>;\n /**\n * Form validate event\n */\n onValidate: Event<FormState>;\n /**\n * Form field value change event\n */\n onFormValueChangeIn<TValue = FieldValue, TFormValue = FieldValue>(\n name: FieldName,\n callback: (payload: onFormValueChangeInPayload<TValue, TFormValue>) => void\n ): Disposable;\n}\n\n/**\n * Only support FormModelV2\n * @param node\n */\nexport function getNodeForm<TValues = FieldValue>(\n node: FlowNodeEntity\n): NodeFormProps<TValues> | undefined {\n const formModel = node.getData<FlowNodeFormData>(FlowNodeFormData)?.getFormModel<FormModelV2>();\n const nativeFormModel = formModel?.nativeFormModel;\n\n if (!formModel || !nativeFormModel) return undefined;\n\n const result: NodeFormProps<TValues> = {\n initialValues: nativeFormModel.initialValues,\n get values() {\n return nativeFormModel.values;\n },\n\n state: nativeFormModel.state,\n getValueIn: (name: FieldName) => nativeFormModel.getValueIn(name),\n setValueIn: (name: FieldName, value: any) => nativeFormModel.setValueIn(name, value),\n updateFormValues: (values: any) => {\n formModel.updateFormValues(values);\n },\n render: () => <NodeRender node={node} />,\n onFormValuesChange: formModel.onFormValuesChange.bind(formModel),\n onFormValueChangeIn: formModel.onFormValueChangeIn.bind(formModel),\n onValidate: formModel.nativeFormModel.onValidate,\n validate: formModel.validate.bind(formModel),\n };\n\n Object.defineProperty(result, '_formModel', {\n enumerable: false,\n get() {\n return formModel;\n },\n });\n return result;\n}\n"],"mappings":"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","names":["DataEvent","effect","FlowNodeFormData","FlowNodeFormData","React","FlowNodeFormData"]}
|
|
1
|
+
{"version":3,"sources":["../../src/types.ts","../../src/form-model-v2.ts","../../src/utils.ts","../../src/form-render.tsx","../../src/helpers.ts","../../src/hooks.ts","../../src/form-plugin.ts","../../src/get-node-form.tsx"],"sourcesContent":["/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport * as React from 'react';\n\nimport { FormModel, IFormMeta, NodeFormContext } from '@flowgram.ai/form-core';\nimport { FieldName, FieldValue } from '@flowgram.ai/form/src/types';\nimport {\n FormRenderProps,\n IForm,\n Validate as FormValidate,\n ValidateTrigger,\n} from '@flowgram.ai/form';\n\nimport { FormPlugin } from './form-plugin';\nimport { FormModelV2 } from './form-model-v2';\n\nexport interface Node {}\n\nexport interface Flow {}\n\n/**\n * NodeContext contains\n * - node: the Editor's node entity.\n * - playgroundContext: the Editor's playgroundContext injected when initiate the Editor.\n */\ntype NodeContext = NodeFormContext;\n\nexport type Validate<TFieldValue = any, TFormValues = any> = (props: {\n value: TFieldValue;\n formValues: TFormValues;\n context: NodeContext;\n name: FieldName;\n}) => ReturnType<FormValidate<TFieldValue, TFormValues>>;\n\nexport enum DataEvent {\n /* When value change */\n onValueChange = 'onValueChange',\n /**\n * When value Init,it triggers when\n * - defaultValue is configured in formMeta, it will trigger when form is initializing.\n * - defaultValue is configured in Field, it will trigger when this Field is initializing if no initial value is set to this field.\n */\n onValueInit = 'onValueInit',\n /**\n * When Value Init or change\n */\n onValueInitOrChange = 'onValueInitOrChange',\n /* It will trigger when ArrayField.append is called. It relies on ArrayField's rendering. If ArrayField is possibly not rendered in your case, please avoid using this event */\n onArrayAppend = 'onArrayAppend',\n /* It will trigger when ArrayField.delete is called. It relies on ArrayField's rendering. If ArrayField is possibly not rendered in your case, please avoid using this event */\n onArrayDelete = 'onArrayDelete',\n}\n\nexport type EffectReturn = () => void;\n\nexport interface EffectFuncProps<TFieldValue = any, TFormValues = any> {\n name: FieldName;\n value: TFieldValue;\n prevValue?: TFieldValue;\n formValues: TFormValues;\n form: IForm;\n context: NodeContext;\n}\n\nexport type Effect<TFieldValue = any, TFormValues = any> = (\n props: EffectFuncProps<TFieldValue, TFormValues>\n) => void | EffectReturn;\n\nexport type ArrayAppendEffect<TFieldValue = any, TFormValues = any> = (props: {\n index: number;\n value: TFieldValue;\n arrayValues: Array<TFieldValue>;\n formValues: TFormValues;\n form: IForm;\n context: NodeContext;\n}) => void | EffectReturn;\n\nexport type ArrayDeleteEffect<TFieldValue = any, TFormValues = any> = (props: {\n index: number;\n arrayValue: Array<TFieldValue>;\n formValues: TFormValues;\n form: IForm;\n context: NodeContext;\n}) => void | EffectReturn;\n\nexport type EffectOptions =\n | { effect: Effect; event: DataEvent }\n | { effect: ArrayAppendEffect; event: DataEvent }\n | { effect: ArrayDeleteEffect; event: DataEvent };\n\nexport interface FormMeta<TValues = any> {\n /**\n * The render method of the node form content. <Form /> is already integrated, so you don't need to wrap your components with <Form />\n * @param props\n */\n render: (props: FormRenderProps<any>) => React.ReactElement;\n /**\n * When to trigger the validation.\n */\n validateTrigger?: ValidateTrigger;\n /**\n * Form data's validation rules. It's a key value map, where the key is a pattern of data's path (or field name), the value is a validate function.\n */\n validate?: Record<FieldName, Validate>;\n /**\n * Form data's effects. It's a key value map, where the key is a pattern of data's path (or field name), the value is an array of effect configuration.\n */\n effect?: Record<FieldName, EffectOptions[]>;\n /**\n * Form data's complete default value. it will not be sent to formatOnInit, but used directly as form's value when needed.\n */\n defaultValues?: TValues | ((context: NodeContext) => TValues);\n /**\n * This function is to format the value when initiate the form, the returned value will be used as the initial value of the form.\n * @param value value input to node as initialValue.\n * @param context\n */\n formatOnInit?: (value: any, context: NodeContext) => any;\n /**\n * This function is to format the value when FormModel.toJSON is called, the returned value will be used as the final value to be saved .\n * @param value value sent by form before format.\n * @param context\n */\n formatOnSubmit?: (value: any, context: NodeContext) => any;\n /**\n * Form's plugins\n */\n plugins?: FormPlugin[];\n}\n\nexport function isFormModelV2(fm: FormModel | FormModelV2): fm is FormModelV2 {\n return 'onFormValuesChange' in fm;\n}\n\nexport function isFormMetaV2(formMeta: IFormMeta | FormMeta) {\n return 'render' in formMeta;\n}\n\nexport type FormPluginCtx = {\n formModel: FormModelV2;\n} & NodeContext;\n\nexport type FormPluginSetupMetaCtx = {\n mergeEffect: (effect: Record<string, EffectOptions[]>) => void;\n mergeValidate: (validate: Record<FieldName, Validate>) => void;\n addFormatOnInit: (formatOnInit: FormMeta['formatOnInit']) => void;\n addFormatOnSubmit: (formatOnSubmit: FormMeta['formatOnSubmit']) => void;\n} & NodeContext;\n\nexport interface onFormValueChangeInPayload<TValue = FieldValue, TFormValues = FieldValue> {\n value: TValue;\n prevValue: TValue;\n formValues: TFormValues;\n prevFormValues: TFormValues;\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { get, groupBy, isEmpty, mapKeys } from 'lodash';\nimport { Disposable, DisposableCollection, Emitter } from '@flowgram.ai/utils';\nimport {\n FlowNodeFormData,\n FormFeedback,\n FormItem,\n FormManager,\n FormModel,\n FormModelValid,\n IFormItem,\n OnFormValuesChangePayload,\n} from '@flowgram.ai/form-core';\nimport {\n createForm,\n FieldArrayModel,\n FieldName,\n FieldValue,\n type FormControl,\n FormModel as NativeFormModel,\n FormValidateReturn,\n Glob,\n IField,\n IFieldArray,\n toForm,\n} from '@flowgram.ai/form';\nimport { FlowNodeEntity } from '@flowgram.ai/document';\nimport { PlaygroundContext, PluginContext } from '@flowgram.ai/core';\n\nimport { convertGlobPath, findMatchedInMap, formFeedbacksToNodeCoreFormFeedbacks } from './utils';\nimport {\n DataEvent,\n Effect,\n EffectOptions,\n EffectReturn,\n FormMeta,\n onFormValueChangeInPayload,\n} from './types';\nimport { renderForm } from './form-render';\nimport { FormPlugin } from './form-plugin';\n\nconst DEFAULT = {\n // Different formModel should have different reference\n EFFECT_MAP: () => ({}),\n EFFECT_RETURN_MAP: () =>\n new Map([\n [DataEvent.onValueInitOrChange, {}],\n [DataEvent.onValueChange, {}],\n [DataEvent.onValueInit, {}],\n [DataEvent.onArrayAppend, {}],\n [DataEvent.onArrayDelete, {}],\n ]),\n FORM_FEEDBACKS: () => [],\n VALID: null,\n};\n\nexport class FormModelV2 extends FormModel implements Disposable {\n protected effectMap: Record<string, EffectOptions[]> = DEFAULT.EFFECT_MAP();\n\n protected effectReturnMap: Map<DataEvent, Record<string, EffectReturn>> =\n DEFAULT.EFFECT_RETURN_MAP();\n\n protected plugins: FormPlugin[] = [];\n\n protected node: FlowNodeEntity;\n\n protected formFeedbacks: FormValidateReturn | undefined = DEFAULT.FORM_FEEDBACKS();\n\n protected onInitializedEmitter = new Emitter<FormModel>();\n\n protected onValidateEmitter = new Emitter<FormModel>();\n\n readonly onValidate = this.onValidateEmitter.event;\n\n readonly onInitialized = this.onInitializedEmitter.event;\n\n protected onDisposeEmitter = new Emitter<void>();\n\n readonly onDispose = this.onDisposeEmitter.event;\n\n protected toDispose = new DisposableCollection();\n\n protected onFormValuesChangeEmitter = new Emitter<OnFormValuesChangePayload>();\n\n readonly onFormValuesChange = this.onFormValuesChangeEmitter.event;\n\n protected onValidChangeEmitter = new Emitter<FormModelValid>();\n\n readonly onValidChange = this.onValidChangeEmitter.event;\n\n protected onFeedbacksChangeEmitter = new Emitter<FormFeedback[]>();\n\n readonly onFeedbacksChange = this.onFeedbacksChangeEmitter.event;\n\n constructor(node: FlowNodeEntity) {\n super();\n this.node = node;\n this.toDispose.pushAll([\n this.onInitializedEmitter,\n this.onValidateEmitter,\n this.onValidChangeEmitter,\n this.onFeedbacksChangeEmitter,\n this.onFormValuesChangeEmitter,\n ]);\n }\n\n protected _valid: FormModelValid = DEFAULT.VALID;\n\n get valid(): FormModelValid {\n return this._valid;\n }\n\n private set valid(valid: FormModelValid) {\n this._valid = valid;\n this.onValidChangeEmitter.fire(valid);\n }\n\n get flowNodeEntity() {\n return this.node;\n }\n\n get formManager() {\n return this.node.getService(FormManager);\n }\n\n protected _formControl?: FormControl<any>;\n\n get formControl() {\n return this._formControl;\n }\n\n protected _formMeta: FormMeta;\n\n get formMeta(): FormMeta {\n return this._formMeta || (this.node.getNodeRegistry().formMeta as FormMeta);\n }\n\n get values() {\n return this.nativeFormModel?.values;\n }\n\n protected _feedbacks: FormFeedback[] = [];\n\n get feedbacks(): FormFeedback[] {\n return this._feedbacks;\n }\n\n updateFormValues(value: any) {\n if (this.nativeFormModel) {\n const finalValue = this.formMeta.formatOnInit\n ? this.formMeta.formatOnInit(value, this.nodeContext)\n : value;\n this.nativeFormModel.values = finalValue;\n }\n }\n\n private set feedbacks(feedbacks: FormFeedback[]) {\n this._feedbacks = feedbacks;\n this.onFeedbacksChangeEmitter.fire(feedbacks);\n }\n\n get formItemPathMap(): Map<string, IFormItem> {\n return new Map<string, IFormItem>();\n }\n\n protected _initialized: boolean = false;\n\n get initialized(): boolean {\n return this._initialized;\n }\n\n get nodeContext() {\n return {\n node: this.node,\n playgroundContext: this.node.getService(PlaygroundContext),\n clientContext: this.node.getService(PluginContext),\n };\n }\n\n get nativeFormModel(): NativeFormModel | undefined {\n return this._formControl?._formModel;\n }\n\n render() {\n return renderForm(this);\n }\n\n initPlugins(plugins: FormPlugin[]) {\n if (!plugins.length) {\n return;\n }\n\n this.plugins = plugins;\n plugins.forEach((plugin) => {\n plugin.init(this);\n });\n }\n\n init(formMeta: FormMeta, rawInitialValues?: any) {\n /* 透传 onFormValuesChange 事件给 FlowNodeFormData */\n const formData = this.node.getData<FlowNodeFormData>(FlowNodeFormData);\n this.onFormValuesChange(() => {\n this._valid = null;\n formData.fireChange();\n });\n\n (formMeta.plugins || [])?.forEach((_plugin) => {\n if (_plugin.setupFormMeta) {\n formMeta = _plugin.setupFormMeta(formMeta, this.nodeContext);\n }\n });\n\n this._formMeta = formMeta;\n\n const { validateTrigger, validate, effect } = formMeta;\n if (effect) {\n this.effectMap = effect;\n }\n\n // 计算初始值: defaultValues 是默认表单值,不需要被format, 而rawInitialValues 是用户创建form 时传入的初始值,可能不同于表单数据格式,需要被format\n const defaultValues =\n typeof formMeta.defaultValues === 'function'\n ? formMeta.defaultValues(this.nodeContext)\n : formMeta.defaultValues;\n\n const initialValues = formMeta.formatOnInit\n ? formMeta.formatOnInit(rawInitialValues, this.nodeContext)\n : rawInitialValues;\n\n // 初始化底层表单\n const { control } = createForm({\n initialValues: initialValues || defaultValues,\n validateTrigger,\n context: this.nodeContext,\n validate: validate,\n disableAutoInit: true,\n });\n\n this._formControl = control;\n const nativeFormModel = control._formModel;\n this.toDispose.push(nativeFormModel);\n\n // forward onFormValuesChange event\n nativeFormModel.onFormValuesChange((props) => {\n this.onFormValuesChangeEmitter.fire(props);\n });\n\n if (formMeta.plugins) {\n this.initPlugins(formMeta.plugins);\n }\n\n // Form 数据变更时触发对应的effect\n nativeFormModel.onFormValuesChange(({ values, prevValues, name }) => {\n // 找到所有路径匹配的副作用,包括父亲路径\n const effectKeys = Object.keys(this.effectMap).filter((pattern) =>\n Glob.isMatchOrParent(pattern, name)\n );\n\n effectKeys.forEach((effectKey) => {\n const effectOptionsArr = this.effectMap[effectKey];\n // 执行该事件配置下所有 onValueChange 事件的 effect\n effectOptionsArr.forEach(({ effect, event }: EffectOptions) => {\n if (event === DataEvent.onValueChange || event === DataEvent.onValueInitOrChange) {\n // 对于冒泡的事件,需要获取 parent 的 name\n const currentName = Glob.getParentPathByPattern(effectKey, name);\n\n // 执行上一次effect 的 return\n const prevEffectReturn = this.effectReturnMap.get(event)?.[currentName];\n if (prevEffectReturn) {\n prevEffectReturn();\n }\n\n // 执行effect\n const effectReturn = (effect as Effect)({\n name: currentName,\n value: get(values, currentName),\n prevValue: get(prevValues, currentName),\n formValues: values,\n form: toForm(this.nativeFormModel!),\n context: this.nodeContext,\n });\n\n // 更新 effect return\n if (\n effectReturn &&\n typeof effectReturn === 'function' &&\n this.effectReturnMap.has(event)\n ) {\n const eventMap = this.effectReturnMap.get(event) as Record<string, EffectReturn>;\n eventMap[currentName] = effectReturn;\n }\n }\n });\n });\n });\n\n // Form 数据初始化时触发对应的effect\n nativeFormModel.onFormValuesInit(({ values, name, prevValues }) => {\n Object.keys(this.effectMap).forEach((pattern) => {\n // 找到匹配 pattern 的数据路径\n const paths = Glob.findMatchPaths(values, pattern);\n\n // 获取配置在该 pattern上的所有effect配置\n const effectOptionsArr = this.effectMap[pattern];\n\n effectOptionsArr.forEach(({ event, effect }: EffectOptions) => {\n if (event === DataEvent.onValueInit || event === DataEvent.onValueInitOrChange) {\n paths.forEach((path) => {\n // 对触发 init 事件的 name 或他的字 path 触发effect\n if (Glob.isMatchOrParent(name, path) || name === path) {\n // 执行上一次effect 的 return\n const prevEffectReturn = this.effectReturnMap.get(event)?.[path];\n if (prevEffectReturn) {\n prevEffectReturn();\n }\n\n const effectReturn = (effect as Effect)({\n name: path,\n value: get(values, path),\n formValues: values,\n prevValue: get(prevValues, path),\n form: toForm(this.nativeFormModel!),\n context: this.nodeContext,\n });\n\n // 更新 effect return\n if (\n effectReturn &&\n typeof effectReturn === 'function' &&\n this.effectReturnMap.has(event)\n ) {\n const eventMap = this.effectReturnMap.get(event) as Record<string, EffectReturn>;\n eventMap[path] = effectReturn;\n }\n }\n });\n }\n });\n });\n });\n\n // 为 Field 添加 effect, 主要针对array\n nativeFormModel.onFieldModelCreate((field) => {\n // register effect\n const effectOptionsArr = findMatchedInMap<EffectOptions[]>(field, this.effectMap);\n if (effectOptionsArr?.length) {\n // 按事件聚合\n const eventMap = groupBy(effectOptionsArr, 'event');\n\n mapKeys(eventMap, (optionsArr, event) => {\n const combinedEffect = (props: any) => {\n // 该事件下执行所有effect\n optionsArr.forEach(({ effect }) =>\n effect({\n ...props,\n formValues: nativeFormModel.values,\n form: toForm(this.nativeFormModel!),\n context: this.nodeContext,\n })\n );\n };\n\n switch (event) {\n case DataEvent.onArrayAppend:\n if (field instanceof FieldArrayModel) {\n (field as FieldArrayModel).onAppend(combinedEffect);\n }\n break;\n case DataEvent.onArrayDelete:\n if (field instanceof FieldArrayModel) {\n (field as FieldArrayModel).onDelete(combinedEffect);\n }\n break;\n }\n });\n }\n });\n\n // 手动初始化form\n this._formControl.init();\n\n this._initialized = true;\n\n this.onInitializedEmitter.fire(this);\n\n this.onDispose(() => {\n this._initialized = false;\n this.effectMap = {};\n nativeFormModel.dispose();\n });\n }\n\n toJSON() {\n if (this.formMeta.formatOnSubmit) {\n return this.formMeta.formatOnSubmit(this.nativeFormModel?.values, this.nodeContext);\n }\n return this.nativeFormModel?.values;\n }\n\n clearValid() {\n if (this.valid !== null) {\n this.valid = null;\n }\n }\n\n async validate() {\n this.formFeedbacks = await this.nativeFormModel?.validate();\n this.valid = isEmpty(this.formFeedbacks?.filter((f) => f.level === 'error'));\n this.onValidateEmitter.fire(this);\n return this.valid;\n }\n\n getValues<T = any>(): T | undefined {\n return this._formControl?._formModel.values;\n }\n\n getField<\n TValue = FieldValue,\n TField extends IFieldArray<TValue> | IField<TValue> = IField<TValue>\n >(name: FieldName): TField | undefined {\n let finalName = name.includes('/') ? convertGlobPath(name) : name;\n\n return this.formControl?.getField<TValue, TField>(finalName) as TField;\n }\n\n getValueIn<TValue>(name: FieldName): TValue | undefined {\n let finalName = name.includes('/') ? convertGlobPath(name) : name;\n\n return this.nativeFormModel?.getValueIn(finalName);\n }\n\n setValueIn(name: FieldName, value: any) {\n let finalName = name.includes('/') ? convertGlobPath(name) : name;\n\n this.nativeFormModel?.setValueIn(finalName, value);\n }\n\n /**\n * 监听表单某个路径下的值变化\n * @param name 路径\n * @param callback 回调函数\n */\n onFormValueChangeIn<TValue = FieldValue, TFormValue = FieldValue>(\n name: FieldName,\n callback: (payload: onFormValueChangeInPayload<TValue, TFormValue>) => void\n ): Disposable {\n if (!this._initialized) {\n throw new Error(\n `[NodeEngine] FormModel Error: onFormValueChangeIn can not be called before initialized`\n );\n }\n\n return this.formControl!._formModel.onFormValuesChange(\n ({ name: changedName, values, prevValues }) => {\n if (changedName === name) {\n callback({\n value: get(values, name),\n prevValue: get(prevValues, name),\n formValues: values,\n prevFormValues: prevValues,\n });\n }\n }\n );\n }\n\n /**\n * @deprecated 该方法用于兼容 V1 版本 FormModel接口,如果确定是FormModelV2 请使用 FormModel.getValueIn\n * @param path glob path\n */\n getFormItemValueByPath(globPath: string) {\n if (!globPath) {\n return;\n }\n if (globPath === '/') {\n return this._formControl?._formModel.values;\n }\n const name = convertGlobPath(globPath);\n return this.getValueIn(name!);\n }\n\n async validateWithFeedbacks(): Promise<FormFeedback[]> {\n await this.validate();\n return formFeedbacksToNodeCoreFormFeedbacks(this.formFeedbacks!);\n }\n\n /**\n * @deprecated 该方法用于兼容 V1 版本 FormModel接口,如果确定是FormModelV2, 请使用FormModel.getValueIn 和 FormModel.setValueIn\n * @param path glob path\n */\n getFormItemByPath(path: string): FormItem | undefined {\n if (!this.nativeFormModel) {\n return;\n }\n\n const that = this;\n\n if (path === '/') {\n return {\n get value() {\n return that.nativeFormModel!.values;\n },\n set value(v) {\n that.nativeFormModel!.values = v;\n },\n } as FormItem;\n }\n\n const name = convertGlobPath(path);\n const formItemValue = that.getValueIn(name!);\n return {\n get value() {\n return formItemValue;\n },\n set value(v) {\n that.setValueIn(name, v);\n },\n } as FormItem;\n }\n\n dispose(): void {\n this.onDisposeEmitter.fire();\n\n // 执行所有effect return\n this.effectReturnMap.forEach((eventMap) => {\n Object.values(eventMap).forEach((effectReturn) => {\n effectReturn();\n });\n });\n\n this.effectMap = DEFAULT.EFFECT_MAP();\n this.effectReturnMap = DEFAULT.EFFECT_RETURN_MAP();\n\n this.plugins.forEach((p) => {\n p.dispose();\n });\n\n this.plugins = [];\n\n this.formFeedbacks = DEFAULT.FORM_FEEDBACKS();\n this._valid = DEFAULT.VALID;\n\n this._formControl = undefined;\n this._initialized = false;\n this.toDispose.dispose();\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { find, mergeWith } from 'lodash';\nimport { FormFeedback, FormPathService } from '@flowgram.ai/form-core';\nimport { FormValidateReturn } from '@flowgram.ai/form/src/types';\nimport { type FieldModel, FieldName } from '@flowgram.ai/form';\n\nimport { EffectOptions } from './types';\n\nexport function findMatchedInMap<T = any>(\n field: FieldModel<any>,\n validateMap: Record<FieldName, T> | undefined\n): T | undefined {\n if (!validateMap) {\n return;\n }\n if (validateMap[field.name]) {\n return validateMap[field.name];\n }\n\n const found = find(Object.keys(validateMap), (key) => {\n if (key.startsWith('regex:')) {\n const regex = RegExp(key.split(':')[1]);\n return regex.test(field.name);\n }\n return false;\n });\n\n if (found) {\n return validateMap[found];\n }\n}\n\nexport function formFeedbacksToNodeCoreFormFeedbacks(\n formFeedbacks: FormValidateReturn\n): FormFeedback[] {\n return formFeedbacks.map(\n (f) =>\n ({\n feedbackStatus: f.level,\n feedbackText: f.message,\n path: f.name,\n } as FormFeedback)\n );\n}\n\nexport function convertGlobPath(path: string) {\n if (path.startsWith('/')) {\n const parts = FormPathService.normalize(path).slice(1).split('/');\n return parts.join('.');\n }\n return path;\n}\n\nexport function mergeEffectMap(\n origin: Record<string, EffectOptions[]>,\n source: Record<string, EffectOptions[]>\n) {\n return mergeWith(origin, source, function (objValue: EffectOptions[], srcValue: EffectOptions[]) {\n return (objValue || []).concat(srcValue);\n });\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport React from 'react';\n\nimport { Form } from '@flowgram.ai/form';\n\nimport { FormModelV2 } from './form-model-v2';\n\ninterface FormRenderProps {\n formModel: FormModelV2;\n}\n\nconst FormRender = ({ formModel }: FormRenderProps) =>\n formModel?.formControl ? (\n <>\n <Form control={formModel?.formControl} keepModelOnUnMount>\n {formModel.formMeta.render}\n </Form>\n </>\n ) : null;\n\nexport function renderForm(formModel: FormModelV2) {\n return <FormRender formModel={formModel} />;\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { FlowNodeFormData } from '@flowgram.ai/form-core';\nimport { FlowNodeEntity } from '@flowgram.ai/document';\n\nimport { DataEvent } from './types';\nimport { FormModelV2 } from './form-model-v2';\n\nexport function getFormModel(node: FlowNodeEntity) {\n // @ts-ignore\n return node.getData<FlowNodeFormData>(FlowNodeFormData)?.formModel as FormModelV2;\n}\n\nexport function isFormV2(node: FlowNodeEntity) {\n return !!node.getNodeRegistry().formMeta?.render;\n}\n\nexport function createEffectOptions<T>(\n event: DataEvent,\n effect: T\n): { effect: T; event: DataEvent } {\n return {\n event,\n effect,\n };\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { useEffect } from 'react';\n\nimport { useRefresh } from '@flowgram.ai/utils';\nimport { FlowNodeFormData } from '@flowgram.ai/form-core';\nimport { Errors, Warnings } from '@flowgram.ai/form/src/types';\nimport { FormState, useFormErrors, useFormState, useFormWarnings } from '@flowgram.ai/form';\nimport { FlowNodeEntity } from '@flowgram.ai/document';\n\nimport { FormModelV2 } from './form-model-v2';\n\n/**\n * Listen to Form's values and refresh the React component.\n * By providing related node, you can use this hook outside the Form Component.\n * @param node\n */\nexport function useWatchFormValues<T = any>(node: FlowNodeEntity): T | undefined {\n const formModel = node.getData(FlowNodeFormData).getFormModel<FormModelV2>();\n const refresh = useRefresh();\n\n useEffect(() => {\n const disposable = formModel.nativeFormModel?.onFormValuesChange(() => {\n refresh();\n });\n return () => disposable?.dispose();\n }, [formModel.nativeFormModel]);\n\n return formModel.getValues<T>();\n}\n\n/**\n * Listen to Form's value in a certain path and refresh the React component.\n * By providing related node, you can use this hook outside the Form Component.\n * @param node\n */\nexport function useWatchFormValueIn<T = any>(node: FlowNodeEntity, name: string): T | undefined {\n const formModel = node.getData(FlowNodeFormData).getFormModel<FormModelV2>();\n const refresh = useRefresh();\n\n useEffect(() => {\n const disposable = formModel.nativeFormModel?.onFormValuesChange(({ name: changedName }) => {\n if (name === changedName) {\n refresh();\n }\n });\n\n return () => disposable?.dispose();\n }, []);\n\n return formModel.getValueIn<T>(name);\n}\n\n/**\n * Listen to FormModel's initialization and refresh React component.\n * By providing related node, you can use this hook outside the Form Component.\n * @param node\n */\nexport function useInitializedFormModel(node: FlowNodeEntity) {\n const formModel = node.getData(FlowNodeFormData).getFormModel<FormModelV2>();\n const refresh = useRefresh();\n\n useEffect(() => {\n const disposable = formModel.onInitialized(() => {\n refresh();\n });\n return () => disposable.dispose();\n }, [formModel]);\n\n return formModel;\n}\n\n/**\n * Get Form's state, Form State is a proxy, it will refresh the React component when the value you accessed changed\n * By providing related node, you can use this hook outside the Form Component.\n * @param node\n */\nexport function useWatchFormState(node: FlowNodeEntity): FormState | undefined {\n const formModel = useInitializedFormModel(node);\n return useFormState(formModel.formControl);\n}\n\n/**\n * Get Form's errors, Form errors is a proxy, it will refresh the React component when the value you accessed changed\n * By providing related node, you can use this hook outside the Form Component.\n * @param node\n */\nexport function useWatchFormErrors(node: FlowNodeEntity): Errors | undefined {\n const formModel = useInitializedFormModel(node);\n return useFormErrors(formModel.formControl);\n}\n\n/**\n * Get Form's warnings, Form warnings is a proxy, it will refresh the React component when the value you accessed changed\n * By providing related node, you can use this hook outside the Form Component.\n * @param node\n */\nexport function useWatchFormWarnings(node: FlowNodeEntity): Warnings | undefined {\n const formModel = useInitializedFormModel(node);\n return useFormWarnings(formModel.formControl);\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { nanoid } from 'nanoid';\nimport { Disposable } from '@flowgram.ai/utils';\nimport { type NodeFormContext } from '@flowgram.ai/form-core';\n\nimport { type FormMeta, type FormPluginCtx, type FormPluginSetupMetaCtx } from './types';\nimport { FormModelV2 } from './form-model-v2';\n\nexport interface FormPluginConfig<Opts = any> {\n /**\n * form plugin name, for debug use\n */\n name?: string;\n\n /**\n * setup formMeta\n * @param ctx\n * @returns\n */\n onSetupFormMeta?: (ctx: FormPluginSetupMetaCtx, opts: Opts) => void;\n\n /**\n * FormModel 初始化时执行\n * @param ctx\n */\n onInit?: (ctx: FormPluginCtx, opts: Opts) => void;\n\n /**\n * FormModel 销毁时执行\n */\n onDispose?: (ctx: FormPluginCtx, opts: Opts) => void;\n}\n\nexport class FormPlugin<Opts = any> implements Disposable {\n readonly name: string;\n\n readonly pluginId: string;\n\n readonly config: FormPluginConfig;\n\n readonly opts?: Opts;\n\n protected _formModel: FormModelV2;\n\n constructor(config: FormPluginConfig, opts?: Opts) {\n this.name = config?.name || '';\n this.pluginId = `${this.name}__${nanoid()}`;\n this.config = config;\n\n this.opts = opts;\n }\n\n get formModel(): FormModelV2 {\n return this._formModel;\n }\n\n get ctx() {\n return {\n formModel: this.formModel,\n node: this.formModel.nodeContext.node,\n playgroundContext: this.formModel.nodeContext.playgroundContext,\n };\n }\n\n setupFormMeta(formMeta: FormMeta, nodeContext: NodeFormContext): FormMeta {\n const nextFormMeta: FormMeta = {\n ...formMeta,\n };\n\n this.config.onSetupFormMeta?.(\n {\n mergeEffect: (effect) => {\n nextFormMeta.effect = {\n ...(nextFormMeta.effect || {}),\n ...effect,\n };\n },\n mergeValidate: (validate) => {\n nextFormMeta.validate = {\n ...(nextFormMeta.validate || {}),\n ...validate,\n };\n },\n addFormatOnInit: (formatOnInit) => {\n if (!nextFormMeta.formatOnInit) {\n nextFormMeta.formatOnInit = formatOnInit;\n return;\n }\n const legacyFormatOnInit = nextFormMeta.formatOnInit;\n nextFormMeta.formatOnInit = (v, c) => formatOnInit?.(legacyFormatOnInit(v, c), c);\n },\n addFormatOnSubmit: (formatOnSubmit) => {\n if (!nextFormMeta.formatOnSubmit) {\n nextFormMeta.formatOnSubmit = formatOnSubmit;\n return;\n }\n const legacyFormatOnSubmit = nextFormMeta.formatOnSubmit;\n nextFormMeta.formatOnSubmit = (v, c) => formatOnSubmit?.(legacyFormatOnSubmit(v, c), c);\n },\n ...nodeContext,\n },\n this.opts\n );\n\n return nextFormMeta;\n }\n\n init(formModel: FormModelV2) {\n this._formModel = formModel;\n this.config?.onInit?.(this.ctx, this.opts);\n }\n\n dispose() {\n if (this.config?.onDispose) {\n this.config?.onDispose(this.ctx, this.opts);\n }\n }\n}\n\nexport type FormPluginCreator<Opts> = (opts: Opts) => FormPlugin<Opts>;\n\nexport function defineFormPluginCreator<Opts>(config: FormPluginConfig): FormPluginCreator<Opts> {\n return function (opts: Opts) {\n return new FormPlugin(config, opts);\n };\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport React from 'react';\n\nimport { Disposable, Event } from '@flowgram.ai/utils';\nimport { FlowNodeFormData, NodeRender, OnFormValuesChangePayload } from '@flowgram.ai/form-core';\nimport { FieldName, FieldValue, FormState } from '@flowgram.ai/form';\nimport { FlowNodeEntity } from '@flowgram.ai/document';\n\nimport { onFormValueChangeInPayload } from './types';\nimport { FormModelV2 } from './form-model-v2';\n\nexport interface NodeFormProps<TValues> {\n /**\n * The initialValues of the form.\n */\n initialValues: TValues;\n /**\n * Form values. Returns a deep copy of the data in the store.\n */\n values: TValues;\n /**\n * Form state\n */\n state: FormState;\n /**\n * Get value in certain path\n * @param name path\n */\n getValueIn<TValue = FieldValue>(name: FieldName): TValue;\n\n /**\n * Set value in certain path.\n * It will trigger the re-rendering of the Field Component if a Field is related to this path\n * @param name path\n */\n setValueIn<TValue>(name: FieldName, value: TValue): void;\n /**\n * set form values\n */\n updateFormValues(values: any): void;\n /**\n * Render form\n */\n render: () => React.ReactNode;\n /**\n * Form value change event\n */\n onFormValuesChange: Event<OnFormValuesChangePayload>;\n /**\n * Trigger form validate\n */\n validate: () => Promise<boolean>;\n /**\n * Form validate event\n */\n onValidate: Event<FormState>;\n /**\n * Form field value change event\n */\n onFormValueChangeIn<TValue = FieldValue, TFormValue = FieldValue>(\n name: FieldName,\n callback: (payload: onFormValueChangeInPayload<TValue, TFormValue>) => void\n ): Disposable;\n}\n\n/**\n * Only support FormModelV2\n * @param node\n */\nexport function getNodeForm<TValues = FieldValue>(\n node: FlowNodeEntity\n): NodeFormProps<TValues> | undefined {\n const formModel = node.getData<FlowNodeFormData>(FlowNodeFormData)?.getFormModel<FormModelV2>();\n const nativeFormModel = formModel?.nativeFormModel;\n\n if (!formModel || !nativeFormModel) return undefined;\n\n const result: NodeFormProps<TValues> = {\n initialValues: nativeFormModel.initialValues,\n get values() {\n return nativeFormModel.values;\n },\n\n state: nativeFormModel.state,\n getValueIn: (name: FieldName) => nativeFormModel.getValueIn(name),\n setValueIn: (name: FieldName, value: any) => nativeFormModel.setValueIn(name, value),\n updateFormValues: (values: any) => {\n formModel.updateFormValues(values);\n },\n render: () => <NodeRender node={node} />,\n onFormValuesChange: formModel.onFormValuesChange.bind(formModel),\n onFormValueChangeIn: formModel.onFormValueChangeIn.bind(formModel),\n onValidate: formModel.nativeFormModel.onValidate,\n validate: formModel.validate.bind(formModel),\n };\n\n Object.defineProperty(result, '_formModel', {\n enumerable: false,\n get() {\n return formModel;\n },\n });\n return result;\n}\n"],"mappings":"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","names":["DataEvent","effect","FlowNodeFormData","FlowNodeFormData","React","FlowNodeFormData"]}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import React__default from 'react';
|
|
3
|
-
import { FormModel, OnFormValuesChangePayload, FormModelValid, FormFeedback, FormManager, IFormItem, FormItem,
|
|
3
|
+
import { FormModel, OnFormValuesChangePayload, FormModelValid, FormFeedback, FormManager, IFormItem, FormItem, NodeFormContext, IFormMeta } from '@flowgram.ai/form-core';
|
|
4
4
|
import { FieldName as FieldName$1, FieldValue as FieldValue$1, Errors, Warnings } from '@flowgram.ai/form/src/types';
|
|
5
5
|
import { FormValidateReturn, FormControl, FormModel as FormModel$1, FieldValue, IFieldArray, IField, FieldName, Validate as Validate$1, IForm, FormRenderProps, ValidateTrigger, FormState } from '@flowgram.ai/form';
|
|
6
6
|
import * as _flowgram_ai_document from '@flowgram.ai/document';
|
|
@@ -35,7 +35,8 @@ declare class FormModelV2 extends FormModel implements Disposable {
|
|
|
35
35
|
get formManager(): FormManager;
|
|
36
36
|
protected _formControl?: FormControl<any>;
|
|
37
37
|
get formControl(): FormControl<any> | undefined;
|
|
38
|
-
|
|
38
|
+
protected _formMeta: FormMeta;
|
|
39
|
+
get formMeta(): FormMeta;
|
|
39
40
|
get values(): any;
|
|
40
41
|
protected _feedbacks: FormFeedback[];
|
|
41
42
|
get feedbacks(): FormFeedback[];
|
|
@@ -82,17 +83,22 @@ declare class FormModelV2 extends FormModel implements Disposable {
|
|
|
82
83
|
|
|
83
84
|
interface FormPluginConfig<Opts = any> {
|
|
84
85
|
/**
|
|
85
|
-
*
|
|
86
|
+
* form plugin name, for debug use
|
|
87
|
+
*/
|
|
88
|
+
name?: string;
|
|
89
|
+
/**
|
|
90
|
+
* setup formMeta
|
|
86
91
|
* @param ctx
|
|
92
|
+
* @returns
|
|
87
93
|
*/
|
|
88
|
-
|
|
94
|
+
onSetupFormMeta?: (ctx: FormPluginSetupMetaCtx, opts: Opts) => void;
|
|
89
95
|
/**
|
|
90
|
-
*
|
|
96
|
+
* FormModel 初始化时执行
|
|
97
|
+
* @param ctx
|
|
91
98
|
*/
|
|
92
|
-
|
|
99
|
+
onInit?: (ctx: FormPluginCtx, opts: Opts) => void;
|
|
93
100
|
/**
|
|
94
101
|
* FormModel 销毁时执行
|
|
95
|
-
* @param ctx
|
|
96
102
|
*/
|
|
97
103
|
onDispose?: (ctx: FormPluginCtx, opts: Opts) => void;
|
|
98
104
|
}
|
|
@@ -102,17 +108,24 @@ declare class FormPlugin<Opts = any> implements Disposable {
|
|
|
102
108
|
readonly config: FormPluginConfig;
|
|
103
109
|
readonly opts?: Opts;
|
|
104
110
|
protected _formModel: FormModelV2;
|
|
105
|
-
constructor(
|
|
111
|
+
constructor(config: FormPluginConfig, opts?: Opts);
|
|
106
112
|
get formModel(): FormModelV2;
|
|
107
113
|
get ctx(): {
|
|
108
114
|
formModel: FormModelV2;
|
|
109
115
|
node: _flowgram_ai_document.FlowNodeEntity;
|
|
110
116
|
playgroundContext: unknown;
|
|
111
117
|
};
|
|
118
|
+
setupFormMeta(formMeta: FormMeta, nodeContext: NodeFormContext): FormMeta;
|
|
112
119
|
init(formModel: FormModelV2): void;
|
|
113
120
|
dispose(): void;
|
|
114
121
|
}
|
|
115
|
-
|
|
122
|
+
type FormPluginCreator<Opts> = (opts: Opts) => FormPlugin<Opts>;
|
|
123
|
+
declare function defineFormPluginCreator<Opts>(config: FormPluginConfig): FormPluginCreator<Opts>;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
127
|
+
* SPDX-License-Identifier: MIT
|
|
128
|
+
*/
|
|
116
129
|
|
|
117
130
|
interface Node {
|
|
118
131
|
}
|
|
@@ -224,6 +237,12 @@ declare function isFormMetaV2(formMeta: IFormMeta | FormMeta): boolean;
|
|
|
224
237
|
type FormPluginCtx = {
|
|
225
238
|
formModel: FormModelV2;
|
|
226
239
|
} & NodeContext;
|
|
240
|
+
type FormPluginSetupMetaCtx = {
|
|
241
|
+
mergeEffect: (effect: Record<string, EffectOptions[]>) => void;
|
|
242
|
+
mergeValidate: (validate: Record<FieldName$1, Validate>) => void;
|
|
243
|
+
addFormatOnInit: (formatOnInit: FormMeta['formatOnInit']) => void;
|
|
244
|
+
addFormatOnSubmit: (formatOnSubmit: FormMeta['formatOnSubmit']) => void;
|
|
245
|
+
} & NodeContext;
|
|
227
246
|
interface onFormValueChangeInPayload<TValue = FieldValue$1, TFormValues = FieldValue$1> {
|
|
228
247
|
value: TValue;
|
|
229
248
|
prevValue: TValue;
|
|
@@ -231,12 +250,22 @@ interface onFormValueChangeInPayload<TValue = FieldValue$1, TFormValues = FieldV
|
|
|
231
250
|
prevFormValues: TFormValues;
|
|
232
251
|
}
|
|
233
252
|
|
|
253
|
+
/**
|
|
254
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
255
|
+
* SPDX-License-Identifier: MIT
|
|
256
|
+
*/
|
|
257
|
+
|
|
234
258
|
declare function isFormV2(node: FlowNodeEntity): boolean;
|
|
235
259
|
declare function createEffectOptions<T>(event: DataEvent, effect: T): {
|
|
236
260
|
effect: T;
|
|
237
261
|
event: DataEvent;
|
|
238
262
|
};
|
|
239
263
|
|
|
264
|
+
/**
|
|
265
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
266
|
+
* SPDX-License-Identifier: MIT
|
|
267
|
+
*/
|
|
268
|
+
|
|
240
269
|
/**
|
|
241
270
|
* Listen to Form's values and refresh the React component.
|
|
242
271
|
* By providing related node, you can use this hook outside the Form Component.
|
|
@@ -274,6 +303,11 @@ declare function useWatchFormErrors(node: FlowNodeEntity): Errors | undefined;
|
|
|
274
303
|
*/
|
|
275
304
|
declare function useWatchFormWarnings(node: FlowNodeEntity): Warnings | undefined;
|
|
276
305
|
|
|
306
|
+
/**
|
|
307
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
308
|
+
* SPDX-License-Identifier: MIT
|
|
309
|
+
*/
|
|
310
|
+
|
|
277
311
|
interface NodeFormProps<TValues> {
|
|
278
312
|
/**
|
|
279
313
|
* The initialValues of the form.
|
|
@@ -329,4 +363,4 @@ interface NodeFormProps<TValues> {
|
|
|
329
363
|
*/
|
|
330
364
|
declare function getNodeForm<TValues = FieldValue>(node: FlowNodeEntity): NodeFormProps<TValues> | undefined;
|
|
331
365
|
|
|
332
|
-
export { type ArrayAppendEffect, type ArrayDeleteEffect, DataEvent, type Effect, type EffectFuncProps, type EffectOptions, type EffectReturn, type Flow, type FormMeta, FormModelV2, FormPlugin, type FormPluginConfig, type FormPluginCtx, type Node, type NodeFormProps, type Validate, createEffectOptions, defineFormPluginCreator, getNodeForm, isFormMetaV2, isFormModelV2, isFormV2, type onFormValueChangeInPayload, useInitializedFormModel, useWatchFormErrors, useWatchFormState, useWatchFormValueIn, useWatchFormValues, useWatchFormWarnings };
|
|
366
|
+
export { type ArrayAppendEffect, type ArrayDeleteEffect, DataEvent, type Effect, type EffectFuncProps, type EffectOptions, type EffectReturn, type Flow, type FormMeta, FormModelV2, FormPlugin, type FormPluginConfig, type FormPluginCreator, type FormPluginCtx, type FormPluginSetupMetaCtx, type Node, type NodeFormProps, type Validate, createEffectOptions, defineFormPluginCreator, getNodeForm, isFormMetaV2, isFormModelV2, isFormV2, type onFormValueChangeInPayload, useInitializedFormModel, useWatchFormErrors, useWatchFormState, useWatchFormValueIn, useWatchFormValues, useWatchFormWarnings };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import React__default from 'react';
|
|
3
|
-
import { FormModel, OnFormValuesChangePayload, FormModelValid, FormFeedback, FormManager, IFormItem, FormItem,
|
|
3
|
+
import { FormModel, OnFormValuesChangePayload, FormModelValid, FormFeedback, FormManager, IFormItem, FormItem, NodeFormContext, IFormMeta } from '@flowgram.ai/form-core';
|
|
4
4
|
import { FieldName as FieldName$1, FieldValue as FieldValue$1, Errors, Warnings } from '@flowgram.ai/form/src/types';
|
|
5
5
|
import { FormValidateReturn, FormControl, FormModel as FormModel$1, FieldValue, IFieldArray, IField, FieldName, Validate as Validate$1, IForm, FormRenderProps, ValidateTrigger, FormState } from '@flowgram.ai/form';
|
|
6
6
|
import * as _flowgram_ai_document from '@flowgram.ai/document';
|
|
@@ -35,7 +35,8 @@ declare class FormModelV2 extends FormModel implements Disposable {
|
|
|
35
35
|
get formManager(): FormManager;
|
|
36
36
|
protected _formControl?: FormControl<any>;
|
|
37
37
|
get formControl(): FormControl<any> | undefined;
|
|
38
|
-
|
|
38
|
+
protected _formMeta: FormMeta;
|
|
39
|
+
get formMeta(): FormMeta;
|
|
39
40
|
get values(): any;
|
|
40
41
|
protected _feedbacks: FormFeedback[];
|
|
41
42
|
get feedbacks(): FormFeedback[];
|
|
@@ -82,17 +83,22 @@ declare class FormModelV2 extends FormModel implements Disposable {
|
|
|
82
83
|
|
|
83
84
|
interface FormPluginConfig<Opts = any> {
|
|
84
85
|
/**
|
|
85
|
-
*
|
|
86
|
+
* form plugin name, for debug use
|
|
87
|
+
*/
|
|
88
|
+
name?: string;
|
|
89
|
+
/**
|
|
90
|
+
* setup formMeta
|
|
86
91
|
* @param ctx
|
|
92
|
+
* @returns
|
|
87
93
|
*/
|
|
88
|
-
|
|
94
|
+
onSetupFormMeta?: (ctx: FormPluginSetupMetaCtx, opts: Opts) => void;
|
|
89
95
|
/**
|
|
90
|
-
*
|
|
96
|
+
* FormModel 初始化时执行
|
|
97
|
+
* @param ctx
|
|
91
98
|
*/
|
|
92
|
-
|
|
99
|
+
onInit?: (ctx: FormPluginCtx, opts: Opts) => void;
|
|
93
100
|
/**
|
|
94
101
|
* FormModel 销毁时执行
|
|
95
|
-
* @param ctx
|
|
96
102
|
*/
|
|
97
103
|
onDispose?: (ctx: FormPluginCtx, opts: Opts) => void;
|
|
98
104
|
}
|
|
@@ -102,17 +108,24 @@ declare class FormPlugin<Opts = any> implements Disposable {
|
|
|
102
108
|
readonly config: FormPluginConfig;
|
|
103
109
|
readonly opts?: Opts;
|
|
104
110
|
protected _formModel: FormModelV2;
|
|
105
|
-
constructor(
|
|
111
|
+
constructor(config: FormPluginConfig, opts?: Opts);
|
|
106
112
|
get formModel(): FormModelV2;
|
|
107
113
|
get ctx(): {
|
|
108
114
|
formModel: FormModelV2;
|
|
109
115
|
node: _flowgram_ai_document.FlowNodeEntity;
|
|
110
116
|
playgroundContext: unknown;
|
|
111
117
|
};
|
|
118
|
+
setupFormMeta(formMeta: FormMeta, nodeContext: NodeFormContext): FormMeta;
|
|
112
119
|
init(formModel: FormModelV2): void;
|
|
113
120
|
dispose(): void;
|
|
114
121
|
}
|
|
115
|
-
|
|
122
|
+
type FormPluginCreator<Opts> = (opts: Opts) => FormPlugin<Opts>;
|
|
123
|
+
declare function defineFormPluginCreator<Opts>(config: FormPluginConfig): FormPluginCreator<Opts>;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
127
|
+
* SPDX-License-Identifier: MIT
|
|
128
|
+
*/
|
|
116
129
|
|
|
117
130
|
interface Node {
|
|
118
131
|
}
|
|
@@ -224,6 +237,12 @@ declare function isFormMetaV2(formMeta: IFormMeta | FormMeta): boolean;
|
|
|
224
237
|
type FormPluginCtx = {
|
|
225
238
|
formModel: FormModelV2;
|
|
226
239
|
} & NodeContext;
|
|
240
|
+
type FormPluginSetupMetaCtx = {
|
|
241
|
+
mergeEffect: (effect: Record<string, EffectOptions[]>) => void;
|
|
242
|
+
mergeValidate: (validate: Record<FieldName$1, Validate>) => void;
|
|
243
|
+
addFormatOnInit: (formatOnInit: FormMeta['formatOnInit']) => void;
|
|
244
|
+
addFormatOnSubmit: (formatOnSubmit: FormMeta['formatOnSubmit']) => void;
|
|
245
|
+
} & NodeContext;
|
|
227
246
|
interface onFormValueChangeInPayload<TValue = FieldValue$1, TFormValues = FieldValue$1> {
|
|
228
247
|
value: TValue;
|
|
229
248
|
prevValue: TValue;
|
|
@@ -231,12 +250,22 @@ interface onFormValueChangeInPayload<TValue = FieldValue$1, TFormValues = FieldV
|
|
|
231
250
|
prevFormValues: TFormValues;
|
|
232
251
|
}
|
|
233
252
|
|
|
253
|
+
/**
|
|
254
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
255
|
+
* SPDX-License-Identifier: MIT
|
|
256
|
+
*/
|
|
257
|
+
|
|
234
258
|
declare function isFormV2(node: FlowNodeEntity): boolean;
|
|
235
259
|
declare function createEffectOptions<T>(event: DataEvent, effect: T): {
|
|
236
260
|
effect: T;
|
|
237
261
|
event: DataEvent;
|
|
238
262
|
};
|
|
239
263
|
|
|
264
|
+
/**
|
|
265
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
266
|
+
* SPDX-License-Identifier: MIT
|
|
267
|
+
*/
|
|
268
|
+
|
|
240
269
|
/**
|
|
241
270
|
* Listen to Form's values and refresh the React component.
|
|
242
271
|
* By providing related node, you can use this hook outside the Form Component.
|
|
@@ -274,6 +303,11 @@ declare function useWatchFormErrors(node: FlowNodeEntity): Errors | undefined;
|
|
|
274
303
|
*/
|
|
275
304
|
declare function useWatchFormWarnings(node: FlowNodeEntity): Warnings | undefined;
|
|
276
305
|
|
|
306
|
+
/**
|
|
307
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
308
|
+
* SPDX-License-Identifier: MIT
|
|
309
|
+
*/
|
|
310
|
+
|
|
277
311
|
interface NodeFormProps<TValues> {
|
|
278
312
|
/**
|
|
279
313
|
* The initialValues of the form.
|
|
@@ -329,4 +363,4 @@ interface NodeFormProps<TValues> {
|
|
|
329
363
|
*/
|
|
330
364
|
declare function getNodeForm<TValues = FieldValue>(node: FlowNodeEntity): NodeFormProps<TValues> | undefined;
|
|
331
365
|
|
|
332
|
-
export { type ArrayAppendEffect, type ArrayDeleteEffect, DataEvent, type Effect, type EffectFuncProps, type EffectOptions, type EffectReturn, type Flow, type FormMeta, FormModelV2, FormPlugin, type FormPluginConfig, type FormPluginCtx, type Node, type NodeFormProps, type Validate, createEffectOptions, defineFormPluginCreator, getNodeForm, isFormMetaV2, isFormModelV2, isFormV2, type onFormValueChangeInPayload, useInitializedFormModel, useWatchFormErrors, useWatchFormState, useWatchFormValueIn, useWatchFormValues, useWatchFormWarnings };
|
|
366
|
+
export { type ArrayAppendEffect, type ArrayDeleteEffect, DataEvent, type Effect, type EffectFuncProps, type EffectOptions, type EffectReturn, type Flow, type FormMeta, FormModelV2, FormPlugin, type FormPluginConfig, type FormPluginCreator, type FormPluginCtx, type FormPluginSetupMetaCtx, type Node, type NodeFormProps, type Validate, createEffectOptions, defineFormPluginCreator, getNodeForm, isFormMetaV2, isFormModelV2, isFormV2, type onFormValueChangeInPayload, useInitializedFormModel, useWatchFormErrors, useWatchFormState, useWatchFormValueIn, useWatchFormValues, useWatchFormWarnings };
|
package/dist/index.js
CHANGED
|
@@ -108,11 +108,6 @@ function convertGlobPath(path) {
|
|
|
108
108
|
}
|
|
109
109
|
return path;
|
|
110
110
|
}
|
|
111
|
-
function mergeEffectMap(origin, source) {
|
|
112
|
-
return (0, import_lodash.mergeWith)(origin, source, function(objValue, srcValue) {
|
|
113
|
-
return (objValue || []).concat(srcValue);
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
111
|
|
|
117
112
|
// src/form-render.tsx
|
|
118
113
|
var import_react = __toESM(require("react"));
|
|
@@ -185,7 +180,7 @@ var FormModelV2 = class extends import_form_core2.FormModel {
|
|
|
185
180
|
return this._formControl;
|
|
186
181
|
}
|
|
187
182
|
get formMeta() {
|
|
188
|
-
return this.node.getNodeRegistry().formMeta;
|
|
183
|
+
return this._formMeta || this.node.getNodeRegistry().formMeta;
|
|
189
184
|
}
|
|
190
185
|
get values() {
|
|
191
186
|
return this.nativeFormModel?.values;
|
|
@@ -229,9 +224,6 @@ var FormModelV2 = class extends import_form_core2.FormModel {
|
|
|
229
224
|
this.plugins = plugins;
|
|
230
225
|
plugins.forEach((plugin) => {
|
|
231
226
|
plugin.init(this);
|
|
232
|
-
if (plugin.config?.effect) {
|
|
233
|
-
mergeEffectMap(this.effectMap, plugin.config.effect);
|
|
234
|
-
}
|
|
235
227
|
});
|
|
236
228
|
}
|
|
237
229
|
init(formMeta, rawInitialValues) {
|
|
@@ -240,6 +232,12 @@ var FormModelV2 = class extends import_form_core2.FormModel {
|
|
|
240
232
|
this._valid = null;
|
|
241
233
|
formData.fireChange();
|
|
242
234
|
});
|
|
235
|
+
(formMeta.plugins || [])?.forEach((_plugin) => {
|
|
236
|
+
if (_plugin.setupFormMeta) {
|
|
237
|
+
formMeta = _plugin.setupFormMeta(formMeta, this.nodeContext);
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
this._formMeta = formMeta;
|
|
243
241
|
const { validateTrigger, validate, effect } = formMeta;
|
|
244
242
|
if (effect) {
|
|
245
243
|
this.effectMap = effect;
|
|
@@ -553,9 +551,9 @@ function useWatchFormWarnings(node) {
|
|
|
553
551
|
// src/form-plugin.ts
|
|
554
552
|
var import_nanoid = require("nanoid");
|
|
555
553
|
var FormPlugin = class {
|
|
556
|
-
constructor(
|
|
557
|
-
this.name = name;
|
|
558
|
-
this.pluginId = `${name}__${(0, import_nanoid.nanoid)()}`;
|
|
554
|
+
constructor(config, opts) {
|
|
555
|
+
this.name = config?.name || "";
|
|
556
|
+
this.pluginId = `${this.name}__${(0, import_nanoid.nanoid)()}`;
|
|
559
557
|
this.config = config;
|
|
560
558
|
this.opts = opts;
|
|
561
559
|
}
|
|
@@ -569,6 +567,46 @@ var FormPlugin = class {
|
|
|
569
567
|
playgroundContext: this.formModel.nodeContext.playgroundContext
|
|
570
568
|
};
|
|
571
569
|
}
|
|
570
|
+
setupFormMeta(formMeta, nodeContext) {
|
|
571
|
+
const nextFormMeta = {
|
|
572
|
+
...formMeta
|
|
573
|
+
};
|
|
574
|
+
this.config.onSetupFormMeta?.(
|
|
575
|
+
{
|
|
576
|
+
mergeEffect: (effect) => {
|
|
577
|
+
nextFormMeta.effect = {
|
|
578
|
+
...nextFormMeta.effect || {},
|
|
579
|
+
...effect
|
|
580
|
+
};
|
|
581
|
+
},
|
|
582
|
+
mergeValidate: (validate) => {
|
|
583
|
+
nextFormMeta.validate = {
|
|
584
|
+
...nextFormMeta.validate || {},
|
|
585
|
+
...validate
|
|
586
|
+
};
|
|
587
|
+
},
|
|
588
|
+
addFormatOnInit: (formatOnInit) => {
|
|
589
|
+
if (!nextFormMeta.formatOnInit) {
|
|
590
|
+
nextFormMeta.formatOnInit = formatOnInit;
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
const legacyFormatOnInit = nextFormMeta.formatOnInit;
|
|
594
|
+
nextFormMeta.formatOnInit = (v, c) => formatOnInit?.(legacyFormatOnInit(v, c), c);
|
|
595
|
+
},
|
|
596
|
+
addFormatOnSubmit: (formatOnSubmit) => {
|
|
597
|
+
if (!nextFormMeta.formatOnSubmit) {
|
|
598
|
+
nextFormMeta.formatOnSubmit = formatOnSubmit;
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
const legacyFormatOnSubmit = nextFormMeta.formatOnSubmit;
|
|
602
|
+
nextFormMeta.formatOnSubmit = (v, c) => formatOnSubmit?.(legacyFormatOnSubmit(v, c), c);
|
|
603
|
+
},
|
|
604
|
+
...nodeContext
|
|
605
|
+
},
|
|
606
|
+
this.opts
|
|
607
|
+
);
|
|
608
|
+
return nextFormMeta;
|
|
609
|
+
}
|
|
572
610
|
init(formModel) {
|
|
573
611
|
this._formModel = formModel;
|
|
574
612
|
this.config?.onInit?.(this.ctx, this.opts);
|
|
@@ -579,9 +617,9 @@ var FormPlugin = class {
|
|
|
579
617
|
}
|
|
580
618
|
}
|
|
581
619
|
};
|
|
582
|
-
function defineFormPluginCreator(
|
|
620
|
+
function defineFormPluginCreator(config) {
|
|
583
621
|
return function(opts) {
|
|
584
|
-
return new FormPlugin(
|
|
622
|
+
return new FormPlugin(config, opts);
|
|
585
623
|
};
|
|
586
624
|
}
|
|
587
625
|
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/form-model-v2.ts","../src/utils.ts","../src/form-render.tsx","../src/helpers.ts","../src/hooks.ts","../src/form-plugin.ts","../src/get-node-form.tsx"],"sourcesContent":["export * from './types';\nexport * from './form-model-v2';\nexport { isFormV2, createEffectOptions } from './helpers';\nexport * from './hooks';\nexport * from './form-plugin';\nexport { type NodeFormProps, getNodeForm } from './get-node-form';\n","import * as React from 'react';\n\nimport { FormModel, IFormMeta, NodeFormContext } from '@flowgram.ai/form-core';\nimport { FieldName, FieldValue } from '@flowgram.ai/form/src/types';\nimport {\n FormRenderProps,\n IForm,\n Validate as FormValidate,\n ValidateTrigger,\n} from '@flowgram.ai/form';\n\nimport { FormPlugin } from './form-plugin';\nimport { FormModelV2 } from './form-model-v2';\n\nexport interface Node {}\n\nexport interface Flow {}\n\n/**\n * NodeContext contains\n * - node: the Editor's node entity.\n * - playgroundContext: the Editor's playgroundContext injected when initiate the Editor.\n */\ntype NodeContext = NodeFormContext;\n\nexport type Validate<TFieldValue = any, TFormValues = any> = (props: {\n value: TFieldValue;\n formValues: TFormValues;\n context: NodeContext;\n name: FieldName;\n}) => ReturnType<FormValidate<TFieldValue, TFormValues>>;\n\nexport enum DataEvent {\n /* When value change */\n onValueChange = 'onValueChange',\n /**\n * When value Init,it triggers when\n * - defaultValue is configured in formMeta, it will trigger when form is initializing.\n * - defaultValue is configured in Field, it will trigger when this Field is initializing if no initial value is set to this field.\n */\n onValueInit = 'onValueInit',\n /**\n * When Value Init or change\n */\n onValueInitOrChange = 'onValueInitOrChange',\n /* It will trigger when ArrayField.append is called. It relies on ArrayField's rendering. If ArrayField is possibly not rendered in your case, please avoid using this event */\n onArrayAppend = 'onArrayAppend',\n /* It will trigger when ArrayField.delete is called. It relies on ArrayField's rendering. If ArrayField is possibly not rendered in your case, please avoid using this event */\n onArrayDelete = 'onArrayDelete',\n}\n\nexport type EffectReturn = () => void;\n\nexport interface EffectFuncProps<TFieldValue = any, TFormValues = any> {\n name: FieldName;\n value: TFieldValue;\n prevValue?: TFieldValue;\n formValues: TFormValues;\n form: IForm;\n context: NodeContext;\n}\n\nexport type Effect<TFieldValue = any, TFormValues = any> = (\n props: EffectFuncProps<TFieldValue, TFormValues>\n) => void | EffectReturn;\n\nexport type ArrayAppendEffect<TFieldValue = any, TFormValues = any> = (props: {\n index: number;\n value: TFieldValue;\n arrayValues: Array<TFieldValue>;\n formValues: TFormValues;\n form: IForm;\n context: NodeContext;\n}) => void | EffectReturn;\n\nexport type ArrayDeleteEffect<TFieldValue = any, TFormValues = any> = (props: {\n index: number;\n arrayValue: Array<TFieldValue>;\n formValues: TFormValues;\n form: IForm;\n context: NodeContext;\n}) => void | EffectReturn;\n\nexport type EffectOptions =\n | { effect: Effect; event: DataEvent }\n | { effect: ArrayAppendEffect; event: DataEvent }\n | { effect: ArrayDeleteEffect; event: DataEvent };\n\nexport interface FormMeta<TValues = any> {\n /**\n * The render method of the node form content. <Form /> is already integrated, so you don't need to wrap your components with <Form />\n * @param props\n */\n render: (props: FormRenderProps<any>) => React.ReactElement;\n /**\n * When to trigger the validation.\n */\n validateTrigger?: ValidateTrigger;\n /**\n * Form data's validation rules. It's a key value map, where the key is a pattern of data's path (or field name), the value is a validate function.\n */\n validate?: Record<FieldName, Validate>;\n /**\n * Form data's effects. It's a key value map, where the key is a pattern of data's path (or field name), the value is an array of effect configuration.\n */\n effect?: Record<FieldName, EffectOptions[]>;\n /**\n * Form data's complete default value. it will not be sent to formatOnInit, but used directly as form's value when needed.\n */\n defaultValues?: TValues | ((context: NodeContext) => TValues);\n /**\n * This function is to format the value when initiate the form, the returned value will be used as the initial value of the form.\n * @param value value input to node as initialValue.\n * @param context\n */\n formatOnInit?: (value: any, context: NodeContext) => any;\n /**\n * This function is to format the value when FormModel.toJSON is called, the returned value will be used as the final value to be saved .\n * @param value value sent by form before format.\n * @param context\n */\n formatOnSubmit?: (value: any, context: NodeContext) => any;\n /**\n * Form's plugins\n */\n plugins?: FormPlugin[];\n}\n\nexport function isFormModelV2(fm: FormModel | FormModelV2): fm is FormModelV2 {\n return 'onFormValuesChange' in fm;\n}\n\nexport function isFormMetaV2(formMeta: IFormMeta | FormMeta) {\n return 'render' in formMeta;\n}\n\nexport type FormPluginCtx = {\n formModel: FormModelV2;\n} & NodeContext;\n\nexport interface onFormValueChangeInPayload<TValue = FieldValue, TFormValues = FieldValue> {\n value: TValue;\n prevValue: TValue;\n formValues: TFormValues;\n prevFormValues: TFormValues;\n}\n","import { get, groupBy, isEmpty, mapKeys } from 'lodash';\nimport { Disposable, DisposableCollection, Emitter } from '@flowgram.ai/utils';\nimport {\n FlowNodeFormData,\n FormFeedback,\n FormItem,\n FormManager,\n FormModel,\n FormModelValid,\n IFormItem,\n OnFormValuesChangePayload,\n} from '@flowgram.ai/form-core';\nimport {\n createForm,\n FieldArrayModel,\n FieldName,\n FieldValue,\n type FormControl,\n FormModel as NativeFormModel,\n FormValidateReturn,\n Glob,\n IField,\n IFieldArray,\n toForm,\n} from '@flowgram.ai/form';\nimport { FlowNodeEntity } from '@flowgram.ai/document';\nimport { PlaygroundContext, PluginContext } from '@flowgram.ai/core';\n\nimport {\n convertGlobPath,\n findMatchedInMap,\n formFeedbacksToNodeCoreFormFeedbacks,\n mergeEffectMap,\n} from './utils';\nimport {\n DataEvent,\n Effect,\n EffectOptions,\n EffectReturn,\n FormMeta,\n onFormValueChangeInPayload,\n} from './types';\nimport { renderForm } from './form-render';\nimport { FormPlugin } from './form-plugin';\n\nconst DEFAULT = {\n // Different formModel should have different reference\n EFFECT_MAP: () => ({}),\n EFFECT_RETURN_MAP: () =>\n new Map([\n [DataEvent.onValueInitOrChange, {}],\n [DataEvent.onValueChange, {}],\n [DataEvent.onValueInit, {}],\n [DataEvent.onArrayAppend, {}],\n [DataEvent.onArrayDelete, {}],\n ]),\n FORM_FEEDBACKS: () => [],\n VALID: null,\n};\n\nexport class FormModelV2 extends FormModel implements Disposable {\n protected effectMap: Record<string, EffectOptions[]> = DEFAULT.EFFECT_MAP();\n\n protected effectReturnMap: Map<DataEvent, Record<string, EffectReturn>> =\n DEFAULT.EFFECT_RETURN_MAP();\n\n protected plugins: FormPlugin[] = [];\n\n protected node: FlowNodeEntity;\n\n protected formFeedbacks: FormValidateReturn | undefined = DEFAULT.FORM_FEEDBACKS();\n\n protected onInitializedEmitter = new Emitter<FormModel>();\n\n protected onValidateEmitter = new Emitter<FormModel>();\n\n readonly onValidate = this.onValidateEmitter.event;\n\n readonly onInitialized = this.onInitializedEmitter.event;\n\n protected onDisposeEmitter = new Emitter<void>();\n\n readonly onDispose = this.onDisposeEmitter.event;\n\n protected toDispose = new DisposableCollection();\n\n protected onFormValuesChangeEmitter = new Emitter<OnFormValuesChangePayload>();\n\n readonly onFormValuesChange = this.onFormValuesChangeEmitter.event;\n\n protected onValidChangeEmitter = new Emitter<FormModelValid>();\n\n readonly onValidChange = this.onValidChangeEmitter.event;\n\n protected onFeedbacksChangeEmitter = new Emitter<FormFeedback[]>();\n\n readonly onFeedbacksChange = this.onFeedbacksChangeEmitter.event;\n\n constructor(node: FlowNodeEntity) {\n super();\n this.node = node;\n this.toDispose.pushAll([\n this.onInitializedEmitter,\n this.onValidateEmitter,\n this.onValidChangeEmitter,\n this.onFeedbacksChangeEmitter,\n this.onFormValuesChangeEmitter,\n ]);\n }\n\n protected _valid: FormModelValid = DEFAULT.VALID;\n\n get valid(): FormModelValid {\n return this._valid;\n }\n\n private set valid(valid: FormModelValid) {\n this._valid = valid;\n this.onValidChangeEmitter.fire(valid);\n }\n\n get flowNodeEntity() {\n return this.node;\n }\n\n get formManager() {\n return this.node.getService(FormManager);\n }\n\n protected _formControl?: FormControl<any>;\n\n get formControl() {\n return this._formControl;\n }\n\n get formMeta() {\n return this.node.getNodeRegistry().formMeta;\n }\n\n get values() {\n return this.nativeFormModel?.values;\n }\n\n protected _feedbacks: FormFeedback[] = [];\n\n get feedbacks(): FormFeedback[] {\n return this._feedbacks;\n }\n\n updateFormValues(value: any) {\n if (this.nativeFormModel) {\n const finalValue = this.formMeta.formatOnInit\n ? this.formMeta.formatOnInit(value, this.nodeContext)\n : value;\n this.nativeFormModel.values = finalValue;\n }\n }\n\n private set feedbacks(feedbacks: FormFeedback[]) {\n this._feedbacks = feedbacks;\n this.onFeedbacksChangeEmitter.fire(feedbacks);\n }\n\n get formItemPathMap(): Map<string, IFormItem> {\n return new Map<string, IFormItem>();\n }\n\n protected _initialized: boolean = false;\n\n get initialized(): boolean {\n return this._initialized;\n }\n\n get nodeContext() {\n return {\n node: this.node,\n playgroundContext: this.node.getService(PlaygroundContext),\n clientContext: this.node.getService(PluginContext),\n };\n }\n\n get nativeFormModel(): NativeFormModel | undefined {\n return this._formControl?._formModel;\n }\n\n render() {\n return renderForm(this);\n }\n\n initPlugins(plugins: FormPlugin[]) {\n if (!plugins.length) {\n return;\n }\n\n this.plugins = plugins;\n plugins.forEach((plugin) => {\n plugin.init(this);\n if (plugin.config?.effect) {\n mergeEffectMap(this.effectMap, plugin.config.effect);\n }\n });\n }\n\n init(formMeta: FormMeta, rawInitialValues?: any) {\n /* 透传 onFormValuesChange 事件给 FlowNodeFormData */\n const formData = this.node.getData<FlowNodeFormData>(FlowNodeFormData);\n this.onFormValuesChange(() => {\n this._valid = null;\n formData.fireChange();\n });\n\n const { validateTrigger, validate, effect } = formMeta;\n if (effect) {\n this.effectMap = effect;\n }\n\n // 计算初始值: defaultValues 是默认表单值,不需要被format, 而rawInitialValues 是用户创建form 时传入的初始值,可能不同于表单数据格式,需要被format\n const defaultValues =\n typeof formMeta.defaultValues === 'function'\n ? formMeta.defaultValues(this.nodeContext)\n : formMeta.defaultValues;\n\n const initialValues = formMeta.formatOnInit\n ? formMeta.formatOnInit(rawInitialValues, this.nodeContext)\n : rawInitialValues;\n\n // 初始化底层表单\n const { control } = createForm({\n initialValues: initialValues || defaultValues,\n validateTrigger,\n context: this.nodeContext,\n validate: validate,\n disableAutoInit: true,\n });\n\n this._formControl = control;\n const nativeFormModel = control._formModel;\n this.toDispose.push(nativeFormModel);\n\n // forward onFormValuesChange event\n nativeFormModel.onFormValuesChange((props) => {\n this.onFormValuesChangeEmitter.fire(props);\n });\n\n if (formMeta.plugins) {\n this.initPlugins(formMeta.plugins);\n }\n\n // Form 数据变更时触发对应的effect\n nativeFormModel.onFormValuesChange(({ values, prevValues, name }) => {\n // 找到所有路径匹配的副作用,包括父亲路径\n const effectKeys = Object.keys(this.effectMap).filter((pattern) =>\n Glob.isMatchOrParent(pattern, name)\n );\n\n effectKeys.forEach((effectKey) => {\n const effectOptionsArr = this.effectMap[effectKey];\n // 执行该事件配置下所有 onValueChange 事件的 effect\n effectOptionsArr.forEach(({ effect, event }: EffectOptions) => {\n if (event === DataEvent.onValueChange || event === DataEvent.onValueInitOrChange) {\n // 对于冒泡的事件,需要获取 parent 的 name\n const currentName = Glob.getParentPathByPattern(effectKey, name);\n\n // 执行上一次effect 的 return\n const prevEffectReturn = this.effectReturnMap.get(event)?.[currentName];\n if (prevEffectReturn) {\n prevEffectReturn();\n }\n\n // 执行effect\n const effectReturn = (effect as Effect)({\n name: currentName,\n value: get(values, currentName),\n prevValue: get(prevValues, currentName),\n formValues: values,\n form: toForm(this.nativeFormModel!),\n context: this.nodeContext,\n });\n\n // 更新 effect return\n if (\n effectReturn &&\n typeof effectReturn === 'function' &&\n this.effectReturnMap.has(event)\n ) {\n const eventMap = this.effectReturnMap.get(event) as Record<string, EffectReturn>;\n eventMap[currentName] = effectReturn;\n }\n }\n });\n });\n });\n\n // Form 数据初始化时触发对应的effect\n nativeFormModel.onFormValuesInit(({ values, name, prevValues }) => {\n Object.keys(this.effectMap).forEach((pattern) => {\n // 找到匹配 pattern 的数据路径\n const paths = Glob.findMatchPaths(values, pattern);\n\n // 获取配置在该 pattern上的所有effect配置\n const effectOptionsArr = this.effectMap[pattern];\n\n effectOptionsArr.forEach(({ event, effect }: EffectOptions) => {\n if (event === DataEvent.onValueInit || event === DataEvent.onValueInitOrChange) {\n paths.forEach((path) => {\n // 对触发 init 事件的 name 或他的字 path 触发effect\n if (Glob.isMatchOrParent(name, path) || name === path) {\n // 执行上一次effect 的 return\n const prevEffectReturn = this.effectReturnMap.get(event)?.[path];\n if (prevEffectReturn) {\n prevEffectReturn();\n }\n\n const effectReturn = (effect as Effect)({\n name: path,\n value: get(values, path),\n formValues: values,\n prevValue: get(prevValues, path),\n form: toForm(this.nativeFormModel!),\n context: this.nodeContext,\n });\n\n // 更新 effect return\n if (\n effectReturn &&\n typeof effectReturn === 'function' &&\n this.effectReturnMap.has(event)\n ) {\n const eventMap = this.effectReturnMap.get(event) as Record<string, EffectReturn>;\n eventMap[path] = effectReturn;\n }\n }\n });\n }\n });\n });\n });\n\n // 为 Field 添加 effect, 主要针对array\n nativeFormModel.onFieldModelCreate((field) => {\n // register effect\n const effectOptionsArr = findMatchedInMap<EffectOptions[]>(field, this.effectMap);\n if (effectOptionsArr?.length) {\n // 按事件聚合\n const eventMap = groupBy(effectOptionsArr, 'event');\n\n mapKeys(eventMap, (optionsArr, event) => {\n const combinedEffect = (props: any) => {\n // 该事件下执行所有effect\n optionsArr.forEach(({ effect }) =>\n effect({\n ...props,\n formValues: nativeFormModel.values,\n form: toForm(this.nativeFormModel!),\n context: this.nodeContext,\n })\n );\n };\n\n switch (event) {\n case DataEvent.onArrayAppend:\n if (field instanceof FieldArrayModel) {\n (field as FieldArrayModel).onAppend(combinedEffect);\n }\n break;\n case DataEvent.onArrayDelete:\n if (field instanceof FieldArrayModel) {\n (field as FieldArrayModel).onDelete(combinedEffect);\n }\n break;\n }\n });\n }\n });\n\n // 手动初始化form\n this._formControl.init();\n\n this._initialized = true;\n\n this.onInitializedEmitter.fire(this);\n\n this.onDispose(() => {\n this._initialized = false;\n this.effectMap = {};\n nativeFormModel.dispose();\n });\n }\n\n toJSON() {\n if (this.formMeta.formatOnSubmit) {\n return this.formMeta.formatOnSubmit(this.nativeFormModel?.values, this.nodeContext);\n }\n return this.nativeFormModel?.values;\n }\n\n clearValid() {\n if (this.valid !== null) {\n this.valid = null;\n }\n }\n\n async validate() {\n this.formFeedbacks = await this.nativeFormModel?.validate();\n this.valid = isEmpty(this.formFeedbacks?.filter((f) => f.level === 'error'));\n this.onValidateEmitter.fire(this);\n return this.valid;\n }\n\n getValues<T = any>(): T | undefined {\n return this._formControl?._formModel.values;\n }\n\n getField<\n TValue = FieldValue,\n TField extends IFieldArray<TValue> | IField<TValue> = IField<TValue>\n >(name: FieldName): TField | undefined {\n let finalName = name.includes('/') ? convertGlobPath(name) : name;\n\n return this.formControl?.getField<TValue, TField>(finalName) as TField;\n }\n\n getValueIn<TValue>(name: FieldName): TValue | undefined {\n let finalName = name.includes('/') ? convertGlobPath(name) : name;\n\n return this.nativeFormModel?.getValueIn(finalName);\n }\n\n setValueIn(name: FieldName, value: any) {\n let finalName = name.includes('/') ? convertGlobPath(name) : name;\n\n this.nativeFormModel?.setValueIn(finalName, value);\n }\n\n /**\n * 监听表单某个路径下的值变化\n * @param name 路径\n * @param callback 回调函数\n */\n onFormValueChangeIn<TValue = FieldValue, TFormValue = FieldValue>(\n name: FieldName,\n callback: (payload: onFormValueChangeInPayload<TValue, TFormValue>) => void\n ): Disposable {\n if (!this._initialized) {\n throw new Error(\n `[NodeEngine] FormModel Error: onFormValueChangeIn can not be called before initialized`\n );\n }\n\n return this.formControl!._formModel.onFormValuesChange(\n ({ name: changedName, values, prevValues }) => {\n if (changedName === name) {\n callback({\n value: get(values, name),\n prevValue: get(prevValues, name),\n formValues: values,\n prevFormValues: prevValues,\n });\n }\n }\n );\n }\n\n /**\n * @deprecated 该方法用于兼容 V1 版本 FormModel接口,如果确定是FormModelV2 请使用 FormModel.getValueIn\n * @param path glob path\n */\n getFormItemValueByPath(globPath: string) {\n if (!globPath) {\n return;\n }\n if (globPath === '/') {\n return this._formControl?._formModel.values;\n }\n const name = convertGlobPath(globPath);\n return this.getValueIn(name!);\n }\n\n async validateWithFeedbacks(): Promise<FormFeedback[]> {\n await this.validate();\n return formFeedbacksToNodeCoreFormFeedbacks(this.formFeedbacks!);\n }\n\n /**\n * @deprecated 该方法用于兼容 V1 版本 FormModel接口,如果确定是FormModelV2, 请使用FormModel.getValueIn 和 FormModel.setValueIn\n * @param path glob path\n */\n getFormItemByPath(path: string): FormItem | undefined {\n if (!this.nativeFormModel) {\n return;\n }\n\n const that = this;\n\n if (path === '/') {\n return {\n get value() {\n return that.nativeFormModel!.values;\n },\n set value(v) {\n that.nativeFormModel!.values = v;\n },\n } as FormItem;\n }\n\n const name = convertGlobPath(path);\n const formItemValue = that.getValueIn(name!);\n return {\n get value() {\n return formItemValue;\n },\n set value(v) {\n that.setValueIn(name, v);\n },\n } as FormItem;\n }\n\n dispose(): void {\n this.onDisposeEmitter.fire();\n\n // 执行所有effect return\n this.effectReturnMap.forEach((eventMap) => {\n Object.values(eventMap).forEach((effectReturn) => {\n effectReturn();\n });\n });\n\n this.effectMap = DEFAULT.EFFECT_MAP();\n this.effectReturnMap = DEFAULT.EFFECT_RETURN_MAP();\n\n this.plugins.forEach((p) => {\n p.dispose();\n });\n\n this.plugins = [];\n\n this.formFeedbacks = DEFAULT.FORM_FEEDBACKS();\n this._valid = DEFAULT.VALID;\n\n this._formControl = undefined;\n this._initialized = false;\n this.toDispose.dispose();\n }\n}\n","import { find, mergeWith } from 'lodash';\nimport { FormFeedback, FormPathService } from '@flowgram.ai/form-core';\nimport { FormValidateReturn } from '@flowgram.ai/form/src/types';\nimport { type FieldModel, FieldName } from '@flowgram.ai/form';\n\nimport { EffectOptions } from './types';\n\nexport function findMatchedInMap<T = any>(\n field: FieldModel<any>,\n validateMap: Record<FieldName, T> | undefined\n): T | undefined {\n if (!validateMap) {\n return;\n }\n if (validateMap[field.name]) {\n return validateMap[field.name];\n }\n\n const found = find(Object.keys(validateMap), (key) => {\n if (key.startsWith('regex:')) {\n const regex = RegExp(key.split(':')[1]);\n return regex.test(field.name);\n }\n return false;\n });\n\n if (found) {\n return validateMap[found];\n }\n}\n\nexport function formFeedbacksToNodeCoreFormFeedbacks(\n formFeedbacks: FormValidateReturn\n): FormFeedback[] {\n return formFeedbacks.map(\n (f) =>\n ({\n feedbackStatus: f.level,\n feedbackText: f.message,\n path: f.name,\n } as FormFeedback)\n );\n}\n\nexport function convertGlobPath(path: string) {\n if (path.startsWith('/')) {\n const parts = FormPathService.normalize(path).slice(1).split('/');\n return parts.join('.');\n }\n return path;\n}\n\nexport function mergeEffectMap(\n origin: Record<string, EffectOptions[]>,\n source: Record<string, EffectOptions[]>\n) {\n return mergeWith(origin, source, function (objValue: EffectOptions[], srcValue: EffectOptions[]) {\n return (objValue || []).concat(srcValue);\n });\n}\n","import React from 'react';\n\nimport { Form } from '@flowgram.ai/form';\n\nimport { FormModelV2 } from './form-model-v2';\n\ninterface FormRenderProps {\n formModel: FormModelV2;\n}\n\nconst FormRender = ({ formModel }: FormRenderProps) =>\n formModel?.formControl ? (\n <>\n <Form control={formModel?.formControl} keepModelOnUnMount>\n {formModel.formMeta.render}\n </Form>\n </>\n ) : null;\n\nexport function renderForm(formModel: FormModelV2) {\n return <FormRender formModel={formModel} />;\n}\n","import { FlowNodeFormData } from '@flowgram.ai/form-core';\nimport { FlowNodeEntity } from '@flowgram.ai/document';\n\nimport { DataEvent } from './types';\nimport { FormModelV2 } from './form-model-v2';\n\nexport function getFormModel(node: FlowNodeEntity) {\n // @ts-ignore\n return node.getData<FlowNodeFormData>(FlowNodeFormData)?.formModel as FormModelV2;\n}\n\nexport function isFormV2(node: FlowNodeEntity) {\n return !!node.getNodeRegistry().formMeta?.render;\n}\n\nexport function createEffectOptions<T>(\n event: DataEvent,\n effect: T\n): { effect: T; event: DataEvent } {\n return {\n event,\n effect,\n };\n}\n","import { useEffect } from 'react';\n\nimport { useRefresh } from '@flowgram.ai/utils';\nimport { FlowNodeFormData } from '@flowgram.ai/form-core';\nimport { Errors, Warnings } from '@flowgram.ai/form/src/types';\nimport { FormState, useFormErrors, useFormState, useFormWarnings } from '@flowgram.ai/form';\nimport { FlowNodeEntity } from '@flowgram.ai/document';\n\nimport { FormModelV2 } from './form-model-v2';\n\n/**\n * Listen to Form's values and refresh the React component.\n * By providing related node, you can use this hook outside the Form Component.\n * @param node\n */\nexport function useWatchFormValues<T = any>(node: FlowNodeEntity): T | undefined {\n const formModel = node.getData(FlowNodeFormData).getFormModel<FormModelV2>();\n const refresh = useRefresh();\n\n useEffect(() => {\n const disposable = formModel.nativeFormModel?.onFormValuesChange(() => {\n refresh();\n });\n return () => disposable?.dispose();\n }, [formModel.nativeFormModel]);\n\n return formModel.getValues<T>();\n}\n\n/**\n * Listen to Form's value in a certain path and refresh the React component.\n * By providing related node, you can use this hook outside the Form Component.\n * @param node\n */\nexport function useWatchFormValueIn<T = any>(node: FlowNodeEntity, name: string): T | undefined {\n const formModel = node.getData(FlowNodeFormData).getFormModel<FormModelV2>();\n const refresh = useRefresh();\n\n useEffect(() => {\n const disposable = formModel.nativeFormModel?.onFormValuesChange(({ name: changedName }) => {\n if (name === changedName) {\n refresh();\n }\n });\n\n return () => disposable?.dispose();\n }, []);\n\n return formModel.getValueIn<T>(name);\n}\n\n/**\n * Listen to FormModel's initialization and refresh React component.\n * By providing related node, you can use this hook outside the Form Component.\n * @param node\n */\nexport function useInitializedFormModel(node: FlowNodeEntity) {\n const formModel = node.getData(FlowNodeFormData).getFormModel<FormModelV2>();\n const refresh = useRefresh();\n\n useEffect(() => {\n const disposable = formModel.onInitialized(() => {\n refresh();\n });\n return () => disposable.dispose();\n }, [formModel]);\n\n return formModel;\n}\n\n/**\n * Get Form's state, Form State is a proxy, it will refresh the React component when the value you accessed changed\n * By providing related node, you can use this hook outside the Form Component.\n * @param node\n */\nexport function useWatchFormState(node: FlowNodeEntity): FormState | undefined {\n const formModel = useInitializedFormModel(node);\n return useFormState(formModel.formControl);\n}\n\n/**\n * Get Form's errors, Form errors is a proxy, it will refresh the React component when the value you accessed changed\n * By providing related node, you can use this hook outside the Form Component.\n * @param node\n */\nexport function useWatchFormErrors(node: FlowNodeEntity): Errors | undefined {\n const formModel = useInitializedFormModel(node);\n return useFormErrors(formModel.formControl);\n}\n\n/**\n * Get Form's warnings, Form warnings is a proxy, it will refresh the React component when the value you accessed changed\n * By providing related node, you can use this hook outside the Form Component.\n * @param node\n */\nexport function useWatchFormWarnings(node: FlowNodeEntity): Warnings | undefined {\n const formModel = useInitializedFormModel(node);\n return useFormWarnings(formModel.formControl);\n}\n","import { nanoid } from 'nanoid';\nimport { Disposable } from '@flowgram.ai/utils';\n\nimport { EffectOptions, FormPluginCtx } from './types';\nimport { FormModelV2 } from './form-model-v2';\n\nexport interface FormPluginConfig<Opts = any> {\n /**\n * FormModel 初始化时执行\n * @param ctx\n */\n onInit?: (ctx: FormPluginCtx, opts: Opts) => void;\n\n /**\n * 同 FormMeta 中的effects 会与 FormMeta 中的effects 合并\n */\n effect?: Record<string, EffectOptions[]>;\n /**\n * FormModel 销毁时执行\n * @param ctx\n */\n onDispose?: (ctx: FormPluginCtx, opts: Opts) => void;\n}\n\nexport class FormPlugin<Opts = any> implements Disposable {\n readonly name: string;\n\n readonly pluginId: string;\n\n readonly config: FormPluginConfig;\n\n readonly opts?: Opts;\n\n protected _formModel: FormModelV2;\n\n constructor(name: string, config: FormPluginConfig, opts?: Opts) {\n this.name = name;\n this.pluginId = `${name}__${nanoid()}`;\n this.config = config;\n this.opts = opts;\n }\n\n get formModel(): FormModelV2 {\n return this._formModel;\n }\n\n get ctx() {\n return {\n formModel: this.formModel,\n node: this.formModel.nodeContext.node,\n playgroundContext: this.formModel.nodeContext.playgroundContext,\n };\n }\n\n init(formModel: FormModelV2) {\n this._formModel = formModel;\n this.config?.onInit?.(this.ctx, this.opts);\n }\n\n dispose() {\n if (this.config?.onDispose) {\n this.config?.onDispose(this.ctx, this.opts);\n }\n }\n}\n\nexport function defineFormPluginCreator<Opts>(name: string, config: FormPluginConfig) {\n return function (opts: Opts) {\n return new FormPlugin(name, config, opts);\n };\n}\n","import React from 'react';\n\nimport { Disposable, Event } from '@flowgram.ai/utils';\nimport { FlowNodeFormData, NodeRender, OnFormValuesChangePayload } from '@flowgram.ai/form-core';\nimport { FieldName, FieldValue, FormState } from '@flowgram.ai/form';\nimport { FlowNodeEntity } from '@flowgram.ai/document';\n\nimport { onFormValueChangeInPayload } from './types';\nimport { FormModelV2 } from './form-model-v2';\n\nexport interface NodeFormProps<TValues> {\n /**\n * The initialValues of the form.\n */\n initialValues: TValues;\n /**\n * Form values. Returns a deep copy of the data in the store.\n */\n values: TValues;\n /**\n * Form state\n */\n state: FormState;\n /**\n * Get value in certain path\n * @param name path\n */\n getValueIn<TValue = FieldValue>(name: FieldName): TValue;\n\n /**\n * Set value in certain path.\n * It will trigger the re-rendering of the Field Component if a Field is related to this path\n * @param name path\n */\n setValueIn<TValue>(name: FieldName, value: TValue): void;\n /**\n * set form values\n */\n updateFormValues(values: any): void;\n /**\n * Render form\n */\n render: () => React.ReactNode;\n /**\n * Form value change event\n */\n onFormValuesChange: Event<OnFormValuesChangePayload>;\n /**\n * Trigger form validate\n */\n validate: () => Promise<boolean>;\n /**\n * Form validate event\n */\n onValidate: Event<FormState>;\n /**\n * Form field value change event\n */\n onFormValueChangeIn<TValue = FieldValue, TFormValue = FieldValue>(\n name: FieldName,\n callback: (payload: onFormValueChangeInPayload<TValue, TFormValue>) => void\n ): Disposable;\n}\n\n/**\n * Only support FormModelV2\n * @param node\n */\nexport function getNodeForm<TValues = FieldValue>(\n node: FlowNodeEntity\n): NodeFormProps<TValues> | undefined {\n const formModel = node.getData<FlowNodeFormData>(FlowNodeFormData)?.getFormModel<FormModelV2>();\n const nativeFormModel = formModel?.nativeFormModel;\n\n if (!formModel || !nativeFormModel) return undefined;\n\n const result: NodeFormProps<TValues> = {\n initialValues: nativeFormModel.initialValues,\n get values() {\n return nativeFormModel.values;\n },\n\n state: nativeFormModel.state,\n getValueIn: (name: FieldName) => nativeFormModel.getValueIn(name),\n setValueIn: (name: FieldName, value: any) => nativeFormModel.setValueIn(name, value),\n updateFormValues: (values: any) => {\n formModel.updateFormValues(values);\n },\n render: () => <NodeRender node={node} />,\n onFormValuesChange: formModel.onFormValuesChange.bind(formModel),\n onFormValueChangeIn: formModel.onFormValueChangeIn.bind(formModel),\n onValidate: formModel.nativeFormModel.onValidate,\n validate: formModel.validate.bind(formModel),\n };\n\n Object.defineProperty(result, '_formModel', {\n enumerable: false,\n get() {\n return formModel;\n },\n });\n return result;\n}\n"],"mappings":"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","names":["DataEvent","import_lodash","import_form_core","import_form","React","effect","import_form_core","import_react","import_utils","import_form_core","import_form","import_react","import_form_core","React"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/form-model-v2.ts","../src/utils.ts","../src/form-render.tsx","../src/helpers.ts","../src/hooks.ts","../src/form-plugin.ts","../src/get-node-form.tsx"],"sourcesContent":["/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nexport * from './types';\nexport * from './form-model-v2';\nexport { isFormV2, createEffectOptions } from './helpers';\nexport * from './hooks';\nexport * from './form-plugin';\nexport { type NodeFormProps, getNodeForm } from './get-node-form';\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport * as React from 'react';\n\nimport { FormModel, IFormMeta, NodeFormContext } from '@flowgram.ai/form-core';\nimport { FieldName, FieldValue } from '@flowgram.ai/form/src/types';\nimport {\n FormRenderProps,\n IForm,\n Validate as FormValidate,\n ValidateTrigger,\n} from '@flowgram.ai/form';\n\nimport { FormPlugin } from './form-plugin';\nimport { FormModelV2 } from './form-model-v2';\n\nexport interface Node {}\n\nexport interface Flow {}\n\n/**\n * NodeContext contains\n * - node: the Editor's node entity.\n * - playgroundContext: the Editor's playgroundContext injected when initiate the Editor.\n */\ntype NodeContext = NodeFormContext;\n\nexport type Validate<TFieldValue = any, TFormValues = any> = (props: {\n value: TFieldValue;\n formValues: TFormValues;\n context: NodeContext;\n name: FieldName;\n}) => ReturnType<FormValidate<TFieldValue, TFormValues>>;\n\nexport enum DataEvent {\n /* When value change */\n onValueChange = 'onValueChange',\n /**\n * When value Init,it triggers when\n * - defaultValue is configured in formMeta, it will trigger when form is initializing.\n * - defaultValue is configured in Field, it will trigger when this Field is initializing if no initial value is set to this field.\n */\n onValueInit = 'onValueInit',\n /**\n * When Value Init or change\n */\n onValueInitOrChange = 'onValueInitOrChange',\n /* It will trigger when ArrayField.append is called. It relies on ArrayField's rendering. If ArrayField is possibly not rendered in your case, please avoid using this event */\n onArrayAppend = 'onArrayAppend',\n /* It will trigger when ArrayField.delete is called. It relies on ArrayField's rendering. If ArrayField is possibly not rendered in your case, please avoid using this event */\n onArrayDelete = 'onArrayDelete',\n}\n\nexport type EffectReturn = () => void;\n\nexport interface EffectFuncProps<TFieldValue = any, TFormValues = any> {\n name: FieldName;\n value: TFieldValue;\n prevValue?: TFieldValue;\n formValues: TFormValues;\n form: IForm;\n context: NodeContext;\n}\n\nexport type Effect<TFieldValue = any, TFormValues = any> = (\n props: EffectFuncProps<TFieldValue, TFormValues>\n) => void | EffectReturn;\n\nexport type ArrayAppendEffect<TFieldValue = any, TFormValues = any> = (props: {\n index: number;\n value: TFieldValue;\n arrayValues: Array<TFieldValue>;\n formValues: TFormValues;\n form: IForm;\n context: NodeContext;\n}) => void | EffectReturn;\n\nexport type ArrayDeleteEffect<TFieldValue = any, TFormValues = any> = (props: {\n index: number;\n arrayValue: Array<TFieldValue>;\n formValues: TFormValues;\n form: IForm;\n context: NodeContext;\n}) => void | EffectReturn;\n\nexport type EffectOptions =\n | { effect: Effect; event: DataEvent }\n | { effect: ArrayAppendEffect; event: DataEvent }\n | { effect: ArrayDeleteEffect; event: DataEvent };\n\nexport interface FormMeta<TValues = any> {\n /**\n * The render method of the node form content. <Form /> is already integrated, so you don't need to wrap your components with <Form />\n * @param props\n */\n render: (props: FormRenderProps<any>) => React.ReactElement;\n /**\n * When to trigger the validation.\n */\n validateTrigger?: ValidateTrigger;\n /**\n * Form data's validation rules. It's a key value map, where the key is a pattern of data's path (or field name), the value is a validate function.\n */\n validate?: Record<FieldName, Validate>;\n /**\n * Form data's effects. It's a key value map, where the key is a pattern of data's path (or field name), the value is an array of effect configuration.\n */\n effect?: Record<FieldName, EffectOptions[]>;\n /**\n * Form data's complete default value. it will not be sent to formatOnInit, but used directly as form's value when needed.\n */\n defaultValues?: TValues | ((context: NodeContext) => TValues);\n /**\n * This function is to format the value when initiate the form, the returned value will be used as the initial value of the form.\n * @param value value input to node as initialValue.\n * @param context\n */\n formatOnInit?: (value: any, context: NodeContext) => any;\n /**\n * This function is to format the value when FormModel.toJSON is called, the returned value will be used as the final value to be saved .\n * @param value value sent by form before format.\n * @param context\n */\n formatOnSubmit?: (value: any, context: NodeContext) => any;\n /**\n * Form's plugins\n */\n plugins?: FormPlugin[];\n}\n\nexport function isFormModelV2(fm: FormModel | FormModelV2): fm is FormModelV2 {\n return 'onFormValuesChange' in fm;\n}\n\nexport function isFormMetaV2(formMeta: IFormMeta | FormMeta) {\n return 'render' in formMeta;\n}\n\nexport type FormPluginCtx = {\n formModel: FormModelV2;\n} & NodeContext;\n\nexport type FormPluginSetupMetaCtx = {\n mergeEffect: (effect: Record<string, EffectOptions[]>) => void;\n mergeValidate: (validate: Record<FieldName, Validate>) => void;\n addFormatOnInit: (formatOnInit: FormMeta['formatOnInit']) => void;\n addFormatOnSubmit: (formatOnSubmit: FormMeta['formatOnSubmit']) => void;\n} & NodeContext;\n\nexport interface onFormValueChangeInPayload<TValue = FieldValue, TFormValues = FieldValue> {\n value: TValue;\n prevValue: TValue;\n formValues: TFormValues;\n prevFormValues: TFormValues;\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { get, groupBy, isEmpty, mapKeys } from 'lodash';\nimport { Disposable, DisposableCollection, Emitter } from '@flowgram.ai/utils';\nimport {\n FlowNodeFormData,\n FormFeedback,\n FormItem,\n FormManager,\n FormModel,\n FormModelValid,\n IFormItem,\n OnFormValuesChangePayload,\n} from '@flowgram.ai/form-core';\nimport {\n createForm,\n FieldArrayModel,\n FieldName,\n FieldValue,\n type FormControl,\n FormModel as NativeFormModel,\n FormValidateReturn,\n Glob,\n IField,\n IFieldArray,\n toForm,\n} from '@flowgram.ai/form';\nimport { FlowNodeEntity } from '@flowgram.ai/document';\nimport { PlaygroundContext, PluginContext } from '@flowgram.ai/core';\n\nimport { convertGlobPath, findMatchedInMap, formFeedbacksToNodeCoreFormFeedbacks } from './utils';\nimport {\n DataEvent,\n Effect,\n EffectOptions,\n EffectReturn,\n FormMeta,\n onFormValueChangeInPayload,\n} from './types';\nimport { renderForm } from './form-render';\nimport { FormPlugin } from './form-plugin';\n\nconst DEFAULT = {\n // Different formModel should have different reference\n EFFECT_MAP: () => ({}),\n EFFECT_RETURN_MAP: () =>\n new Map([\n [DataEvent.onValueInitOrChange, {}],\n [DataEvent.onValueChange, {}],\n [DataEvent.onValueInit, {}],\n [DataEvent.onArrayAppend, {}],\n [DataEvent.onArrayDelete, {}],\n ]),\n FORM_FEEDBACKS: () => [],\n VALID: null,\n};\n\nexport class FormModelV2 extends FormModel implements Disposable {\n protected effectMap: Record<string, EffectOptions[]> = DEFAULT.EFFECT_MAP();\n\n protected effectReturnMap: Map<DataEvent, Record<string, EffectReturn>> =\n DEFAULT.EFFECT_RETURN_MAP();\n\n protected plugins: FormPlugin[] = [];\n\n protected node: FlowNodeEntity;\n\n protected formFeedbacks: FormValidateReturn | undefined = DEFAULT.FORM_FEEDBACKS();\n\n protected onInitializedEmitter = new Emitter<FormModel>();\n\n protected onValidateEmitter = new Emitter<FormModel>();\n\n readonly onValidate = this.onValidateEmitter.event;\n\n readonly onInitialized = this.onInitializedEmitter.event;\n\n protected onDisposeEmitter = new Emitter<void>();\n\n readonly onDispose = this.onDisposeEmitter.event;\n\n protected toDispose = new DisposableCollection();\n\n protected onFormValuesChangeEmitter = new Emitter<OnFormValuesChangePayload>();\n\n readonly onFormValuesChange = this.onFormValuesChangeEmitter.event;\n\n protected onValidChangeEmitter = new Emitter<FormModelValid>();\n\n readonly onValidChange = this.onValidChangeEmitter.event;\n\n protected onFeedbacksChangeEmitter = new Emitter<FormFeedback[]>();\n\n readonly onFeedbacksChange = this.onFeedbacksChangeEmitter.event;\n\n constructor(node: FlowNodeEntity) {\n super();\n this.node = node;\n this.toDispose.pushAll([\n this.onInitializedEmitter,\n this.onValidateEmitter,\n this.onValidChangeEmitter,\n this.onFeedbacksChangeEmitter,\n this.onFormValuesChangeEmitter,\n ]);\n }\n\n protected _valid: FormModelValid = DEFAULT.VALID;\n\n get valid(): FormModelValid {\n return this._valid;\n }\n\n private set valid(valid: FormModelValid) {\n this._valid = valid;\n this.onValidChangeEmitter.fire(valid);\n }\n\n get flowNodeEntity() {\n return this.node;\n }\n\n get formManager() {\n return this.node.getService(FormManager);\n }\n\n protected _formControl?: FormControl<any>;\n\n get formControl() {\n return this._formControl;\n }\n\n protected _formMeta: FormMeta;\n\n get formMeta(): FormMeta {\n return this._formMeta || (this.node.getNodeRegistry().formMeta as FormMeta);\n }\n\n get values() {\n return this.nativeFormModel?.values;\n }\n\n protected _feedbacks: FormFeedback[] = [];\n\n get feedbacks(): FormFeedback[] {\n return this._feedbacks;\n }\n\n updateFormValues(value: any) {\n if (this.nativeFormModel) {\n const finalValue = this.formMeta.formatOnInit\n ? this.formMeta.formatOnInit(value, this.nodeContext)\n : value;\n this.nativeFormModel.values = finalValue;\n }\n }\n\n private set feedbacks(feedbacks: FormFeedback[]) {\n this._feedbacks = feedbacks;\n this.onFeedbacksChangeEmitter.fire(feedbacks);\n }\n\n get formItemPathMap(): Map<string, IFormItem> {\n return new Map<string, IFormItem>();\n }\n\n protected _initialized: boolean = false;\n\n get initialized(): boolean {\n return this._initialized;\n }\n\n get nodeContext() {\n return {\n node: this.node,\n playgroundContext: this.node.getService(PlaygroundContext),\n clientContext: this.node.getService(PluginContext),\n };\n }\n\n get nativeFormModel(): NativeFormModel | undefined {\n return this._formControl?._formModel;\n }\n\n render() {\n return renderForm(this);\n }\n\n initPlugins(plugins: FormPlugin[]) {\n if (!plugins.length) {\n return;\n }\n\n this.plugins = plugins;\n plugins.forEach((plugin) => {\n plugin.init(this);\n });\n }\n\n init(formMeta: FormMeta, rawInitialValues?: any) {\n /* 透传 onFormValuesChange 事件给 FlowNodeFormData */\n const formData = this.node.getData<FlowNodeFormData>(FlowNodeFormData);\n this.onFormValuesChange(() => {\n this._valid = null;\n formData.fireChange();\n });\n\n (formMeta.plugins || [])?.forEach((_plugin) => {\n if (_plugin.setupFormMeta) {\n formMeta = _plugin.setupFormMeta(formMeta, this.nodeContext);\n }\n });\n\n this._formMeta = formMeta;\n\n const { validateTrigger, validate, effect } = formMeta;\n if (effect) {\n this.effectMap = effect;\n }\n\n // 计算初始值: defaultValues 是默认表单值,不需要被format, 而rawInitialValues 是用户创建form 时传入的初始值,可能不同于表单数据格式,需要被format\n const defaultValues =\n typeof formMeta.defaultValues === 'function'\n ? formMeta.defaultValues(this.nodeContext)\n : formMeta.defaultValues;\n\n const initialValues = formMeta.formatOnInit\n ? formMeta.formatOnInit(rawInitialValues, this.nodeContext)\n : rawInitialValues;\n\n // 初始化底层表单\n const { control } = createForm({\n initialValues: initialValues || defaultValues,\n validateTrigger,\n context: this.nodeContext,\n validate: validate,\n disableAutoInit: true,\n });\n\n this._formControl = control;\n const nativeFormModel = control._formModel;\n this.toDispose.push(nativeFormModel);\n\n // forward onFormValuesChange event\n nativeFormModel.onFormValuesChange((props) => {\n this.onFormValuesChangeEmitter.fire(props);\n });\n\n if (formMeta.plugins) {\n this.initPlugins(formMeta.plugins);\n }\n\n // Form 数据变更时触发对应的effect\n nativeFormModel.onFormValuesChange(({ values, prevValues, name }) => {\n // 找到所有路径匹配的副作用,包括父亲路径\n const effectKeys = Object.keys(this.effectMap).filter((pattern) =>\n Glob.isMatchOrParent(pattern, name)\n );\n\n effectKeys.forEach((effectKey) => {\n const effectOptionsArr = this.effectMap[effectKey];\n // 执行该事件配置下所有 onValueChange 事件的 effect\n effectOptionsArr.forEach(({ effect, event }: EffectOptions) => {\n if (event === DataEvent.onValueChange || event === DataEvent.onValueInitOrChange) {\n // 对于冒泡的事件,需要获取 parent 的 name\n const currentName = Glob.getParentPathByPattern(effectKey, name);\n\n // 执行上一次effect 的 return\n const prevEffectReturn = this.effectReturnMap.get(event)?.[currentName];\n if (prevEffectReturn) {\n prevEffectReturn();\n }\n\n // 执行effect\n const effectReturn = (effect as Effect)({\n name: currentName,\n value: get(values, currentName),\n prevValue: get(prevValues, currentName),\n formValues: values,\n form: toForm(this.nativeFormModel!),\n context: this.nodeContext,\n });\n\n // 更新 effect return\n if (\n effectReturn &&\n typeof effectReturn === 'function' &&\n this.effectReturnMap.has(event)\n ) {\n const eventMap = this.effectReturnMap.get(event) as Record<string, EffectReturn>;\n eventMap[currentName] = effectReturn;\n }\n }\n });\n });\n });\n\n // Form 数据初始化时触发对应的effect\n nativeFormModel.onFormValuesInit(({ values, name, prevValues }) => {\n Object.keys(this.effectMap).forEach((pattern) => {\n // 找到匹配 pattern 的数据路径\n const paths = Glob.findMatchPaths(values, pattern);\n\n // 获取配置在该 pattern上的所有effect配置\n const effectOptionsArr = this.effectMap[pattern];\n\n effectOptionsArr.forEach(({ event, effect }: EffectOptions) => {\n if (event === DataEvent.onValueInit || event === DataEvent.onValueInitOrChange) {\n paths.forEach((path) => {\n // 对触发 init 事件的 name 或他的字 path 触发effect\n if (Glob.isMatchOrParent(name, path) || name === path) {\n // 执行上一次effect 的 return\n const prevEffectReturn = this.effectReturnMap.get(event)?.[path];\n if (prevEffectReturn) {\n prevEffectReturn();\n }\n\n const effectReturn = (effect as Effect)({\n name: path,\n value: get(values, path),\n formValues: values,\n prevValue: get(prevValues, path),\n form: toForm(this.nativeFormModel!),\n context: this.nodeContext,\n });\n\n // 更新 effect return\n if (\n effectReturn &&\n typeof effectReturn === 'function' &&\n this.effectReturnMap.has(event)\n ) {\n const eventMap = this.effectReturnMap.get(event) as Record<string, EffectReturn>;\n eventMap[path] = effectReturn;\n }\n }\n });\n }\n });\n });\n });\n\n // 为 Field 添加 effect, 主要针对array\n nativeFormModel.onFieldModelCreate((field) => {\n // register effect\n const effectOptionsArr = findMatchedInMap<EffectOptions[]>(field, this.effectMap);\n if (effectOptionsArr?.length) {\n // 按事件聚合\n const eventMap = groupBy(effectOptionsArr, 'event');\n\n mapKeys(eventMap, (optionsArr, event) => {\n const combinedEffect = (props: any) => {\n // 该事件下执行所有effect\n optionsArr.forEach(({ effect }) =>\n effect({\n ...props,\n formValues: nativeFormModel.values,\n form: toForm(this.nativeFormModel!),\n context: this.nodeContext,\n })\n );\n };\n\n switch (event) {\n case DataEvent.onArrayAppend:\n if (field instanceof FieldArrayModel) {\n (field as FieldArrayModel).onAppend(combinedEffect);\n }\n break;\n case DataEvent.onArrayDelete:\n if (field instanceof FieldArrayModel) {\n (field as FieldArrayModel).onDelete(combinedEffect);\n }\n break;\n }\n });\n }\n });\n\n // 手动初始化form\n this._formControl.init();\n\n this._initialized = true;\n\n this.onInitializedEmitter.fire(this);\n\n this.onDispose(() => {\n this._initialized = false;\n this.effectMap = {};\n nativeFormModel.dispose();\n });\n }\n\n toJSON() {\n if (this.formMeta.formatOnSubmit) {\n return this.formMeta.formatOnSubmit(this.nativeFormModel?.values, this.nodeContext);\n }\n return this.nativeFormModel?.values;\n }\n\n clearValid() {\n if (this.valid !== null) {\n this.valid = null;\n }\n }\n\n async validate() {\n this.formFeedbacks = await this.nativeFormModel?.validate();\n this.valid = isEmpty(this.formFeedbacks?.filter((f) => f.level === 'error'));\n this.onValidateEmitter.fire(this);\n return this.valid;\n }\n\n getValues<T = any>(): T | undefined {\n return this._formControl?._formModel.values;\n }\n\n getField<\n TValue = FieldValue,\n TField extends IFieldArray<TValue> | IField<TValue> = IField<TValue>\n >(name: FieldName): TField | undefined {\n let finalName = name.includes('/') ? convertGlobPath(name) : name;\n\n return this.formControl?.getField<TValue, TField>(finalName) as TField;\n }\n\n getValueIn<TValue>(name: FieldName): TValue | undefined {\n let finalName = name.includes('/') ? convertGlobPath(name) : name;\n\n return this.nativeFormModel?.getValueIn(finalName);\n }\n\n setValueIn(name: FieldName, value: any) {\n let finalName = name.includes('/') ? convertGlobPath(name) : name;\n\n this.nativeFormModel?.setValueIn(finalName, value);\n }\n\n /**\n * 监听表单某个路径下的值变化\n * @param name 路径\n * @param callback 回调函数\n */\n onFormValueChangeIn<TValue = FieldValue, TFormValue = FieldValue>(\n name: FieldName,\n callback: (payload: onFormValueChangeInPayload<TValue, TFormValue>) => void\n ): Disposable {\n if (!this._initialized) {\n throw new Error(\n `[NodeEngine] FormModel Error: onFormValueChangeIn can not be called before initialized`\n );\n }\n\n return this.formControl!._formModel.onFormValuesChange(\n ({ name: changedName, values, prevValues }) => {\n if (changedName === name) {\n callback({\n value: get(values, name),\n prevValue: get(prevValues, name),\n formValues: values,\n prevFormValues: prevValues,\n });\n }\n }\n );\n }\n\n /**\n * @deprecated 该方法用于兼容 V1 版本 FormModel接口,如果确定是FormModelV2 请使用 FormModel.getValueIn\n * @param path glob path\n */\n getFormItemValueByPath(globPath: string) {\n if (!globPath) {\n return;\n }\n if (globPath === '/') {\n return this._formControl?._formModel.values;\n }\n const name = convertGlobPath(globPath);\n return this.getValueIn(name!);\n }\n\n async validateWithFeedbacks(): Promise<FormFeedback[]> {\n await this.validate();\n return formFeedbacksToNodeCoreFormFeedbacks(this.formFeedbacks!);\n }\n\n /**\n * @deprecated 该方法用于兼容 V1 版本 FormModel接口,如果确定是FormModelV2, 请使用FormModel.getValueIn 和 FormModel.setValueIn\n * @param path glob path\n */\n getFormItemByPath(path: string): FormItem | undefined {\n if (!this.nativeFormModel) {\n return;\n }\n\n const that = this;\n\n if (path === '/') {\n return {\n get value() {\n return that.nativeFormModel!.values;\n },\n set value(v) {\n that.nativeFormModel!.values = v;\n },\n } as FormItem;\n }\n\n const name = convertGlobPath(path);\n const formItemValue = that.getValueIn(name!);\n return {\n get value() {\n return formItemValue;\n },\n set value(v) {\n that.setValueIn(name, v);\n },\n } as FormItem;\n }\n\n dispose(): void {\n this.onDisposeEmitter.fire();\n\n // 执行所有effect return\n this.effectReturnMap.forEach((eventMap) => {\n Object.values(eventMap).forEach((effectReturn) => {\n effectReturn();\n });\n });\n\n this.effectMap = DEFAULT.EFFECT_MAP();\n this.effectReturnMap = DEFAULT.EFFECT_RETURN_MAP();\n\n this.plugins.forEach((p) => {\n p.dispose();\n });\n\n this.plugins = [];\n\n this.formFeedbacks = DEFAULT.FORM_FEEDBACKS();\n this._valid = DEFAULT.VALID;\n\n this._formControl = undefined;\n this._initialized = false;\n this.toDispose.dispose();\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { find, mergeWith } from 'lodash';\nimport { FormFeedback, FormPathService } from '@flowgram.ai/form-core';\nimport { FormValidateReturn } from '@flowgram.ai/form/src/types';\nimport { type FieldModel, FieldName } from '@flowgram.ai/form';\n\nimport { EffectOptions } from './types';\n\nexport function findMatchedInMap<T = any>(\n field: FieldModel<any>,\n validateMap: Record<FieldName, T> | undefined\n): T | undefined {\n if (!validateMap) {\n return;\n }\n if (validateMap[field.name]) {\n return validateMap[field.name];\n }\n\n const found = find(Object.keys(validateMap), (key) => {\n if (key.startsWith('regex:')) {\n const regex = RegExp(key.split(':')[1]);\n return regex.test(field.name);\n }\n return false;\n });\n\n if (found) {\n return validateMap[found];\n }\n}\n\nexport function formFeedbacksToNodeCoreFormFeedbacks(\n formFeedbacks: FormValidateReturn\n): FormFeedback[] {\n return formFeedbacks.map(\n (f) =>\n ({\n feedbackStatus: f.level,\n feedbackText: f.message,\n path: f.name,\n } as FormFeedback)\n );\n}\n\nexport function convertGlobPath(path: string) {\n if (path.startsWith('/')) {\n const parts = FormPathService.normalize(path).slice(1).split('/');\n return parts.join('.');\n }\n return path;\n}\n\nexport function mergeEffectMap(\n origin: Record<string, EffectOptions[]>,\n source: Record<string, EffectOptions[]>\n) {\n return mergeWith(origin, source, function (objValue: EffectOptions[], srcValue: EffectOptions[]) {\n return (objValue || []).concat(srcValue);\n });\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport React from 'react';\n\nimport { Form } from '@flowgram.ai/form';\n\nimport { FormModelV2 } from './form-model-v2';\n\ninterface FormRenderProps {\n formModel: FormModelV2;\n}\n\nconst FormRender = ({ formModel }: FormRenderProps) =>\n formModel?.formControl ? (\n <>\n <Form control={formModel?.formControl} keepModelOnUnMount>\n {formModel.formMeta.render}\n </Form>\n </>\n ) : null;\n\nexport function renderForm(formModel: FormModelV2) {\n return <FormRender formModel={formModel} />;\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { FlowNodeFormData } from '@flowgram.ai/form-core';\nimport { FlowNodeEntity } from '@flowgram.ai/document';\n\nimport { DataEvent } from './types';\nimport { FormModelV2 } from './form-model-v2';\n\nexport function getFormModel(node: FlowNodeEntity) {\n // @ts-ignore\n return node.getData<FlowNodeFormData>(FlowNodeFormData)?.formModel as FormModelV2;\n}\n\nexport function isFormV2(node: FlowNodeEntity) {\n return !!node.getNodeRegistry().formMeta?.render;\n}\n\nexport function createEffectOptions<T>(\n event: DataEvent,\n effect: T\n): { effect: T; event: DataEvent } {\n return {\n event,\n effect,\n };\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { useEffect } from 'react';\n\nimport { useRefresh } from '@flowgram.ai/utils';\nimport { FlowNodeFormData } from '@flowgram.ai/form-core';\nimport { Errors, Warnings } from '@flowgram.ai/form/src/types';\nimport { FormState, useFormErrors, useFormState, useFormWarnings } from '@flowgram.ai/form';\nimport { FlowNodeEntity } from '@flowgram.ai/document';\n\nimport { FormModelV2 } from './form-model-v2';\n\n/**\n * Listen to Form's values and refresh the React component.\n * By providing related node, you can use this hook outside the Form Component.\n * @param node\n */\nexport function useWatchFormValues<T = any>(node: FlowNodeEntity): T | undefined {\n const formModel = node.getData(FlowNodeFormData).getFormModel<FormModelV2>();\n const refresh = useRefresh();\n\n useEffect(() => {\n const disposable = formModel.nativeFormModel?.onFormValuesChange(() => {\n refresh();\n });\n return () => disposable?.dispose();\n }, [formModel.nativeFormModel]);\n\n return formModel.getValues<T>();\n}\n\n/**\n * Listen to Form's value in a certain path and refresh the React component.\n * By providing related node, you can use this hook outside the Form Component.\n * @param node\n */\nexport function useWatchFormValueIn<T = any>(node: FlowNodeEntity, name: string): T | undefined {\n const formModel = node.getData(FlowNodeFormData).getFormModel<FormModelV2>();\n const refresh = useRefresh();\n\n useEffect(() => {\n const disposable = formModel.nativeFormModel?.onFormValuesChange(({ name: changedName }) => {\n if (name === changedName) {\n refresh();\n }\n });\n\n return () => disposable?.dispose();\n }, []);\n\n return formModel.getValueIn<T>(name);\n}\n\n/**\n * Listen to FormModel's initialization and refresh React component.\n * By providing related node, you can use this hook outside the Form Component.\n * @param node\n */\nexport function useInitializedFormModel(node: FlowNodeEntity) {\n const formModel = node.getData(FlowNodeFormData).getFormModel<FormModelV2>();\n const refresh = useRefresh();\n\n useEffect(() => {\n const disposable = formModel.onInitialized(() => {\n refresh();\n });\n return () => disposable.dispose();\n }, [formModel]);\n\n return formModel;\n}\n\n/**\n * Get Form's state, Form State is a proxy, it will refresh the React component when the value you accessed changed\n * By providing related node, you can use this hook outside the Form Component.\n * @param node\n */\nexport function useWatchFormState(node: FlowNodeEntity): FormState | undefined {\n const formModel = useInitializedFormModel(node);\n return useFormState(formModel.formControl);\n}\n\n/**\n * Get Form's errors, Form errors is a proxy, it will refresh the React component when the value you accessed changed\n * By providing related node, you can use this hook outside the Form Component.\n * @param node\n */\nexport function useWatchFormErrors(node: FlowNodeEntity): Errors | undefined {\n const formModel = useInitializedFormModel(node);\n return useFormErrors(formModel.formControl);\n}\n\n/**\n * Get Form's warnings, Form warnings is a proxy, it will refresh the React component when the value you accessed changed\n * By providing related node, you can use this hook outside the Form Component.\n * @param node\n */\nexport function useWatchFormWarnings(node: FlowNodeEntity): Warnings | undefined {\n const formModel = useInitializedFormModel(node);\n return useFormWarnings(formModel.formControl);\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { nanoid } from 'nanoid';\nimport { Disposable } from '@flowgram.ai/utils';\nimport { type NodeFormContext } from '@flowgram.ai/form-core';\n\nimport { type FormMeta, type FormPluginCtx, type FormPluginSetupMetaCtx } from './types';\nimport { FormModelV2 } from './form-model-v2';\n\nexport interface FormPluginConfig<Opts = any> {\n /**\n * form plugin name, for debug use\n */\n name?: string;\n\n /**\n * setup formMeta\n * @param ctx\n * @returns\n */\n onSetupFormMeta?: (ctx: FormPluginSetupMetaCtx, opts: Opts) => void;\n\n /**\n * FormModel 初始化时执行\n * @param ctx\n */\n onInit?: (ctx: FormPluginCtx, opts: Opts) => void;\n\n /**\n * FormModel 销毁时执行\n */\n onDispose?: (ctx: FormPluginCtx, opts: Opts) => void;\n}\n\nexport class FormPlugin<Opts = any> implements Disposable {\n readonly name: string;\n\n readonly pluginId: string;\n\n readonly config: FormPluginConfig;\n\n readonly opts?: Opts;\n\n protected _formModel: FormModelV2;\n\n constructor(config: FormPluginConfig, opts?: Opts) {\n this.name = config?.name || '';\n this.pluginId = `${this.name}__${nanoid()}`;\n this.config = config;\n\n this.opts = opts;\n }\n\n get formModel(): FormModelV2 {\n return this._formModel;\n }\n\n get ctx() {\n return {\n formModel: this.formModel,\n node: this.formModel.nodeContext.node,\n playgroundContext: this.formModel.nodeContext.playgroundContext,\n };\n }\n\n setupFormMeta(formMeta: FormMeta, nodeContext: NodeFormContext): FormMeta {\n const nextFormMeta: FormMeta = {\n ...formMeta,\n };\n\n this.config.onSetupFormMeta?.(\n {\n mergeEffect: (effect) => {\n nextFormMeta.effect = {\n ...(nextFormMeta.effect || {}),\n ...effect,\n };\n },\n mergeValidate: (validate) => {\n nextFormMeta.validate = {\n ...(nextFormMeta.validate || {}),\n ...validate,\n };\n },\n addFormatOnInit: (formatOnInit) => {\n if (!nextFormMeta.formatOnInit) {\n nextFormMeta.formatOnInit = formatOnInit;\n return;\n }\n const legacyFormatOnInit = nextFormMeta.formatOnInit;\n nextFormMeta.formatOnInit = (v, c) => formatOnInit?.(legacyFormatOnInit(v, c), c);\n },\n addFormatOnSubmit: (formatOnSubmit) => {\n if (!nextFormMeta.formatOnSubmit) {\n nextFormMeta.formatOnSubmit = formatOnSubmit;\n return;\n }\n const legacyFormatOnSubmit = nextFormMeta.formatOnSubmit;\n nextFormMeta.formatOnSubmit = (v, c) => formatOnSubmit?.(legacyFormatOnSubmit(v, c), c);\n },\n ...nodeContext,\n },\n this.opts\n );\n\n return nextFormMeta;\n }\n\n init(formModel: FormModelV2) {\n this._formModel = formModel;\n this.config?.onInit?.(this.ctx, this.opts);\n }\n\n dispose() {\n if (this.config?.onDispose) {\n this.config?.onDispose(this.ctx, this.opts);\n }\n }\n}\n\nexport type FormPluginCreator<Opts> = (opts: Opts) => FormPlugin<Opts>;\n\nexport function defineFormPluginCreator<Opts>(config: FormPluginConfig): FormPluginCreator<Opts> {\n return function (opts: Opts) {\n return new FormPlugin(config, opts);\n };\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport React from 'react';\n\nimport { Disposable, Event } from '@flowgram.ai/utils';\nimport { FlowNodeFormData, NodeRender, OnFormValuesChangePayload } from '@flowgram.ai/form-core';\nimport { FieldName, FieldValue, FormState } from '@flowgram.ai/form';\nimport { FlowNodeEntity } from '@flowgram.ai/document';\n\nimport { onFormValueChangeInPayload } from './types';\nimport { FormModelV2 } from './form-model-v2';\n\nexport interface NodeFormProps<TValues> {\n /**\n * The initialValues of the form.\n */\n initialValues: TValues;\n /**\n * Form values. Returns a deep copy of the data in the store.\n */\n values: TValues;\n /**\n * Form state\n */\n state: FormState;\n /**\n * Get value in certain path\n * @param name path\n */\n getValueIn<TValue = FieldValue>(name: FieldName): TValue;\n\n /**\n * Set value in certain path.\n * It will trigger the re-rendering of the Field Component if a Field is related to this path\n * @param name path\n */\n setValueIn<TValue>(name: FieldName, value: TValue): void;\n /**\n * set form values\n */\n updateFormValues(values: any): void;\n /**\n * Render form\n */\n render: () => React.ReactNode;\n /**\n * Form value change event\n */\n onFormValuesChange: Event<OnFormValuesChangePayload>;\n /**\n * Trigger form validate\n */\n validate: () => Promise<boolean>;\n /**\n * Form validate event\n */\n onValidate: Event<FormState>;\n /**\n * Form field value change event\n */\n onFormValueChangeIn<TValue = FieldValue, TFormValue = FieldValue>(\n name: FieldName,\n callback: (payload: onFormValueChangeInPayload<TValue, TFormValue>) => void\n ): Disposable;\n}\n\n/**\n * Only support FormModelV2\n * @param node\n */\nexport function getNodeForm<TValues = FieldValue>(\n node: FlowNodeEntity\n): NodeFormProps<TValues> | undefined {\n const formModel = node.getData<FlowNodeFormData>(FlowNodeFormData)?.getFormModel<FormModelV2>();\n const nativeFormModel = formModel?.nativeFormModel;\n\n if (!formModel || !nativeFormModel) return undefined;\n\n const result: NodeFormProps<TValues> = {\n initialValues: nativeFormModel.initialValues,\n get values() {\n return nativeFormModel.values;\n },\n\n state: nativeFormModel.state,\n getValueIn: (name: FieldName) => nativeFormModel.getValueIn(name),\n setValueIn: (name: FieldName, value: any) => nativeFormModel.setValueIn(name, value),\n updateFormValues: (values: any) => {\n formModel.updateFormValues(values);\n },\n render: () => <NodeRender node={node} />,\n onFormValuesChange: formModel.onFormValuesChange.bind(formModel),\n onFormValueChangeIn: formModel.onFormValueChangeIn.bind(formModel),\n onValidate: formModel.nativeFormModel.onValidate,\n validate: formModel.validate.bind(formModel),\n };\n\n Object.defineProperty(result, '_formModel', {\n enumerable: false,\n get() {\n return formModel;\n },\n });\n return result;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACqCO,IAAK,YAAL,kBAAKA,eAAL;AAEL,EAAAA,WAAA,mBAAgB;AAMhB,EAAAA,WAAA,iBAAc;AAId,EAAAA,WAAA,yBAAsB;AAEtB,EAAAA,WAAA,mBAAgB;AAEhB,EAAAA,WAAA,mBAAgB;AAhBN,SAAAA;AAAA,GAAA;AAgGL,SAAS,cAAc,IAAgD;AAC5E,SAAO,wBAAwB;AACjC;AAEO,SAAS,aAAa,UAAgC;AAC3D,SAAO,YAAY;AACrB;;;ACtIA,IAAAC,iBAA+C;AAC/C,mBAA0D;AAC1D,IAAAC,oBASO;AACP,IAAAC,eAYO;AAEP,kBAAiD;;;AC1BjD,oBAAgC;AAChC,uBAA8C;AAMvC,SAAS,iBACd,OACA,aACe;AACf,MAAI,CAAC,aAAa;AAChB;AAAA,EACF;AACA,MAAI,YAAY,MAAM,IAAI,GAAG;AAC3B,WAAO,YAAY,MAAM,IAAI;AAAA,EAC/B;AAEA,QAAM,YAAQ,oBAAK,OAAO,KAAK,WAAW,GAAG,CAAC,QAAQ;AACpD,QAAI,IAAI,WAAW,QAAQ,GAAG;AAC5B,YAAM,QAAQ,OAAO,IAAI,MAAM,GAAG,EAAE,CAAC,CAAC;AACtC,aAAO,MAAM,KAAK,MAAM,IAAI;AAAA,IAC9B;AACA,WAAO;AAAA,EACT,CAAC;AAED,MAAI,OAAO;AACT,WAAO,YAAY,KAAK;AAAA,EAC1B;AACF;AAEO,SAAS,qCACd,eACgB;AAChB,SAAO,cAAc;AAAA,IACnB,CAAC,OACE;AAAA,MACC,gBAAgB,EAAE;AAAA,MAClB,cAAc,EAAE;AAAA,MAChB,MAAM,EAAE;AAAA,IACV;AAAA,EACJ;AACF;AAEO,SAAS,gBAAgB,MAAc;AAC5C,MAAI,KAAK,WAAW,GAAG,GAAG;AACxB,UAAM,QAAQ,iCAAgB,UAAU,IAAI,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG;AAChE,WAAO,MAAM,KAAK,GAAG;AAAA,EACvB;AACA,SAAO;AACT;;;AClDA,mBAAkB;AAElB,kBAAqB;AAQrB,IAAM,aAAa,CAAC,EAAE,UAAU,MAC9B,WAAW,cACT,6BAAAC,QAAA,2BAAAA,QAAA,gBACE,6BAAAA,QAAA,cAAC,oBAAK,SAAS,WAAW,aAAa,oBAAkB,QACtD,UAAU,SAAS,MACtB,CACF,IACE;AAEC,SAAS,WAAW,WAAwB;AACjD,SAAO,6BAAAA,QAAA,cAAC,cAAW,WAAsB;AAC3C;;;AFmBA,IAAM,UAAU;AAAA;AAAA,EAEd,YAAY,OAAO,CAAC;AAAA,EACpB,mBAAmB,MACjB,oBAAI,IAAI;AAAA,IACN,kDAAgC,CAAC,CAAC;AAAA,IAClC,sCAA0B,CAAC,CAAC;AAAA,IAC5B,kCAAwB,CAAC,CAAC;AAAA,IAC1B,sCAA0B,CAAC,CAAC;AAAA,IAC5B,sCAA0B,CAAC,CAAC;AAAA,EAC9B,CAAC;AAAA,EACH,gBAAgB,MAAM,CAAC;AAAA,EACvB,OAAO;AACT;AAEO,IAAM,cAAN,cAA0B,4BAAgC;AAAA,EAsC/D,YAAY,MAAsB;AAChC,UAAM;AAtCR,SAAU,YAA6C,QAAQ,WAAW;AAE1E,SAAU,kBACR,QAAQ,kBAAkB;AAE5B,SAAU,UAAwB,CAAC;AAInC,SAAU,gBAAgD,QAAQ,eAAe;AAEjF,SAAU,uBAAuB,IAAI,qBAAmB;AAExD,SAAU,oBAAoB,IAAI,qBAAmB;AAErD,SAAS,aAAa,KAAK,kBAAkB;AAE7C,SAAS,gBAAgB,KAAK,qBAAqB;AAEnD,SAAU,mBAAmB,IAAI,qBAAc;AAE/C,SAAS,YAAY,KAAK,iBAAiB;AAE3C,SAAU,YAAY,IAAI,kCAAqB;AAE/C,SAAU,4BAA4B,IAAI,qBAAmC;AAE7E,SAAS,qBAAqB,KAAK,0BAA0B;AAE7D,SAAU,uBAAuB,IAAI,qBAAwB;AAE7D,SAAS,gBAAgB,KAAK,qBAAqB;AAEnD,SAAU,2BAA2B,IAAI,qBAAwB;AAEjE,SAAS,oBAAoB,KAAK,yBAAyB;AAc3D,SAAU,SAAyB,QAAQ;AAmC3C,SAAU,aAA6B,CAAC;AAwBxC,SAAU,eAAwB;AArEhC,SAAK,OAAO;AACZ,SAAK,UAAU,QAAQ;AAAA,MACrB,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP,CAAC;AAAA,EACH;AAAA,EAIA,IAAI,QAAwB;AAC1B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAY,MAAM,OAAuB;AACvC,SAAK,SAAS;AACd,SAAK,qBAAqB,KAAK,KAAK;AAAA,EACtC;AAAA,EAEA,IAAI,iBAAiB;AACnB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,cAAc;AAChB,WAAO,KAAK,KAAK,WAAW,6BAAW;AAAA,EACzC;AAAA,EAIA,IAAI,cAAc;AAChB,WAAO,KAAK;AAAA,EACd;AAAA,EAIA,IAAI,WAAqB;AACvB,WAAO,KAAK,aAAc,KAAK,KAAK,gBAAgB,EAAE;AAAA,EACxD;AAAA,EAEA,IAAI,SAAS;AACX,WAAO,KAAK,iBAAiB;AAAA,EAC/B;AAAA,EAIA,IAAI,YAA4B;AAC9B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,iBAAiB,OAAY;AAC3B,QAAI,KAAK,iBAAiB;AACxB,YAAM,aAAa,KAAK,SAAS,eAC7B,KAAK,SAAS,aAAa,OAAO,KAAK,WAAW,IAClD;AACJ,WAAK,gBAAgB,SAAS;AAAA,IAChC;AAAA,EACF;AAAA,EAEA,IAAY,UAAU,WAA2B;AAC/C,SAAK,aAAa;AAClB,SAAK,yBAAyB,KAAK,SAAS;AAAA,EAC9C;AAAA,EAEA,IAAI,kBAA0C;AAC5C,WAAO,oBAAI,IAAuB;AAAA,EACpC;AAAA,EAIA,IAAI,cAAuB;AACzB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,cAAc;AAChB,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,mBAAmB,KAAK,KAAK,WAAW,6BAAiB;AAAA,MACzD,eAAe,KAAK,KAAK,WAAW,yBAAa;AAAA,IACnD;AAAA,EACF;AAAA,EAEA,IAAI,kBAA+C;AACjD,WAAO,KAAK,cAAc;AAAA,EAC5B;AAAA,EAEA,SAAS;AACP,WAAO,WAAW,IAAI;AAAA,EACxB;AAAA,EAEA,YAAY,SAAuB;AACjC,QAAI,CAAC,QAAQ,QAAQ;AACnB;AAAA,IACF;AAEA,SAAK,UAAU;AACf,YAAQ,QAAQ,CAAC,WAAW;AAC1B,aAAO,KAAK,IAAI;AAAA,IAClB,CAAC;AAAA,EACH;AAAA,EAEA,KAAK,UAAoB,kBAAwB;AAE/C,UAAM,WAAW,KAAK,KAAK,QAA0B,kCAAgB;AACrE,SAAK,mBAAmB,MAAM;AAC5B,WAAK,SAAS;AACd,eAAS,WAAW;AAAA,IACtB,CAAC;AAED,KAAC,SAAS,WAAW,CAAC,IAAI,QAAQ,CAAC,YAAY;AAC7C,UAAI,QAAQ,eAAe;AACzB,mBAAW,QAAQ,cAAc,UAAU,KAAK,WAAW;AAAA,MAC7D;AAAA,IACF,CAAC;AAED,SAAK,YAAY;AAEjB,UAAM,EAAE,iBAAiB,UAAU,OAAO,IAAI;AAC9C,QAAI,QAAQ;AACV,WAAK,YAAY;AAAA,IACnB;AAGA,UAAM,gBACJ,OAAO,SAAS,kBAAkB,aAC9B,SAAS,cAAc,KAAK,WAAW,IACvC,SAAS;AAEf,UAAM,gBAAgB,SAAS,eAC3B,SAAS,aAAa,kBAAkB,KAAK,WAAW,IACxD;AAGJ,UAAM,EAAE,QAAQ,QAAI,yBAAW;AAAA,MAC7B,eAAe,iBAAiB;AAAA,MAChC;AAAA,MACA,SAAS,KAAK;AAAA,MACd;AAAA,MACA,iBAAiB;AAAA,IACnB,CAAC;AAED,SAAK,eAAe;AACpB,UAAM,kBAAkB,QAAQ;AAChC,SAAK,UAAU,KAAK,eAAe;AAGnC,oBAAgB,mBAAmB,CAAC,UAAU;AAC5C,WAAK,0BAA0B,KAAK,KAAK;AAAA,IAC3C,CAAC;AAED,QAAI,SAAS,SAAS;AACpB,WAAK,YAAY,SAAS,OAAO;AAAA,IACnC;AAGA,oBAAgB,mBAAmB,CAAC,EAAE,QAAQ,YAAY,KAAK,MAAM;AAEnE,YAAM,aAAa,OAAO,KAAK,KAAK,SAAS,EAAE;AAAA,QAAO,CAAC,YACrD,kBAAK,gBAAgB,SAAS,IAAI;AAAA,MACpC;AAEA,iBAAW,QAAQ,CAAC,cAAc;AAChC,cAAM,mBAAmB,KAAK,UAAU,SAAS;AAEjD,yBAAiB,QAAQ,CAAC,EAAE,QAAAC,SAAQ,MAAM,MAAqB;AAC7D,cAAI,iDAAqC,2DAAyC;AAEhF,kBAAM,cAAc,kBAAK,uBAAuB,WAAW,IAAI;AAG/D,kBAAM,mBAAmB,KAAK,gBAAgB,IAAI,KAAK,IAAI,WAAW;AACtE,gBAAI,kBAAkB;AACpB,+BAAiB;AAAA,YACnB;AAGA,kBAAM,eAAgBA,QAAkB;AAAA,cACtC,MAAM;AAAA,cACN,WAAO,oBAAI,QAAQ,WAAW;AAAA,cAC9B,eAAW,oBAAI,YAAY,WAAW;AAAA,cACtC,YAAY;AAAA,cACZ,UAAM,qBAAO,KAAK,eAAgB;AAAA,cAClC,SAAS,KAAK;AAAA,YAChB,CAAC;AAGD,gBACE,gBACA,OAAO,iBAAiB,cACxB,KAAK,gBAAgB,IAAI,KAAK,GAC9B;AACA,oBAAM,WAAW,KAAK,gBAAgB,IAAI,KAAK;AAC/C,uBAAS,WAAW,IAAI;AAAA,YAC1B;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AAAA,IACH,CAAC;AAGD,oBAAgB,iBAAiB,CAAC,EAAE,QAAQ,MAAM,WAAW,MAAM;AACjE,aAAO,KAAK,KAAK,SAAS,EAAE,QAAQ,CAAC,YAAY;AAE/C,cAAM,QAAQ,kBAAK,eAAe,QAAQ,OAAO;AAGjD,cAAM,mBAAmB,KAAK,UAAU,OAAO;AAE/C,yBAAiB,QAAQ,CAAC,EAAE,OAAO,QAAAA,QAAO,MAAqB;AAC7D,cAAI,6CAAmC,2DAAyC;AAC9E,kBAAM,QAAQ,CAAC,SAAS;AAEtB,kBAAI,kBAAK,gBAAgB,MAAM,IAAI,KAAK,SAAS,MAAM;AAErD,sBAAM,mBAAmB,KAAK,gBAAgB,IAAI,KAAK,IAAI,IAAI;AAC/D,oBAAI,kBAAkB;AACpB,mCAAiB;AAAA,gBACnB;AAEA,sBAAM,eAAgBA,QAAkB;AAAA,kBACtC,MAAM;AAAA,kBACN,WAAO,oBAAI,QAAQ,IAAI;AAAA,kBACvB,YAAY;AAAA,kBACZ,eAAW,oBAAI,YAAY,IAAI;AAAA,kBAC/B,UAAM,qBAAO,KAAK,eAAgB;AAAA,kBAClC,SAAS,KAAK;AAAA,gBAChB,CAAC;AAGD,oBACE,gBACA,OAAO,iBAAiB,cACxB,KAAK,gBAAgB,IAAI,KAAK,GAC9B;AACA,wBAAM,WAAW,KAAK,gBAAgB,IAAI,KAAK;AAC/C,2BAAS,IAAI,IAAI;AAAA,gBACnB;AAAA,cACF;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AAAA,IACH,CAAC;AAGD,oBAAgB,mBAAmB,CAAC,UAAU;AAE5C,YAAM,mBAAmB,iBAAkC,OAAO,KAAK,SAAS;AAChF,UAAI,kBAAkB,QAAQ;AAE5B,cAAM,eAAW,wBAAQ,kBAAkB,OAAO;AAElD,oCAAQ,UAAU,CAAC,YAAY,UAAU;AACvC,gBAAM,iBAAiB,CAAC,UAAe;AAErC,uBAAW;AAAA,cAAQ,CAAC,EAAE,QAAAA,QAAO,MAC3BA,QAAO;AAAA,gBACL,GAAG;AAAA,gBACH,YAAY,gBAAgB;AAAA,gBAC5B,UAAM,qBAAO,KAAK,eAAgB;AAAA,gBAClC,SAAS,KAAK;AAAA,cAChB,CAAC;AAAA,YACH;AAAA,UACF;AAEA,kBAAQ,OAAO;AAAA,YACb;AACE,kBAAI,iBAAiB,8BAAiB;AACpC,gBAAC,MAA0B,SAAS,cAAc;AAAA,cACpD;AACA;AAAA,YACF;AACE,kBAAI,iBAAiB,8BAAiB;AACpC,gBAAC,MAA0B,SAAS,cAAc;AAAA,cACpD;AACA;AAAA,UACJ;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAGD,SAAK,aAAa,KAAK;AAEvB,SAAK,eAAe;AAEpB,SAAK,qBAAqB,KAAK,IAAI;AAEnC,SAAK,UAAU,MAAM;AACnB,WAAK,eAAe;AACpB,WAAK,YAAY,CAAC;AAClB,sBAAgB,QAAQ;AAAA,IAC1B,CAAC;AAAA,EACH;AAAA,EAEA,SAAS;AACP,QAAI,KAAK,SAAS,gBAAgB;AAChC,aAAO,KAAK,SAAS,eAAe,KAAK,iBAAiB,QAAQ,KAAK,WAAW;AAAA,IACpF;AACA,WAAO,KAAK,iBAAiB;AAAA,EAC/B;AAAA,EAEA,aAAa;AACX,QAAI,KAAK,UAAU,MAAM;AACvB,WAAK,QAAQ;AAAA,IACf;AAAA,EACF;AAAA,EAEA,MAAM,WAAW;AACf,SAAK,gBAAgB,MAAM,KAAK,iBAAiB,SAAS;AAC1D,SAAK,YAAQ,wBAAQ,KAAK,eAAe,OAAO,CAAC,MAAM,EAAE,UAAU,OAAO,CAAC;AAC3E,SAAK,kBAAkB,KAAK,IAAI;AAChC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,YAAoC;AAClC,WAAO,KAAK,cAAc,WAAW;AAAA,EACvC;AAAA,EAEA,SAGE,MAAqC;AACrC,QAAI,YAAY,KAAK,SAAS,GAAG,IAAI,gBAAgB,IAAI,IAAI;AAE7D,WAAO,KAAK,aAAa,SAAyB,SAAS;AAAA,EAC7D;AAAA,EAEA,WAAmB,MAAqC;AACtD,QAAI,YAAY,KAAK,SAAS,GAAG,IAAI,gBAAgB,IAAI,IAAI;AAE7D,WAAO,KAAK,iBAAiB,WAAW,SAAS;AAAA,EACnD;AAAA,EAEA,WAAW,MAAiB,OAAY;AACtC,QAAI,YAAY,KAAK,SAAS,GAAG,IAAI,gBAAgB,IAAI,IAAI;AAE7D,SAAK,iBAAiB,WAAW,WAAW,KAAK;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,oBACE,MACA,UACY;AACZ,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,WAAO,KAAK,YAAa,WAAW;AAAA,MAClC,CAAC,EAAE,MAAM,aAAa,QAAQ,WAAW,MAAM;AAC7C,YAAI,gBAAgB,MAAM;AACxB,mBAAS;AAAA,YACP,WAAO,oBAAI,QAAQ,IAAI;AAAA,YACvB,eAAW,oBAAI,YAAY,IAAI;AAAA,YAC/B,YAAY;AAAA,YACZ,gBAAgB;AAAA,UAClB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,uBAAuB,UAAkB;AACvC,QAAI,CAAC,UAAU;AACb;AAAA,IACF;AACA,QAAI,aAAa,KAAK;AACpB,aAAO,KAAK,cAAc,WAAW;AAAA,IACvC;AACA,UAAM,OAAO,gBAAgB,QAAQ;AACrC,WAAO,KAAK,WAAW,IAAK;AAAA,EAC9B;AAAA,EAEA,MAAM,wBAAiD;AACrD,UAAM,KAAK,SAAS;AACpB,WAAO,qCAAqC,KAAK,aAAc;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,kBAAkB,MAAoC;AACpD,QAAI,CAAC,KAAK,iBAAiB;AACzB;AAAA,IACF;AAEA,UAAM,OAAO;AAEb,QAAI,SAAS,KAAK;AAChB,aAAO;AAAA,QACL,IAAI,QAAQ;AACV,iBAAO,KAAK,gBAAiB;AAAA,QAC/B;AAAA,QACA,IAAI,MAAM,GAAG;AACX,eAAK,gBAAiB,SAAS;AAAA,QACjC;AAAA,MACF;AAAA,IACF;AAEA,UAAM,OAAO,gBAAgB,IAAI;AACjC,UAAM,gBAAgB,KAAK,WAAW,IAAK;AAC3C,WAAO;AAAA,MACL,IAAI,QAAQ;AACV,eAAO;AAAA,MACT;AAAA,MACA,IAAI,MAAM,GAAG;AACX,aAAK,WAAW,MAAM,CAAC;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,UAAgB;AACd,SAAK,iBAAiB,KAAK;AAG3B,SAAK,gBAAgB,QAAQ,CAAC,aAAa;AACzC,aAAO,OAAO,QAAQ,EAAE,QAAQ,CAAC,iBAAiB;AAChD,qBAAa;AAAA,MACf,CAAC;AAAA,IACH,CAAC;AAED,SAAK,YAAY,QAAQ,WAAW;AACpC,SAAK,kBAAkB,QAAQ,kBAAkB;AAEjD,SAAK,QAAQ,QAAQ,CAAC,MAAM;AAC1B,QAAE,QAAQ;AAAA,IACZ,CAAC;AAED,SAAK,UAAU,CAAC;AAEhB,SAAK,gBAAgB,QAAQ,eAAe;AAC5C,SAAK,SAAS,QAAQ;AAEtB,SAAK,eAAe;AACpB,SAAK,eAAe;AACpB,SAAK,UAAU,QAAQ;AAAA,EACzB;AACF;;;AGjiBA,IAAAC,oBAAiC;AAW1B,SAAS,SAAS,MAAsB;AAC7C,SAAO,CAAC,CAAC,KAAK,gBAAgB,EAAE,UAAU;AAC5C;AAEO,SAAS,oBACd,OACA,QACiC;AACjC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;;;ACvBA,IAAAC,gBAA0B;AAE1B,IAAAC,gBAA2B;AAC3B,IAAAC,oBAAiC;AAEjC,IAAAC,eAAwE;AAUjE,SAAS,mBAA4B,MAAqC;AAC/E,QAAM,YAAY,KAAK,QAAQ,kCAAgB,EAAE,aAA0B;AAC3E,QAAM,cAAU,0BAAW;AAE3B,+BAAU,MAAM;AACd,UAAM,aAAa,UAAU,iBAAiB,mBAAmB,MAAM;AACrE,cAAQ;AAAA,IACV,CAAC;AACD,WAAO,MAAM,YAAY,QAAQ;AAAA,EACnC,GAAG,CAAC,UAAU,eAAe,CAAC;AAE9B,SAAO,UAAU,UAAa;AAChC;AAOO,SAAS,oBAA6B,MAAsB,MAA6B;AAC9F,QAAM,YAAY,KAAK,QAAQ,kCAAgB,EAAE,aAA0B;AAC3E,QAAM,cAAU,0BAAW;AAE3B,+BAAU,MAAM;AACd,UAAM,aAAa,UAAU,iBAAiB,mBAAmB,CAAC,EAAE,MAAM,YAAY,MAAM;AAC1F,UAAI,SAAS,aAAa;AACxB,gBAAQ;AAAA,MACV;AAAA,IACF,CAAC;AAED,WAAO,MAAM,YAAY,QAAQ;AAAA,EACnC,GAAG,CAAC,CAAC;AAEL,SAAO,UAAU,WAAc,IAAI;AACrC;AAOO,SAAS,wBAAwB,MAAsB;AAC5D,QAAM,YAAY,KAAK,QAAQ,kCAAgB,EAAE,aAA0B;AAC3E,QAAM,cAAU,0BAAW;AAE3B,+BAAU,MAAM;AACd,UAAM,aAAa,UAAU,cAAc,MAAM;AAC/C,cAAQ;AAAA,IACV,CAAC;AACD,WAAO,MAAM,WAAW,QAAQ;AAAA,EAClC,GAAG,CAAC,SAAS,CAAC;AAEd,SAAO;AACT;AAOO,SAAS,kBAAkB,MAA6C;AAC7E,QAAM,YAAY,wBAAwB,IAAI;AAC9C,aAAO,2BAAa,UAAU,WAAW;AAC3C;AAOO,SAAS,mBAAmB,MAA0C;AAC3E,QAAM,YAAY,wBAAwB,IAAI;AAC9C,aAAO,4BAAc,UAAU,WAAW;AAC5C;AAOO,SAAS,qBAAqB,MAA4C;AAC/E,QAAM,YAAY,wBAAwB,IAAI;AAC9C,aAAO,8BAAgB,UAAU,WAAW;AAC9C;;;AClGA,oBAAuB;AAgChB,IAAM,aAAN,MAAmD;AAAA,EAWxD,YAAY,QAA0B,MAAa;AACjD,SAAK,OAAO,QAAQ,QAAQ;AAC5B,SAAK,WAAW,GAAG,KAAK,IAAI,SAAK,sBAAO,CAAC;AACzC,SAAK,SAAS;AAEd,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,IAAI,YAAyB;AAC3B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,MAAM;AACR,WAAO;AAAA,MACL,WAAW,KAAK;AAAA,MAChB,MAAM,KAAK,UAAU,YAAY;AAAA,MACjC,mBAAmB,KAAK,UAAU,YAAY;AAAA,IAChD;AAAA,EACF;AAAA,EAEA,cAAc,UAAoB,aAAwC;AACxE,UAAM,eAAyB;AAAA,MAC7B,GAAG;AAAA,IACL;AAEA,SAAK,OAAO;AAAA,MACV;AAAA,QACE,aAAa,CAAC,WAAW;AACvB,uBAAa,SAAS;AAAA,YACpB,GAAI,aAAa,UAAU,CAAC;AAAA,YAC5B,GAAG;AAAA,UACL;AAAA,QACF;AAAA,QACA,eAAe,CAAC,aAAa;AAC3B,uBAAa,WAAW;AAAA,YACtB,GAAI,aAAa,YAAY,CAAC;AAAA,YAC9B,GAAG;AAAA,UACL;AAAA,QACF;AAAA,QACA,iBAAiB,CAAC,iBAAiB;AACjC,cAAI,CAAC,aAAa,cAAc;AAC9B,yBAAa,eAAe;AAC5B;AAAA,UACF;AACA,gBAAM,qBAAqB,aAAa;AACxC,uBAAa,eAAe,CAAC,GAAG,MAAM,eAAe,mBAAmB,GAAG,CAAC,GAAG,CAAC;AAAA,QAClF;AAAA,QACA,mBAAmB,CAAC,mBAAmB;AACrC,cAAI,CAAC,aAAa,gBAAgB;AAChC,yBAAa,iBAAiB;AAC9B;AAAA,UACF;AACA,gBAAM,uBAAuB,aAAa;AAC1C,uBAAa,iBAAiB,CAAC,GAAG,MAAM,iBAAiB,qBAAqB,GAAG,CAAC,GAAG,CAAC;AAAA,QACxF;AAAA,QACA,GAAG;AAAA,MACL;AAAA,MACA,KAAK;AAAA,IACP;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,KAAK,WAAwB;AAC3B,SAAK,aAAa;AAClB,SAAK,QAAQ,SAAS,KAAK,KAAK,KAAK,IAAI;AAAA,EAC3C;AAAA,EAEA,UAAU;AACR,QAAI,KAAK,QAAQ,WAAW;AAC1B,WAAK,QAAQ,UAAU,KAAK,KAAK,KAAK,IAAI;AAAA,IAC5C;AAAA,EACF;AACF;AAIO,SAAS,wBAA8B,QAAmD;AAC/F,SAAO,SAAU,MAAY;AAC3B,WAAO,IAAI,WAAW,QAAQ,IAAI;AAAA,EACpC;AACF;;;AC5HA,IAAAC,gBAAkB;AAGlB,IAAAC,oBAAwE;AAiEjE,SAAS,YACd,MACoC;AACpC,QAAM,YAAY,KAAK,QAA0B,kCAAgB,GAAG,aAA0B;AAC9F,QAAM,kBAAkB,WAAW;AAEnC,MAAI,CAAC,aAAa,CAAC,gBAAiB,QAAO;AAE3C,QAAM,SAAiC;AAAA,IACrC,eAAe,gBAAgB;AAAA,IAC/B,IAAI,SAAS;AACX,aAAO,gBAAgB;AAAA,IACzB;AAAA,IAEA,OAAO,gBAAgB;AAAA,IACvB,YAAY,CAAC,SAAoB,gBAAgB,WAAW,IAAI;AAAA,IAChE,YAAY,CAAC,MAAiB,UAAe,gBAAgB,WAAW,MAAM,KAAK;AAAA,IACnF,kBAAkB,CAAC,WAAgB;AACjC,gBAAU,iBAAiB,MAAM;AAAA,IACnC;AAAA,IACA,QAAQ,MAAM,8BAAAC,QAAA,cAAC,gCAAW,MAAY;AAAA,IACtC,oBAAoB,UAAU,mBAAmB,KAAK,SAAS;AAAA,IAC/D,qBAAqB,UAAU,oBAAoB,KAAK,SAAS;AAAA,IACjE,YAAY,UAAU,gBAAgB;AAAA,IACtC,UAAU,UAAU,SAAS,KAAK,SAAS;AAAA,EAC7C;AAEA,SAAO,eAAe,QAAQ,cAAc;AAAA,IAC1C,YAAY;AAAA,IACZ,MAAM;AACJ,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AACD,SAAO;AACT;","names":["DataEvent","import_lodash","import_form_core","import_form","React","effect","import_form_core","import_react","import_utils","import_form_core","import_form","import_react","import_form_core","React"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flowgram.ai/node",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.17",
|
|
4
4
|
"description": "automation form core",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"flow",
|
|
@@ -25,11 +25,11 @@
|
|
|
25
25
|
"lodash": "^4.17.21",
|
|
26
26
|
"nanoid": "^4.0.2",
|
|
27
27
|
"reflect-metadata": "~0.2.2",
|
|
28
|
-
"@flowgram.ai/
|
|
29
|
-
"@flowgram.ai/
|
|
30
|
-
"@flowgram.ai/
|
|
31
|
-
"@flowgram.ai/utils": "0.2.
|
|
32
|
-
"@flowgram.ai/
|
|
28
|
+
"@flowgram.ai/form": "0.2.17",
|
|
29
|
+
"@flowgram.ai/document": "0.2.17",
|
|
30
|
+
"@flowgram.ai/form-core": "0.2.17",
|
|
31
|
+
"@flowgram.ai/utils": "0.2.17",
|
|
32
|
+
"@flowgram.ai/core": "0.2.17"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@types/lodash": "^4.14.137",
|
|
@@ -40,9 +40,9 @@
|
|
|
40
40
|
"tsup": "^8.0.1",
|
|
41
41
|
"typescript": "^5.0.4",
|
|
42
42
|
"vitest": "^0.34.6",
|
|
43
|
-
"@flowgram.ai/eslint-config": "0.2.
|
|
44
|
-
"@flowgram.ai/form": "0.2.
|
|
45
|
-
"@flowgram.ai/ts-config": "0.2.
|
|
43
|
+
"@flowgram.ai/eslint-config": "0.2.17",
|
|
44
|
+
"@flowgram.ai/form": "0.2.17",
|
|
45
|
+
"@flowgram.ai/ts-config": "0.2.17"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"react": ">=16.8",
|