@nocobase/plugin-flow-engine 2.1.0-beta.20 → 2.1.0-beta.22

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.
Files changed (37) hide show
  1. package/dist/externalVersion.js +10 -10
  2. package/dist/node_modules/ses/package.json +1 -1
  3. package/dist/node_modules/zod/package.json +1 -1
  4. package/dist/server/flow-surfaces/apply/compiler.js +4 -2
  5. package/dist/server/flow-surfaces/association-interfaces.d.ts +10 -0
  6. package/dist/server/flow-surfaces/association-interfaces.js +39 -0
  7. package/dist/server/flow-surfaces/blueprint/compile-blocks.js +108 -6
  8. package/dist/server/flow-surfaces/blueprint/public-types.d.ts +9 -1
  9. package/dist/server/flow-surfaces/builder.d.ts +27 -1
  10. package/dist/server/flow-surfaces/builder.js +54 -4
  11. package/dist/server/flow-surfaces/catalog.d.ts +1 -0
  12. package/dist/server/flow-surfaces/catalog.js +146 -36
  13. package/dist/server/flow-surfaces/compose-compiler.d.ts +9 -1
  14. package/dist/server/flow-surfaces/compose-compiler.js +8 -0
  15. package/dist/server/flow-surfaces/compose-runtime.d.ts +1 -0
  16. package/dist/server/flow-surfaces/compose-runtime.js +2 -1
  17. package/dist/server/flow-surfaces/configure-options.js +50 -6
  18. package/dist/server/flow-surfaces/default-action-popup.js +2 -2
  19. package/dist/server/flow-surfaces/field-binding-registry.d.ts +1 -0
  20. package/dist/server/flow-surfaces/field-binding-registry.js +6 -1
  21. package/dist/server/flow-surfaces/field-semantics.d.ts +1 -1
  22. package/dist/server/flow-surfaces/field-semantics.js +4 -3
  23. package/dist/server/flow-surfaces/field-type-resolver.d.ts +46 -0
  24. package/dist/server/flow-surfaces/field-type-resolver.js +322 -0
  25. package/dist/server/flow-surfaces/node-use-sets.js +1 -0
  26. package/dist/server/flow-surfaces/service-helpers.js +2 -2
  27. package/dist/server/flow-surfaces/service-utils.d.ts +14 -1
  28. package/dist/server/flow-surfaces/service-utils.js +79 -6
  29. package/dist/server/flow-surfaces/service.d.ts +28 -4
  30. package/dist/server/flow-surfaces/service.js +1158 -116
  31. package/dist/server/flow-surfaces/support-matrix.js +11 -0
  32. package/dist/swagger/flow-surfaces.d.ts +173 -2
  33. package/dist/swagger/flow-surfaces.examples.d.ts +20 -15
  34. package/dist/swagger/flow-surfaces.examples.js +22 -11
  35. package/dist/swagger/flow-surfaces.js +72 -10
  36. package/dist/swagger/index.d.ts +173 -2
  37. package/package.json +2 -2
@@ -57,6 +57,7 @@ var import_errors = require("./errors");
57
57
  var import_field_semantics = require("./field-semantics");
58
58
  var import_core_field_default_bindings = require("./core-field-default-bindings");
59
59
  var import_field_binding_registry = require("./field-binding-registry");
60
+ var import_association_interfaces = require("./association-interfaces");
60
61
  var import_service_helpers = require("./service-helpers");
61
62
  var import_support_matrix = require("./support-matrix");
62
63
  const ANY_VALUE_SCHEMA = {};
@@ -71,6 +72,10 @@ const OPEN_VIEW_SCENE_SCHEMA = {
71
72
  const OBJECT_SCHEMA = { type: "object" };
72
73
  const NUMBER_SCHEMA = { type: "number" };
73
74
  const ARRAY_SCHEMA = { type: "array" };
75
+ const BLOCK_HEIGHT_MODE_SCHEMA = {
76
+ type: "string",
77
+ enum: ["defaultHeight", "specifyValue", "fullHeight"]
78
+ };
74
79
  const NULLABLE_NUMBER_OR_STRING_SCHEMA = {
75
80
  oneOf: [NUMBER_SCHEMA, NULLABLE_STRING_SCHEMA]
76
81
  };
@@ -294,13 +299,21 @@ const FILTER_FORM_BLOCK_SETTINGS_GROUP = {
294
299
  }
295
300
  };
296
301
  const BLOCK_CARD_SETTINGS_GROUP = {
297
- allowedPaths: ["titleDescription.title", "titleDescription.description", "linkageRules"],
302
+ allowedPaths: [
303
+ "titleDescription.title",
304
+ "titleDescription.description",
305
+ "blockHeight.heightMode",
306
+ "blockHeight.height",
307
+ "linkageRules"
308
+ ],
298
309
  clearable: true,
299
310
  mergeStrategy: "deep",
300
- eventBindingSteps: ["titleDescription", "linkageRules"],
311
+ eventBindingSteps: ["titleDescription", "blockHeight", "linkageRules"],
301
312
  pathSchemas: {
302
313
  "titleDescription.title": STRING_SCHEMA,
303
314
  "titleDescription.description": STRING_SCHEMA,
315
+ "blockHeight.heightMode": BLOCK_HEIGHT_MODE_SCHEMA,
316
+ "blockHeight.height": NUMBER_SCHEMA,
304
317
  linkageRules: ARRAY_SCHEMA
305
318
  }
306
319
  };
@@ -333,6 +346,36 @@ const CALENDAR_SETTINGS_GROUP = {
333
346
  "linkageRules.value": ARRAY_SCHEMA
334
347
  }
335
348
  };
349
+ const TREE_BLOCK_PROP_SCHEMAS = {
350
+ searchable: BOOLEAN_SCHEMA,
351
+ defaultExpandAll: BOOLEAN_SCHEMA,
352
+ includeDescendants: BOOLEAN_SCHEMA,
353
+ fieldNames: OBJECT_SCHEMA,
354
+ pageSize: NUMBER_SCHEMA
355
+ };
356
+ const TREE_SETTINGS_GROUP = {
357
+ allowedPaths: [
358
+ "searchable.searchable",
359
+ "defaultExpandAll.defaultExpandAll",
360
+ "includeDescendants.includeDescendants",
361
+ "titleField.titleField",
362
+ "pageSize.pageSize",
363
+ "dataScope.filter",
364
+ "defaultSorting.sort"
365
+ ],
366
+ clearable: true,
367
+ mergeStrategy: "deep",
368
+ eventBindingSteps: ["treeSettings", "dataScope", "defaultSorting"],
369
+ pathSchemas: {
370
+ "searchable.searchable": BOOLEAN_SCHEMA,
371
+ "defaultExpandAll.defaultExpandAll": BOOLEAN_SCHEMA,
372
+ "includeDescendants.includeDescendants": BOOLEAN_SCHEMA,
373
+ "titleField.titleField": STRING_SCHEMA,
374
+ "pageSize.pageSize": NUMBER_SCHEMA,
375
+ "dataScope.filter": FILTER_GROUP_SCHEMA,
376
+ "defaultSorting.sort": ARRAY_SCHEMA
377
+ }
378
+ };
336
379
  const KANBAN_SETTINGS_GROUP = {
337
380
  allowedPaths: [
338
381
  "grouping.groupField",
@@ -426,6 +469,7 @@ const REGISTERED_FILTER_FIELD_USE_SET = (0, import_field_binding_registry.getReg
426
469
  const EDITABLE_FIELD_USE_SET = /* @__PURE__ */ new Set([
427
470
  ...JS_EDITABLE_FIELD_USE_SET,
428
471
  "RecordSelectFieldModel",
472
+ "RecordPickerFieldModel",
429
473
  "JsonFieldModel",
430
474
  "TextareaFieldModel",
431
475
  "IconFieldModel",
@@ -443,11 +487,15 @@ const EDITABLE_FIELD_USE_SET = /* @__PURE__ */ new Set([
443
487
  "TimeFieldModel",
444
488
  "CollectionSelectorFieldModel",
445
489
  "RichTextFieldModel",
446
- "InputFieldModel"
490
+ "InputFieldModel",
491
+ "SubFormListFieldModel",
492
+ "SubTableFieldModel",
493
+ "PopupSubTableFieldModel"
447
494
  ]);
448
495
  const DISPLAY_FIELD_USE_SET = /* @__PURE__ */ new Set([
449
496
  ...JS_DISPLAY_FIELD_USE_SET,
450
497
  "DisplaySubItemFieldModel",
498
+ "DisplaySubListFieldModel",
451
499
  "DisplaySubTableFieldModel",
452
500
  "DisplayHtmlFieldModel",
453
501
  "DisplayNumberFieldModel",
@@ -479,7 +527,6 @@ const APPROVAL_DETAILS_FIELD_COMPONENT_WRAPPER_USE_SET = /* @__PURE__ */ new Set
479
527
  "ApplyTaskCardDetailsItemModel",
480
528
  "ApprovalTaskCardDetailsItemModel"
481
529
  ]);
482
- const SINGLE_VALUE_ASSOCIATION_INTERFACES = /* @__PURE__ */ new Set(["m2o", "o2o", "oho", "obo", "updatedBy", "createdBy"]);
483
530
  const KNOWN_FIELD_NODE_USES = /* @__PURE__ */ new Set([
484
531
  ...EDITABLE_FIELD_USE_SET,
485
532
  ...DISPLAY_FIELD_USE_SET,
@@ -798,8 +845,6 @@ TAB_NODE_CONTRACT.domains.stepParams = groupedDomain({
798
845
  });
799
846
  const TABLE_BLOCK_CONTRACT = createContract({
800
847
  editableDomains: ["props", "decoratorProps", "stepParams", "flowRegistry"],
801
- props: ["height", "heightMode"],
802
- decoratorProps: ["height", "heightMode"],
803
848
  stepParams: ["resourceSettings", "tableSettings", "cardSettings"],
804
849
  flowRegistry: true,
805
850
  eventCapabilities: {
@@ -907,7 +952,6 @@ const CALENDAR_BLOCK_CONTRACT = createContract({
907
952
  "quickCreatePopupSettings",
908
953
  "eventPopupSettings"
909
954
  ],
910
- decoratorProps: ["height", "heightMode"],
911
955
  stepParams: ["resourceSettings", "calendarSettings", "cardSettings"],
912
956
  flowRegistry: true,
913
957
  eventCapabilities: {
@@ -920,6 +964,26 @@ CALENDAR_BLOCK_CONTRACT.domains.stepParams = groupedDomain({
920
964
  calendarSettings: CALENDAR_SETTINGS_GROUP,
921
965
  cardSettings: BLOCK_CARD_SETTINGS_GROUP
922
966
  });
967
+ const TREE_BLOCK_CONTRACT = createContract({
968
+ editableDomains: ["props", "decoratorProps", "stepParams", "flowRegistry"],
969
+ props: ["searchable", "defaultExpandAll", "includeDescendants", "fieldNames", "pageSize"],
970
+ stepParams: ["resourceSettings", "treeSettings", "cardSettings"],
971
+ flowRegistry: true,
972
+ eventCapabilities: {
973
+ direct: DEFAULT_DIRECT_EVENTS,
974
+ object: ["click"]
975
+ }
976
+ });
977
+ TREE_BLOCK_CONTRACT.domains.props = keyedDomain(
978
+ ["searchable", "defaultExpandAll", "includeDescendants", "fieldNames", "pageSize"],
979
+ "deep",
980
+ TREE_BLOCK_PROP_SCHEMAS
981
+ );
982
+ TREE_BLOCK_CONTRACT.domains.stepParams = groupedDomain({
983
+ resourceSettings: RESOURCE_SETTINGS_GROUP,
984
+ treeSettings: TREE_SETTINGS_GROUP,
985
+ cardSettings: BLOCK_CARD_SETTINGS_GROUP
986
+ });
923
987
  const KANBAN_BLOCK_CONTRACT = createContract({
924
988
  editableDomains: ["props", "decoratorProps", "stepParams", "flowRegistry"],
925
989
  props: [
@@ -941,7 +1005,6 @@ const KANBAN_BLOCK_CONTRACT = createContract({
941
1005
  "pageSize",
942
1006
  "columnWidth"
943
1007
  ],
944
- decoratorProps: ["height", "heightMode"],
945
1008
  stepParams: ["resourceSettings", "kanbanSettings", "cardSettings"],
946
1009
  flowRegistry: true,
947
1010
  eventCapabilities: {
@@ -957,7 +1020,6 @@ KANBAN_BLOCK_CONTRACT.domains.stepParams = groupedDomain({
957
1020
  const LIST_BLOCK_CONTRACT = createContract({
958
1021
  editableDomains: ["props", "decoratorProps", "stepParams", "flowRegistry"],
959
1022
  props: [],
960
- decoratorProps: ["height", "heightMode"],
961
1023
  stepParams: ["resourceSettings", "listSettings", "cardSettings"],
962
1024
  flowRegistry: true,
963
1025
  eventCapabilities: {
@@ -997,7 +1059,6 @@ LIST_BLOCK_CONTRACT.domains.stepParams = groupedDomain({
997
1059
  const GRID_CARD_BLOCK_CONTRACT = createContract({
998
1060
  editableDomains: ["props", "decoratorProps", "stepParams", "flowRegistry"],
999
1061
  props: [],
1000
- decoratorProps: ["height", "heightMode"],
1001
1062
  stepParams: ["resourceSettings", "GridCardSettings", "cardSettings"],
1002
1063
  flowRegistry: true,
1003
1064
  eventCapabilities: {
@@ -1161,22 +1222,12 @@ IFRAME_BLOCK_CONTRACT.domains.stepParams = groupedDomain({
1161
1222
  }
1162
1223
  });
1163
1224
  const CHART_CARD_SETTINGS_GROUP = {
1164
- allowedPaths: [
1165
- "titleDescription.title",
1166
- "titleDescription.description",
1167
- "blockHeight.heightMode",
1168
- "blockHeight.height",
1169
- "linkageRules"
1170
- ],
1225
+ allowedPaths: BLOCK_CARD_SETTINGS_GROUP.allowedPaths,
1171
1226
  clearable: true,
1172
1227
  mergeStrategy: "deep",
1173
- eventBindingSteps: ["titleDescription", "blockHeight", "linkageRules"],
1228
+ eventBindingSteps: BLOCK_CARD_SETTINGS_GROUP.eventBindingSteps,
1174
1229
  pathSchemas: {
1175
- "titleDescription.title": STRING_SCHEMA,
1176
- "titleDescription.description": STRING_SCHEMA,
1177
- "blockHeight.heightMode": STRING_SCHEMA,
1178
- "blockHeight.height": NUMBER_SCHEMA,
1179
- linkageRules: ARRAY_SCHEMA
1230
+ ...BLOCK_CARD_SETTINGS_GROUP.pathSchemas
1180
1231
  }
1181
1232
  };
1182
1233
  const CHART_BLOCK_CONTRACT = createContract({
@@ -1238,8 +1289,7 @@ JS_BLOCK_CONTRACT.domains.stepParams = groupedDomain({
1238
1289
  });
1239
1290
  const MAP_BLOCK_CONTRACT = createContract({
1240
1291
  editableDomains: ["props", "decoratorProps", "stepParams", "flowRegistry"],
1241
- props: ["height", "heightMode", "mapField", "marker", "lineSort", "zoom"],
1242
- decoratorProps: ["height", "heightMode"],
1292
+ props: ["mapField", "marker", "lineSort", "zoom"],
1243
1293
  stepParams: ["resourceSettings", "createMapBlock", "cardSettings"],
1244
1294
  flowRegistry: true,
1245
1295
  eventCapabilities: {
@@ -2385,6 +2435,7 @@ const NODE_CONTRACT_ENTRIES = [
2385
2435
  ["ApprovalBlockGridModel", GRID_NODE_CONTRACT],
2386
2436
  ["TableBlockModel", TABLE_BLOCK_CONTRACT],
2387
2437
  ["CalendarBlockModel", CALENDAR_BLOCK_CONTRACT],
2438
+ ["TreeBlockModel", TREE_BLOCK_CONTRACT],
2388
2439
  ["KanbanBlockModel", KANBAN_BLOCK_CONTRACT],
2389
2440
  ["CreateFormModel", CREATE_FORM_BLOCK_CONTRACT],
2390
2441
  ["EditFormModel", EDIT_FORM_BLOCK_CONTRACT],
@@ -2544,7 +2595,7 @@ function getAllowedFieldUseSet(containerUse, enabledPackages) {
2544
2595
  return null;
2545
2596
  }
2546
2597
  }
2547
- function canUseNestedApprovalAssociationFieldComponent(input) {
2598
+ function canUseNestedAssociationFieldComponent(input) {
2548
2599
  var _a;
2549
2600
  const getCollection = input.getCollection || (() => null);
2550
2601
  const targetCollection = (0, import_service_helpers.resolveFieldTargetCollection)(input.field, input.dataSourceKey || "main", getCollection);
@@ -2559,40 +2610,65 @@ function getSupportedFieldComponentUseSet(input) {
2559
2610
  if (!baseAllowedFieldUses || !fieldInterface) {
2560
2611
  return baseAllowedFieldUses;
2561
2612
  }
2562
- const wrapperUse = (0, import_approval.getApprovalFieldWrapperUse)(input.containerUse) || String(input.containerUse || "").trim();
2613
+ const wrapperUse = (0, import_approval.getApprovalFieldWrapperUse)(input.containerUse) || getFieldWrapperUseForContainer(input.containerUse) || String(input.containerUse || "").trim();
2563
2614
  const inferredFieldUse = inferFieldUseByContainer(input.containerUse, input.field, {
2564
2615
  enabledPackages: input.enabledPackages,
2565
2616
  dataSourceKey: input.dataSourceKey,
2566
2617
  getCollection: input.getCollection
2567
2618
  });
2568
2619
  if (wrapperUse === "PatternFormItemModel") {
2569
- if (SINGLE_VALUE_ASSOCIATION_INTERFACES.has(fieldInterface)) {
2620
+ if (import_association_interfaces.SINGLE_VALUE_ASSOCIATION_INTERFACES.has(fieldInterface)) {
2621
+ return new Set(
2622
+ [
2623
+ "RecordSelectFieldModel",
2624
+ "RecordPickerFieldModel",
2625
+ canUseNestedAssociationFieldComponent(input) ? "SubFormFieldModel" : void 0,
2626
+ inferredFieldUse
2627
+ ].filter(Boolean)
2628
+ );
2629
+ }
2630
+ if (import_association_interfaces.MULTI_VALUE_ASSOCIATION_INTERFACES.has(fieldInterface)) {
2631
+ return new Set(
2632
+ [
2633
+ "RecordSelectFieldModel",
2634
+ "RecordPickerFieldModel",
2635
+ canUseNestedAssociationFieldComponent(input) ? "SubFormListFieldModel" : void 0,
2636
+ canUseNestedAssociationFieldComponent(input) ? "SubTableFieldModel" : void 0,
2637
+ canUseNestedAssociationFieldComponent(input) ? "PopupSubTableFieldModel" : void 0,
2638
+ inferredFieldUse
2639
+ ].filter(Boolean)
2640
+ );
2641
+ }
2642
+ }
2643
+ if (wrapperUse === "FormItemModel") {
2644
+ if (import_association_interfaces.SINGLE_VALUE_ASSOCIATION_INTERFACES.has(fieldInterface)) {
2570
2645
  return new Set(
2571
2646
  [
2572
2647
  "RecordSelectFieldModel",
2573
2648
  "RecordPickerFieldModel",
2574
- canUseNestedApprovalAssociationFieldComponent(input) ? "SubFormFieldModel" : void 0,
2649
+ canUseNestedAssociationFieldComponent(input) ? "SubFormFieldModel" : void 0,
2575
2650
  inferredFieldUse
2576
2651
  ].filter(Boolean)
2577
2652
  );
2578
2653
  }
2579
- if (import_field_semantics.MULTI_VALUE_ASSOCIATION_INTERFACES.has(fieldInterface)) {
2654
+ if (import_association_interfaces.MULTI_VALUE_ASSOCIATION_INTERFACES.has(fieldInterface)) {
2580
2655
  return new Set(
2581
2656
  [
2582
2657
  "RecordSelectFieldModel",
2583
2658
  "RecordPickerFieldModel",
2584
- canUseNestedApprovalAssociationFieldComponent(input) ? "SubFormListFieldModel" : void 0,
2585
- canUseNestedApprovalAssociationFieldComponent(input) ? "PatternSubTableFieldModel" : void 0,
2659
+ canUseNestedAssociationFieldComponent(input) ? "SubFormListFieldModel" : void 0,
2660
+ canUseNestedAssociationFieldComponent(input) ? "SubTableFieldModel" : void 0,
2661
+ canUseNestedAssociationFieldComponent(input) ? "PopupSubTableFieldModel" : void 0,
2586
2662
  inferredFieldUse
2587
2663
  ].filter(Boolean)
2588
2664
  );
2589
2665
  }
2590
2666
  }
2591
2667
  if (APPROVAL_DETAILS_FIELD_COMPONENT_WRAPPER_USE_SET.has(wrapperUse)) {
2592
- if (SINGLE_VALUE_ASSOCIATION_INTERFACES.has(fieldInterface)) {
2668
+ if (import_association_interfaces.SINGLE_VALUE_ASSOCIATION_INTERFACES.has(fieldInterface)) {
2593
2669
  return new Set(["DisplayTextFieldModel", "DisplaySubItemFieldModel", inferredFieldUse].filter(Boolean));
2594
2670
  }
2595
- if (import_field_semantics.MULTI_VALUE_ASSOCIATION_INTERFACES.has(fieldInterface)) {
2671
+ if (import_association_interfaces.MULTI_VALUE_ASSOCIATION_INTERFACES.has(fieldInterface)) {
2596
2672
  return new Set(
2597
2673
  ["DisplayTextFieldModel", "DisplaySubListFieldModel", "DisplaySubTableFieldModel", inferredFieldUse].filter(
2598
2674
  Boolean
@@ -2600,6 +2676,33 @@ function getSupportedFieldComponentUseSet(input) {
2600
2676
  );
2601
2677
  }
2602
2678
  }
2679
+ if (wrapperUse === "DetailsItemModel") {
2680
+ if (import_association_interfaces.SINGLE_VALUE_ASSOCIATION_INTERFACES.has(fieldInterface)) {
2681
+ return new Set(["DisplayTextFieldModel", "DisplaySubItemFieldModel", inferredFieldUse].filter(Boolean));
2682
+ }
2683
+ if (import_association_interfaces.MULTI_VALUE_ASSOCIATION_INTERFACES.has(fieldInterface)) {
2684
+ return new Set(
2685
+ ["DisplayTextFieldModel", "DisplaySubListFieldModel", "DisplaySubTableFieldModel", inferredFieldUse].filter(
2686
+ Boolean
2687
+ )
2688
+ );
2689
+ }
2690
+ }
2691
+ if (wrapperUse === "FormAssociationItemModel" || wrapperUse === "TableColumnModel") {
2692
+ if (import_association_interfaces.SINGLE_VALUE_ASSOCIATION_INTERFACES.has(fieldInterface)) {
2693
+ return new Set(["DisplayTextFieldModel", inferredFieldUse].filter(Boolean));
2694
+ }
2695
+ if (import_association_interfaces.MULTI_VALUE_ASSOCIATION_INTERFACES.has(fieldInterface)) {
2696
+ return new Set(
2697
+ ["DisplayTextFieldModel", "DisplaySubListFieldModel", "DisplaySubTableFieldModel", inferredFieldUse].filter(
2698
+ Boolean
2699
+ )
2700
+ );
2701
+ }
2702
+ }
2703
+ if (inferredFieldUse) {
2704
+ return /* @__PURE__ */ new Set([inferredFieldUse]);
2705
+ }
2603
2706
  return baseAllowedFieldUses;
2604
2707
  }
2605
2708
  function inferFieldUseByContainer(containerUse, field, options = {}) {
@@ -2737,12 +2840,18 @@ function resolveSupportedFieldCapability(input) {
2737
2840
  }
2738
2841
  throw new import_errors.FlowSurfaceBadRequestError(`flowSurfaces field '${input.containerUse}' requires a supported fieldUse`);
2739
2842
  }
2740
- if (input.requestedFieldUse && inferredFieldUse && input.requestedFieldUse !== inferredFieldUse && KNOWN_FIELD_NODE_USES.has(input.requestedFieldUse)) {
2843
+ if (input.requestedFieldUse && inferredFieldUse && input.requestedFieldUse !== inferredFieldUse && input.requestedFieldUseMode !== "fieldType" && KNOWN_FIELD_NODE_USES.has(input.requestedFieldUse)) {
2741
2844
  throw new import_errors.FlowSurfaceBadRequestError(
2742
2845
  `flowSurfaces fieldUse '${input.requestedFieldUse}' does not match inferred fieldUse '${inferredFieldUse}' under '${input.containerUse}'`
2743
2846
  );
2744
2847
  }
2745
- const allowedFieldUses = getAllowedFieldUseSet(input.containerUse, input.enabledPackages);
2848
+ const allowedFieldUses = input.requestedFieldUseMode === "fieldType" && input.field ? getSupportedFieldComponentUseSet({
2849
+ containerUse: input.containerUse,
2850
+ field: input.field,
2851
+ enabledPackages: input.enabledPackages,
2852
+ dataSourceKey: input.dataSourceKey,
2853
+ getCollection: input.getCollection
2854
+ }) : getAllowedFieldUseSet(input.containerUse, input.enabledPackages);
2746
2855
  if (!(allowedFieldUses == null ? void 0 : allowedFieldUses.has(fieldUse))) {
2747
2856
  throw new import_errors.FlowSurfaceBadRequestError(
2748
2857
  `flowSurfaces fieldUse '${fieldUse}' is not allowed under '${input.containerUse}'`
@@ -2810,6 +2919,7 @@ function getAvailableActionCatalogItems(containerUse, scope, enabledPackages) {
2810
2919
  const COLLECTION_RESOURCE_REQUIRED = /* @__PURE__ */ new Set([
2811
2920
  "TableBlockModel",
2812
2921
  "CalendarBlockModel",
2922
+ "TreeBlockModel",
2813
2923
  "KanbanBlockModel",
2814
2924
  "CreateFormModel",
2815
2925
  "EditFormModel",
@@ -23,6 +23,14 @@ export type FlowSurfaceComposeNormalizedFieldSpec = {
23
23
  associationPathName?: string;
24
24
  renderer?: string;
25
25
  type?: string;
26
+ fieldType?: string;
27
+ fields?: string[];
28
+ selectorFields?: string[];
29
+ titleField?: string;
30
+ openMode?: string;
31
+ popupSize?: string;
32
+ pageSize?: number;
33
+ showIndex?: boolean;
26
34
  target?: string | Record<string, unknown>;
27
35
  settings?: FlowSurfaceComposeObject;
28
36
  popup?: FlowSurfaceComposeObject;
@@ -105,4 +113,4 @@ export declare function compileComposeExecutionPlan(input: {
105
113
  layout?: FlowSurfaceComposeObject;
106
114
  }): FlowSurfaceCompiledComposePlan;
107
115
  export declare function resolveComposeFieldContainerSource(blockSpec: Pick<FlowSurfaceComposeNormalizedBlockSpec, 'type'>): 'block' | 'item';
108
- export declare function resolveComposeTargetKey(targetKey: string, keyMap: Record<string, FlowSurfaceComposeTargetKey | undefined>, kind: 'field' | 'layout'): string;
116
+ export declare function resolveComposeTargetKey(targetKey: string, keyMap: Record<string, FlowSurfaceComposeTargetKey | undefined>, kind: 'field' | 'layout' | 'tree connectFields'): string;
@@ -123,6 +123,14 @@ function buildComposeFieldCreatePayload(fieldSpec) {
123
123
  ...fieldSpec.associationPathName ? { associationPathName: fieldSpec.associationPathName } : {},
124
124
  ...fieldSpec.renderer ? { renderer: fieldSpec.renderer } : {},
125
125
  ...fieldSpec.type ? { type: fieldSpec.type } : {},
126
+ ...fieldSpec.fieldType ? { fieldType: fieldSpec.fieldType } : {},
127
+ ...typeof fieldSpec.fields !== "undefined" ? { fields: fieldSpec.fields } : {},
128
+ ...typeof fieldSpec.selectorFields !== "undefined" ? { selectorFields: fieldSpec.selectorFields } : {},
129
+ ...fieldSpec.titleField ? { titleField: fieldSpec.titleField } : {},
130
+ ...fieldSpec.openMode ? { openMode: fieldSpec.openMode } : {},
131
+ ...fieldSpec.popupSize ? { popupSize: fieldSpec.popupSize } : {},
132
+ ...typeof fieldSpec.pageSize !== "undefined" ? { pageSize: fieldSpec.pageSize } : {},
133
+ ...typeof fieldSpec.showIndex !== "undefined" ? { showIndex: fieldSpec.showIndex } : {},
126
134
  ...fieldSpec.popup ? { popup: fieldSpec.popup } : {},
127
135
  ...fieldSpec.__autoPopupForRelationField ? { __autoPopupForRelationField: true } : {},
128
136
  ...fieldSpec[import_defaults.FLOW_SURFACE_APPLY_BLUEPRINT_POPUP_DEFAULTS_KEY] ? {
@@ -66,6 +66,7 @@ export type FlowSurfaceComposeRuntimeDeps = {
66
66
  removeExistingItem?: (uid: string) => Promise<void>;
67
67
  createBlock: (payload: Record<string, unknown>, spec: FlowSurfaceComposeNormalizedBlockSpec) => Promise<FlowSurfaceComposeBlockResult>;
68
68
  applyNodeSettings?: (actionName: string, targetUid: string | undefined, settings?: FlowSurfaceComposeObject) => Promise<void>;
69
+ resolveBlockSettings?: (settings: FlowSurfaceComposeObject, state: FlowSurfaceComposeRuntimeState, block: FlowSurfaceComposeRuntimeBlockState) => FlowSurfaceComposeObject | Promise<FlowSurfaceComposeObject>;
69
70
  createField: (payload: Record<string, unknown>, spec: FlowSurfaceComposeNormalizedFieldSpec, blockResult: FlowSurfaceComposeBlockResult) => Promise<FlowSurfaceComposeFieldResult | null>;
70
71
  applyFieldSettings?: (actionName: string, result: FlowSurfaceComposeFieldResult, settings?: FlowSurfaceComposeObject) => Promise<void>;
71
72
  onFieldError?: (input: {
@@ -142,7 +142,8 @@ async function applyBlockSettings(deps, state) {
142
142
  if (!hasInlineSettings(block.spec.settings)) {
143
143
  continue;
144
144
  }
145
- await applyNodeSettings("compose block", block.result.uid, block.spec.settings);
145
+ const settings = deps.resolveBlockSettings ? await deps.resolveBlockSettings(block.spec.settings || {}, state, block) : block.spec.settings;
146
+ await applyNodeSettings("compose block", block.result.uid, settings);
146
147
  }
147
148
  }
148
149
  async function createFields(plan, deps, state) {
@@ -34,6 +34,7 @@ __export(configure_options_exports, {
34
34
  });
35
35
  module.exports = __toCommonJS(configure_options_exports);
36
36
  var import_approval = require("./approval");
37
+ var import_field_type_resolver = require("./field-type-resolver");
37
38
  const stringOption = (description, extra = {}) => ({
38
39
  type: "string",
39
40
  ...description ? { description } : {},
@@ -79,6 +80,16 @@ const SORTING = arrayOption("Sorting rule array", {
79
80
  }
80
81
  ]
81
82
  });
83
+ const CONNECT_FIELDS = objectOption("Tree connect data block targets", {
84
+ example: {
85
+ targets: [
86
+ {
87
+ targetId: "target-block-uid",
88
+ filterPaths: ["id"]
89
+ }
90
+ ]
91
+ }
92
+ });
82
93
  const OPEN_VIEW = objectOption("Popup or drawer open configuration", {
83
94
  example: {
84
95
  dataSourceKey: "main",
@@ -90,9 +101,25 @@ const DISPLAY_STYLE = stringOption("Display style", {
90
101
  enum: ["text", "tag"],
91
102
  example: "tag"
92
103
  });
93
- const FIELD_COMPONENT = stringOption("Field component model use", {
94
- example: "DisplayTextFieldModel"
104
+ const FIELD_TYPE = stringOption("Public relation field presentation type", {
105
+ enum: [...import_field_type_resolver.FLOW_SURFACE_PUBLIC_RELATION_FIELD_TYPES],
106
+ example: "popupSubTable"
107
+ });
108
+ const RELATION_FIELDS = arrayOption("Relation target fields", {
109
+ example: ["title", "name"]
95
110
  });
111
+ const SELECTOR_FIELDS = arrayOption("Record picker selector fields", {
112
+ example: ["title", "code"]
113
+ });
114
+ const RELATION_FIELD_TYPE_OPTIONS = {
115
+ fieldType: FIELD_TYPE,
116
+ fields: RELATION_FIELDS,
117
+ selectorFields: SELECTOR_FIELDS,
118
+ openMode: stringOption("Popup open mode", { example: "drawer" }),
119
+ popupSize: stringOption("Popup size", { example: "medium" }),
120
+ pageSize: numberOption("Page size", { example: 10 }),
121
+ showIndex: booleanOption("Whether to show index", { example: true })
122
+ };
96
123
  const CONFIRM = objectOption("Confirmation dialog configuration. You can also pass a boolean directly.", {
97
124
  example: {
98
125
  enable: true,
@@ -219,6 +246,20 @@ const CALENDAR_OPTIONS = {
219
246
  quickCreatePopup: OPEN_VIEW,
220
247
  eventPopup: OPEN_VIEW
221
248
  };
249
+ const TREE_OPTIONS = {
250
+ ...COMMON_BLOCK_HEADER_OPTIONS,
251
+ ...COMMON_HEIGHT_OPTIONS,
252
+ resource: COMMON_RESOURCE,
253
+ searchable: booleanOption("Whether search is enabled", { example: true }),
254
+ defaultExpandAll: booleanOption("Whether all tree nodes are expanded by default", { example: false }),
255
+ includeDescendants: booleanOption("Whether child nodes are included when filtering", { example: true }),
256
+ titleField: stringOption("Tree node title field", { example: "title" }),
257
+ fieldNames: objectOption("Tree field names", { example: { title: "title", key: "id", children: "children" } }),
258
+ pageSize: numberOption("Root records per page", { example: 200 }),
259
+ dataScope: FILTER_GROUP,
260
+ sorting: SORTING,
261
+ connectFields: CONNECT_FIELDS
262
+ };
222
263
  const KANBAN_OPTIONS = {
223
264
  ...COMMON_BLOCK_HEADER_OPTIONS,
224
265
  ...COMMON_HEIGHT_OPTIONS,
@@ -386,7 +427,7 @@ const TABLE_FIELD_WRAPPER_OPTIONS = {
386
427
  editable: booleanOption("Whether editable", { example: false }),
387
428
  dataIndex: stringOption("Data index"),
388
429
  titleField: stringOption("Association display title field", { example: "title" }),
389
- fieldComponent: FIELD_COMPONENT,
430
+ ...RELATION_FIELD_TYPE_OPTIONS,
390
431
  clickToOpen: booleanOption("Whether clicking can open details", { example: true }),
391
432
  openView: OPEN_VIEW,
392
433
  code: JS_CODE,
@@ -402,7 +443,7 @@ const DETAILS_FIELD_WRAPPER_OPTIONS = {
402
443
  disabled: booleanOption("Whether disabled", { example: false }),
403
444
  pattern: stringOption("Display mode"),
404
445
  titleField: stringOption("Association display title field", { example: "title" }),
405
- fieldComponent: FIELD_COMPONENT,
446
+ ...RELATION_FIELD_TYPE_OPTIONS,
406
447
  labelWidth: stringOption("Label width", { example: "120px" }),
407
448
  labelWrap: booleanOption("Whether labels should wrap", { example: false }),
408
449
  clickToOpen: booleanOption("Whether clicking can open details", { example: true }),
@@ -422,7 +463,7 @@ const FILTER_FIELD_WRAPPER_OPTIONS = {
422
463
  allowMultiple: booleanOption("Whether multiple selection is allowed", { example: false }),
423
464
  maxCount: numberOption("Maximum count", { example: 5 }),
424
465
  name: stringOption("Field name override"),
425
- fieldComponent: FIELD_COMPONENT,
466
+ ...RELATION_FIELD_TYPE_OPTIONS,
426
467
  labelWidth: stringOption("Label width", { example: "120px" }),
427
468
  labelWrap: booleanOption("Whether labels should wrap", { example: false }),
428
469
  clickToOpen: booleanOption("Whether clicking can open details", { example: false }),
@@ -446,7 +487,7 @@ const FORM_FIELD_WRAPPER_OPTIONS = {
446
487
  pattern: stringOption("Input mode"),
447
488
  titleField: stringOption("Association display title field", { example: "title" }),
448
489
  name: stringOption("Field name override"),
449
- fieldComponent: FIELD_COMPONENT,
490
+ ...RELATION_FIELD_TYPE_OPTIONS,
450
491
  labelWidth: stringOption("Label width", { example: "120px" }),
451
492
  labelWrap: booleanOption("Whether labels should wrap", { example: false }),
452
493
  clickToOpen: booleanOption("Whether clicking can open details", { example: false }),
@@ -744,6 +785,9 @@ function getConfigureOptionsForUse(use) {
744
785
  case "CalendarBlockModel":
745
786
  options = cloneOptions(CALENDAR_OPTIONS);
746
787
  break;
788
+ case "TreeBlockModel":
789
+ options = cloneOptions(TREE_OPTIONS);
790
+ break;
747
791
  case "KanbanBlockModel":
748
792
  options = cloneOptions(KANBAN_OPTIONS);
749
793
  break;
@@ -50,7 +50,7 @@ __export(default_action_popup_exports, {
50
50
  });
51
51
  module.exports = __toCommonJS(default_action_popup_exports);
52
52
  var import_lodash = __toESM(require("lodash"));
53
- var import_field_semantics = require("./field-semantics");
53
+ var import_association_interfaces = require("./association-interfaces");
54
54
  var import_service_helpers = require("./service-helpers");
55
55
  const DEFAULT_ACTION_POPUP_SYSTEM_FIELD_NAMES = /* @__PURE__ */ new Set(["id", "createdBy", "createdById", "updatedBy", "updatedById"]);
56
56
  const DEFAULT_ACTION_POPUP_SYSTEM_FIELD_INTERFACES = /* @__PURE__ */ new Set([
@@ -198,7 +198,7 @@ function isFlowSurfaceDefaultActionPopupAuditTimestampField(field) {
198
198
  }
199
199
  function isFlowSurfaceDefaultActionPopupMultiValueAssociationField(field) {
200
200
  const fieldInterface = String((0, import_service_helpers.getFieldInterface)(field) || "").trim();
201
- return import_field_semantics.MULTI_VALUE_ASSOCIATION_INTERFACES.has(fieldInterface);
201
+ return import_association_interfaces.MULTI_VALUE_ASSOCIATION_INTERFACES.has(fieldInterface);
202
202
  }
203
203
  function isFlowSurfaceDefaultActionPopupAssociationField(field) {
204
204
  const fieldType = String((0, import_service_helpers.getFieldType)(field) || "").trim();
@@ -6,6 +6,7 @@
6
6
  * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
+ export { MULTI_VALUE_ASSOCIATION_INTERFACES, SINGLE_VALUE_ASSOCIATION_INTERFACES } from './association-interfaces';
9
10
  export type FlowSurfaceFieldBindingScope = 'display' | 'editable' | 'filter';
10
11
  export type FlowSurfaceFieldBindingResolution = {
11
12
  modelClassName: string;
@@ -26,12 +26,15 @@ var __copyProps = (to, from, except, desc) => {
26
26
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
27
  var field_binding_registry_exports = {};
28
28
  __export(field_binding_registry_exports, {
29
+ MULTI_VALUE_ASSOCIATION_INTERFACES: () => import_association_interfaces2.MULTI_VALUE_ASSOCIATION_INTERFACES,
30
+ SINGLE_VALUE_ASSOCIATION_INTERFACES: () => import_association_interfaces2.SINGLE_VALUE_ASSOCIATION_INTERFACES,
29
31
  getRegisteredFieldUses: () => getRegisteredFieldUses,
30
32
  resolveRegisteredFieldBinding: () => resolveRegisteredFieldBinding
31
33
  });
32
34
  module.exports = __toCommonJS(field_binding_registry_exports);
33
35
  var import_field_semantics = require("./field-semantics");
34
36
  var import_service_helpers = require("./service-helpers");
37
+ var import_association_interfaces2 = require("./association-interfaces");
35
38
  const FILE_MANAGER_PLUGIN = "@nocobase/plugin-file-manager";
36
39
  const ATTACHMENT_URL_PLUGIN = "@nocobase/plugin-field-attachment-url";
37
40
  const CODE_PLUGIN = "@nocobase/plugin-field-code";
@@ -100,7 +103,7 @@ const FIELD_BINDING_RULE_DEFINITIONS = [
100
103
  {
101
104
  scope: "display",
102
105
  modelClassName: "DisplayPreviewFieldModel",
103
- interfaces: ["url", "attachment", "attachmentURL", "m2m", "m2o", "o2o", "o2m", "oho", "obo", "mbm"],
106
+ interfaces: ["attachment", "attachmentURL", "m2m", "m2o", "o2o", "o2m", "oho", "obo", "mbm"],
104
107
  ownerPlugin: FILE_MANAGER_PLUGIN,
105
108
  isDefault: true,
106
109
  when: ({ field, targetCollection }) => isAttachmentInterface(field) || !targetCollection || getCollectionTemplate(targetCollection) === "file"
@@ -386,6 +389,8 @@ function resolveRegisteredFieldBinding(input) {
386
389
  }
387
390
  // Annotate the CommonJS export names for ESM import in node:
388
391
  0 && (module.exports = {
392
+ MULTI_VALUE_ASSOCIATION_INTERFACES,
393
+ SINGLE_VALUE_ASSOCIATION_INTERFACES,
389
394
  getRegisteredFieldUses,
390
395
  resolveRegisteredFieldBinding
391
396
  });
@@ -6,7 +6,7 @@
6
6
  * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
- export declare const MULTI_VALUE_ASSOCIATION_INTERFACES: Set<string>;
9
+ export { MULTI_VALUE_ASSOCIATION_INTERFACES } from './association-interfaces';
10
10
  export declare function normalizeFieldContainerKind(containerUse?: string): "form" | "details" | "table" | "filter-form";
11
11
  export declare function shouldUseAssociationTitleTextDisplay(input: {
12
12
  containerUse?: string;
@@ -26,12 +26,14 @@ var __copyProps = (to, from, except, desc) => {
26
26
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
27
  var field_semantics_exports = {};
28
28
  __export(field_semantics_exports, {
29
- MULTI_VALUE_ASSOCIATION_INTERFACES: () => MULTI_VALUE_ASSOCIATION_INTERFACES,
29
+ MULTI_VALUE_ASSOCIATION_INTERFACES: () => import_association_interfaces2.MULTI_VALUE_ASSOCIATION_INTERFACES,
30
30
  normalizeFieldContainerKind: () => normalizeFieldContainerKind,
31
31
  shouldUseAssociationTitleTextDisplay: () => shouldUseAssociationTitleTextDisplay
32
32
  });
33
33
  module.exports = __toCommonJS(field_semantics_exports);
34
34
  var import_approval = require("./approval");
35
+ var import_association_interfaces = require("./association-interfaces");
36
+ var import_association_interfaces2 = require("./association-interfaces");
35
37
  const FORM_FIELD_CONTAINER_USES = /* @__PURE__ */ new Set([
36
38
  "FormBlockModel",
37
39
  "CreateFormModel",
@@ -54,7 +56,6 @@ const DETAILS_FIELD_CONTAINER_USES = /* @__PURE__ */ new Set([
54
56
  ]);
55
57
  const FILTER_FIELD_CONTAINER_USES = /* @__PURE__ */ new Set(["FilterFormBlockModel", "FilterFormGridModel", "FilterFormItemModel"]);
56
58
  const TABLE_FIELD_CONTAINER_USES = /* @__PURE__ */ new Set(["TableBlockModel", "TableColumnModel"]);
57
- const MULTI_VALUE_ASSOCIATION_INTERFACES = /* @__PURE__ */ new Set(["m2m", "o2m", "mbm"]);
58
59
  function normalizeFieldContainerKind(containerUse) {
59
60
  const normalized = (0, import_approval.normalizeApprovalSemanticUse)(containerUse);
60
61
  if (FORM_FIELD_CONTAINER_USES.has(normalized)) {
@@ -73,7 +74,7 @@ function normalizeFieldContainerKind(containerUse) {
73
74
  }
74
75
  function shouldUseAssociationTitleTextDisplay(input) {
75
76
  const containerKind = normalizeFieldContainerKind(input.containerUse);
76
- return (containerKind === "table" || containerKind === "details") && !String(input.associationPathName || "").trim() && MULTI_VALUE_ASSOCIATION_INTERFACES.has(String(input.fieldInterface || "").trim());
77
+ return (containerKind === "table" || containerKind === "details") && !String(input.associationPathName || "").trim() && import_association_interfaces.MULTI_VALUE_ASSOCIATION_INTERFACES.has(String(input.fieldInterface || "").trim());
77
78
  }
78
79
  // Annotate the CommonJS export names for ESM import in node:
79
80
  0 && (module.exports = {