@nocobase/plugin-flow-engine 2.2.0-beta.2 → 2.2.0-beta.5

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 (50) hide show
  1. package/dist/externalVersion.js +9 -9
  2. package/dist/node_modules/@ant-design/icons-svg/package.json +1 -1
  3. package/dist/node_modules/acorn/package.json +1 -1
  4. package/dist/node_modules/acorn-jsx/package.json +1 -1
  5. package/dist/node_modules/acorn-walk/package.json +1 -1
  6. package/dist/node_modules/ses/package.json +1 -1
  7. package/dist/node_modules/zod/package.json +1 -1
  8. package/dist/server/flow-surfaces/approval/authoring-validation.d.ts +9 -0
  9. package/dist/server/flow-surfaces/approval/authoring-validation.js +1151 -0
  10. package/dist/server/flow-surfaces/approval/blueprint-service.js +2 -0
  11. package/dist/server/flow-surfaces/authoring-validation.js +429 -32
  12. package/dist/server/flow-surfaces/blueprint/export-document.d.ts +50 -0
  13. package/dist/server/flow-surfaces/blueprint/export-document.js +2505 -0
  14. package/dist/server/flow-surfaces/builder.js +16 -1
  15. package/dist/server/flow-surfaces/catalog.js +3 -1
  16. package/dist/server/flow-surfaces/configure-options.js +4 -3
  17. package/dist/server/flow-surfaces/constants.d.ts +9 -2
  18. package/dist/server/flow-surfaces/constants.js +1 -0
  19. package/dist/server/flow-surfaces/contract-guard.js +24 -2
  20. package/dist/server/flow-surfaces/default-action-popup.d.ts +2 -0
  21. package/dist/server/flow-surfaces/default-action-popup.js +27 -13
  22. package/dist/server/flow-surfaces/filter-group.d.ts +19 -2
  23. package/dist/server/flow-surfaces/filter-group.js +232 -3
  24. package/dist/server/flow-surfaces/planning/compiler.d.ts +1 -0
  25. package/dist/server/flow-surfaces/planning/compiler.js +205 -82
  26. package/dist/server/flow-surfaces/planning/runtime.js +1 -0
  27. package/dist/server/flow-surfaces/planning/step-link.d.ts +1 -1
  28. package/dist/server/flow-surfaces/planning/step-link.js +22 -3
  29. package/dist/server/flow-surfaces/public-data-surface-default-filter.js +0 -9
  30. package/dist/server/flow-surfaces/reaction/field-value.d.ts +9 -0
  31. package/dist/server/flow-surfaces/reaction/field-value.js +51 -2
  32. package/dist/server/flow-surfaces/reaction/linkage.d.ts +6 -1
  33. package/dist/server/flow-surfaces/reaction/linkage.js +18 -3
  34. package/dist/server/flow-surfaces/reaction/meta.js +19 -1
  35. package/dist/server/flow-surfaces/reaction/types.d.ts +19 -0
  36. package/dist/server/flow-surfaces/relation-backing-foreign-key.d.ts +10 -0
  37. package/dist/server/flow-surfaces/relation-backing-foreign-key.js +79 -0
  38. package/dist/server/flow-surfaces/runjs-authoring/ast/source.d.ts +1 -0
  39. package/dist/server/flow-surfaces/runjs-authoring/ast/source.js +20 -0
  40. package/dist/server/flow-surfaces/runjs-authoring/scan/filter.js +12 -2
  41. package/dist/server/flow-surfaces/runjs-authoring/scan/index.js +9 -1
  42. package/dist/server/flow-surfaces/service.d.ts +24 -0
  43. package/dist/server/flow-surfaces/service.js +308 -27
  44. package/dist/server/variables/registry.js +3 -0
  45. package/dist/swagger/flow-surfaces.d.ts +180 -0
  46. package/dist/swagger/flow-surfaces.examples.d.ts +8 -0
  47. package/dist/swagger/flow-surfaces.examples.js +8 -0
  48. package/dist/swagger/flow-surfaces.js +160 -4
  49. package/dist/swagger/index.d.ts +180 -0
  50. package/package.json +2 -2
@@ -56,6 +56,7 @@ var import_executor = require("./executor");
56
56
  var import_reference_guards = require("./reference-guards");
57
57
  var import_key_registry = require("./planning/key-registry");
58
58
  var import_blueprint = require("./blueprint");
59
+ var import_export_document = require("./blueprint/export-document");
59
60
  var import_compile_blocks = require("./blueprint/compile-blocks");
60
61
  var import_default_block_actions = require("./default-block-actions");
61
62
  var import_template_reference = require("./template-reference");
@@ -96,6 +97,7 @@ var import_meta = require("./reaction/meta");
96
97
  var import_resolver = require("./reaction/resolver");
97
98
  var import_association_title_field = require("./association-title-field");
98
99
  var import_default_action_popup = require("./default-action-popup");
100
+ var import_relation_backing_foreign_key = require("./relation-backing-foreign-key");
99
101
  var import_defaults = require("./blueprint/defaults");
100
102
  var import_service_utils = require("./service-utils");
101
103
  var import_field_type_resolver = require("./field-type-resolver");
@@ -229,9 +231,11 @@ function isFlowSurfaceChartRepairError(error) {
229
231
  var _a, _b;
230
232
  return error instanceof import_errors.FlowSurfaceBadRequestError && ((_b = (_a = error.options) == null ? void 0 : _a.details) == null ? void 0 : _b.repairHint) === FLOW_SURFACE_CHART_REPAIR_HINT;
231
233
  }
234
+ const FLOW_SURFACE_EXPORT_BLUEPRINT_ROOT_ONLY_MESSAGE = "exportBlueprint v1 only supports root page export";
232
235
  const FORM_BLOCK_USES = /* @__PURE__ */ new Set(["FormBlockModel", "CreateFormModel", "EditFormModel", ...import_approval.APPROVAL_FORM_BLOCK_USES]);
233
236
  const AUTO_SUBMIT_FORM_BLOCK_USES = /* @__PURE__ */ new Set(["CreateFormModel", "EditFormModel"]);
234
237
  const FLOW_SURFACE_DEFAULT_ACTION_SETTINGS_KEYS = /* @__PURE__ */ new Set(["filter"]);
238
+ const ACTION_BUTTON_GENERAL_SETTING_KEYS = ["title", "tooltip", "icon", "iconOnly", "type", "danger", "color"];
235
239
  const DETAILS_BLOCK_USES = /* @__PURE__ */ new Set(["DetailsBlockModel", ...import_approval.APPROVAL_DETAILS_BLOCK_USES]);
236
240
  const SIMPLE_FORM_BLOCK_USES = /* @__PURE__ */ new Set([
237
241
  "FormBlockModel",
@@ -1945,6 +1949,9 @@ class FlowSurfacesService {
1945
1949
  if (!(popupProfile == null ? void 0 : popupProfile.currentCollection)) {
1946
1950
  return popupProfile == null ? void 0 : popupProfile.filterByTk;
1947
1951
  }
1952
+ if (popupProfile.popupKind === "recordPopup" && popupProfile.popupHostUse && POPUP_HOST_DEFAULT_RECORD_CONTEXT_ACTION_USES.has(popupProfile.popupHostUse)) {
1953
+ return "{{ctx.view.inputArgs.filterByTk}}";
1954
+ }
1948
1955
  if (popupProfile.popupKind !== "associationPopup") {
1949
1956
  return popupProfile.filterByTk;
1950
1957
  }
@@ -2300,10 +2307,18 @@ class FlowSurfacesService {
2300
2307
  if (!sameCurrentCollection || !(0, import_service_helpers.hasConfiguredFlowContextValue)(normalized.filterByTk)) {
2301
2308
  return false;
2302
2309
  }
2310
+ const expectedFilterByTk = this.resolvePopupCurrentRecordResourceFilterByTk(input.popupProfile, {
2311
+ usePopupInputArgsWhenSourceIdInferred: true
2312
+ });
2313
+ const matchesCurrentRecordFilterByTk = this.isPopupCurrentRecordFilterByTkMatch(
2314
+ input.popupProfile,
2315
+ normalized.filterByTk,
2316
+ expectedFilterByTk
2317
+ );
2303
2318
  if (input.popupProfile.hasAssociationContext) {
2304
- return this.isSameConfiguredFlowContextValue(normalized.filterByTk, input.popupProfile.filterByTk) && normalized.associationName === input.popupProfile.associationName && this.isSameConfiguredFlowContextValue(normalized.sourceId, input.popupProfile.sourceId);
2319
+ return matchesCurrentRecordFilterByTk && normalized.associationName === input.popupProfile.associationName && this.isSameConfiguredFlowContextValue(normalized.sourceId, input.popupProfile.sourceId);
2305
2320
  }
2306
- return this.isSameConfiguredFlowContextValue(normalized.filterByTk, input.popupProfile.filterByTk) && !(0, import_service_helpers.hasConfiguredFlowContextValue)(normalized.associationName) && !(0, import_service_helpers.hasConfiguredFlowContextValue)(normalized.sourceId);
2321
+ return matchesCurrentRecordFilterByTk && !(0, import_service_helpers.hasConfiguredFlowContextValue)(normalized.associationName) && !(0, import_service_helpers.hasConfiguredFlowContextValue)(normalized.sourceId);
2307
2322
  }
2308
2323
  if (input.binding === "associatedRecords") {
2309
2324
  if (!(0, import_service_helpers.hasConfiguredFlowContextValue)(normalized.collectionName) || !(0, import_service_helpers.hasConfiguredFlowContextValue)(normalized.associationName) || !(0, import_service_helpers.hasConfiguredFlowContextValue)(normalized.sourceId) || (0, import_service_helpers.hasConfiguredFlowContextValue)(normalized.filterByTk)) {
@@ -2346,6 +2361,12 @@ class FlowSurfacesService {
2346
2361
  }
2347
2362
  return import_lodash.default.isEqual(this.normalizeFlowContextTemplateValue(left), this.normalizeFlowContextTemplateValue(right));
2348
2363
  }
2364
+ isPopupCurrentRecordFilterByTkMatch(popupProfile, filterByTk, expectedFilterByTk) {
2365
+ if (this.isSameConfiguredFlowContextValue(filterByTk, expectedFilterByTk)) {
2366
+ return true;
2367
+ }
2368
+ return popupProfile.popupKind === "associationPopup" && this.isSameConfiguredFlowContextValue(filterByTk, popupProfile.filterByTk);
2369
+ }
2349
2370
  isPopupAssociatedRecordsSourceIdMatch(popupProfile, associationField, sourceId) {
2350
2371
  var _a, _b;
2351
2372
  if (!(0, import_service_helpers.hasConfiguredFlowContextValue)(sourceId)) {
@@ -2621,6 +2642,28 @@ class FlowSurfacesService {
2621
2642
  }
2622
2643
  return capability;
2623
2644
  }
2645
+ async getLiveFieldValueCapability(writeTarget, resolvedTarget, node, options = {}) {
2646
+ const context = await this.context(
2647
+ {
2648
+ target: writeTarget
2649
+ },
2650
+ options
2651
+ );
2652
+ const { capabilities } = (0, import_meta.buildReactionMetaCapabilities)({
2653
+ resolvedTarget: {
2654
+ ...resolvedTarget,
2655
+ node
2656
+ },
2657
+ context
2658
+ });
2659
+ const capability = capabilities.find((item) => item.kind === "fieldValue");
2660
+ if (!capability) {
2661
+ (0, import_errors.throwBadRequest)(
2662
+ `flowSurfaces reaction target '${resolvedTarget.use || resolvedTarget.target.uid}' does not support fieldValue`
2663
+ );
2664
+ }
2665
+ return capability;
2666
+ }
2624
2667
  async getReactionMeta(values, options = {}) {
2625
2668
  (0, import_payload_shape.validateFlowSurfacePayloadShape)("getReactionMeta", values, "values");
2626
2669
  const { writeTarget, node, resolvedTarget } = await this.resolveReactionRequest("getReactionMeta", values == null ? void 0 : values.target, {
@@ -2666,6 +2709,8 @@ class FlowSurfacesService {
2666
2709
  },
2667
2710
  rules: Array.isArray(values == null ? void 0 : values.rules) ? values.rules : []
2668
2711
  });
2712
+ const liveCapability = await this.getLiveFieldValueCapability(writeTarget, resolvedTarget, node, options);
2713
+ (0, import_field_value.validateFieldValueRulesAgainstCapability)(result.normalizedRules, liveCapability);
2669
2714
  await this.persistReactionSlot(storageNode, capability.resolvedSlot, result.canonicalRules, options);
2670
2715
  return result;
2671
2716
  }
@@ -2873,6 +2918,41 @@ class FlowSurfacesService {
2873
2918
  const publicNode = this.stripInternalSurfaceMetaFromNodeTree(import_lodash.default.cloneDeep(rawNode));
2874
2919
  return this.buildSurfaceReadPayload(target, resolved, publicNode, options);
2875
2920
  }
2921
+ async exportBlueprint(input, options = {}) {
2922
+ const request = this.normalizeExportBlueprintRequest(input);
2923
+ const resolved = await this.locator.resolve(request.target, options);
2924
+ if (resolved.kind !== "page" || !resolved.pageRoute) {
2925
+ (0, import_errors.throwBadRequest)(FLOW_SURFACE_EXPORT_BLUEPRINT_ROOT_ONLY_MESSAGE);
2926
+ }
2927
+ const pageSchemaUid = this.resolveExportBlueprintPageSchemaUid(request.target, resolved);
2928
+ await this.assertExportBlueprintRootTarget(request.target, resolved, pageSchemaUid, options.transaction);
2929
+ const rawNode = await this.decorateTemplateReadbackTree(
2930
+ this.normalizePopupTreeShape(
2931
+ await this.loadResolvedNode(resolved, options.transaction, {
2932
+ persistCalendarPopupHosts: false
2933
+ })
2934
+ ),
2935
+ options.transaction
2936
+ );
2937
+ if (!(rawNode == null ? void 0 : rawNode.uid)) {
2938
+ (0, import_errors.throwBadRequest)(`flowSurfaces exportBlueprint target '${pageSchemaUid}' could not resolve a readable page tree`);
2939
+ }
2940
+ const pageRoute = resolved.pageRoute ? await this.routeSync.hydrateRoute(resolved.pageRoute, options.transaction) : void 0;
2941
+ const result = (0, import_export_document.exportFlowSurfaceBlueprintDocument)({
2942
+ page: rawNode,
2943
+ pageRoute,
2944
+ target: {
2945
+ pageSchemaUid
2946
+ },
2947
+ unsupportedPolicy: request.unsupportedPolicy
2948
+ });
2949
+ return {
2950
+ ...result,
2951
+ document: (0, import_blueprint.prepareFlowSurfaceApplyBlueprintDocument)(
2952
+ result.document
2953
+ )
2954
+ };
2955
+ }
2876
2956
  getDeclaredKeyPersistenceDeps() {
2877
2957
  return {
2878
2958
  findModelById: (uid2, findOptions) => this.repository.findModelById(uid2, findOptions),
@@ -4474,10 +4554,16 @@ class FlowSurfacesService {
4474
4554
  return this.buildPopupTemplateOpenView(template, "reference", templateTargetUid, options);
4475
4555
  }
4476
4556
  shouldHydrateDetachedPopupTemplateBlockResourceContext(blockNode, context) {
4477
- if (!this.isCollectionBlockUse(blockNode == null ? void 0 : blockNode.use) || !context.associationName || !context.sourceId) {
4557
+ if (!this.isCollectionBlockUse(blockNode == null ? void 0 : blockNode.use)) {
4478
4558
  return false;
4479
4559
  }
4480
4560
  const init = import_lodash.default.get(blockNode, ["stepParams", "resourceSettings", "init"]) || {};
4561
+ if (this.resolveDetachedPopupTemplateBlockCurrentRecordFilterByTk(init, context)) {
4562
+ return true;
4563
+ }
4564
+ if (!context.associationName || !context.sourceId) {
4565
+ return false;
4566
+ }
4481
4567
  const popupDataSourceKey = context.dataSourceKey || "main";
4482
4568
  const blockDataSourceKey = init.dataSourceKey || "main";
4483
4569
  if (!context.collectionName || blockDataSourceKey !== popupDataSourceKey || init.collectionName !== context.collectionName) {
@@ -4492,6 +4578,28 @@ class FlowSurfacesService {
4492
4578
  }
4493
4579
  return blockAssociationName !== context.associationName || !this.isSameConfiguredFlowContextValue(init.sourceId, context.sourceId);
4494
4580
  }
4581
+ resolveDetachedPopupTemplateBlockCurrentRecordFilterByTk(init, context) {
4582
+ if (!(0, import_service_helpers.hasConfiguredFlowContextValue)(init.filterByTk)) {
4583
+ return void 0;
4584
+ }
4585
+ if (this.isSameConfiguredFlowContextValue(init.filterByTk, "{{ctx.view.inputArgs.filterByTk}}")) {
4586
+ return void 0;
4587
+ }
4588
+ const popupDataSourceKey = context.dataSourceKey || "main";
4589
+ const blockDataSourceKey = init.dataSourceKey || "main";
4590
+ if (!context.collectionName || blockDataSourceKey !== popupDataSourceKey || init.collectionName !== context.collectionName) {
4591
+ return void 0;
4592
+ }
4593
+ if (context.filterByTk && this.isSameConfiguredFlowContextValue(init.filterByTk, context.filterByTk)) {
4594
+ return "{{ctx.view.inputArgs.filterByTk}}";
4595
+ }
4596
+ const collection = this.getCollection(popupDataSourceKey, context.collectionName);
4597
+ const filterTargetKey = this.getCollectionFilterTargetKey(collection);
4598
+ if (this.isSameConfiguredFlowContextValue(init.filterByTk, `{{ctx.record.${filterTargetKey}}}`)) {
4599
+ return "{{ctx.view.inputArgs.filterByTk}}";
4600
+ }
4601
+ return void 0;
4602
+ }
4495
4603
  collectDetachedPopupTemplateBlockResourceContextPatches(node, context, patches = []) {
4496
4604
  if (!node || typeof node !== "object") {
4497
4605
  return patches;
@@ -4499,6 +4607,7 @@ class FlowSurfacesService {
4499
4607
  if (node.uid && this.shouldHydrateDetachedPopupTemplateBlockResourceContext(node, context)) {
4500
4608
  const nextStepParams = import_lodash.default.cloneDeep(node.stepParams || {});
4501
4609
  const currentInit = import_lodash.default.get(nextStepParams, ["resourceSettings", "init"]) || {};
4610
+ const filterByTk = this.resolveDetachedPopupTemplateBlockCurrentRecordFilterByTk(currentInit, context);
4502
4611
  import_lodash.default.set(
4503
4612
  nextStepParams,
4504
4613
  ["resourceSettings", "init"],
@@ -4506,8 +4615,11 @@ class FlowSurfacesService {
4506
4615
  ...currentInit,
4507
4616
  dataSourceKey: context.dataSourceKey || currentInit.dataSourceKey || "main",
4508
4617
  collectionName: context.collectionName || currentInit.collectionName,
4509
- associationName: context.associationName,
4510
- sourceId: context.sourceId
4618
+ ...context.associationName && context.sourceId ? {
4619
+ associationName: context.associationName,
4620
+ sourceId: context.sourceId
4621
+ } : {},
4622
+ ...filterByTk ? { filterByTk } : {}
4511
4623
  })
4512
4624
  );
4513
4625
  patches.push({
@@ -6679,11 +6791,6 @@ class FlowSurfacesService {
6679
6791
  requiredFieldCount: options.requiredFieldCount
6680
6792
  }
6681
6793
  );
6682
- if (!(0, import_service_utils.hasOwnDefined)(normalizedSettings, "filterableFieldNames")) {
6683
- normalizedSettings.filterableFieldNames = (0, import_public_data_surface_default_filter.resolveFlowSurfaceDefaultFilterFieldNames)(
6684
- normalizedSettings.defaultFilter
6685
- );
6686
- }
6687
6794
  }
6688
6795
  return normalizedSettings;
6689
6796
  }
@@ -11511,6 +11618,7 @@ class FlowSurfacesService {
11511
11618
  normalizedValues,
11512
11619
  nextPayload
11513
11620
  );
11621
+ this.syncActionButtonSettingsForUpdateSettings(current, normalizedValues, nextPayload);
11514
11622
  this.syncActionTriggerWorkflowsForUpdateSettings(current, normalizedValues, nextPayload);
11515
11623
  const popupActionContext = options.popupActionContext || await this.resolveRecordContextPopupActionContextForHost(current, options.transaction);
11516
11624
  await this.normalizeOpenViewForUpdateSettings(
@@ -11972,17 +12080,6 @@ class FlowSurfacesService {
11972
12080
  const filterValue = this.normalizeEffectivePublicDataSurfaceDefaultFilter(normalizedFilterValue, {
11973
12081
  requiredFieldCount: options.requiredFieldCount
11974
12082
  });
11975
- if (!hasPropsFilterableFieldNames && !hasStepFilterableFieldNames) {
11976
- const filterableFieldNames = (0, import_public_data_surface_default_filter.resolveFlowSurfaceDefaultFilterFieldNames)(filterValue);
11977
- if (filterableFieldNames.length) {
11978
- nextProps.filterableFieldNames = filterableFieldNames;
11979
- import_lodash.default.set(
11980
- nextStepParams,
11981
- ["filterSettings", "filterableFieldNames", "filterableFieldNames"],
11982
- import_lodash.default.cloneDeep(filterableFieldNames)
11983
- );
11984
- }
11985
- }
11986
12083
  nextProps.defaultFilterValue = import_lodash.default.cloneDeep(filterValue);
11987
12084
  nextProps.filterValue = import_lodash.default.cloneDeep(filterValue);
11988
12085
  import_lodash.default.set(nextStepParams, ["filterSettings", "defaultFilter", "defaultFilter"], import_lodash.default.cloneDeep(filterValue));
@@ -12029,6 +12126,65 @@ class FlowSurfacesService {
12029
12126
  nextPayload.stepParams = nextStepParams;
12030
12127
  }
12031
12128
  }
12129
+ syncActionButtonSettingsForUpdateSettings(current, normalizedValues, nextPayload) {
12130
+ if (!this.supportsActionButtonSettingsSync(current)) {
12131
+ return;
12132
+ }
12133
+ const requestedProps = this.pickRequestedActionButtonSettings(normalizedValues.props);
12134
+ const requestedButtonGeneral = this.pickRequestedActionButtonSettings(
12135
+ import_lodash.default.get(normalizedValues, ["stepParams", "buttonSettings", "general"])
12136
+ );
12137
+ const hasRequestedProps = Object.keys(requestedProps).length > 0;
12138
+ const hasRequestedButtonGeneral = Object.keys(requestedButtonGeneral).length > 0;
12139
+ if (!hasRequestedProps && !hasRequestedButtonGeneral) {
12140
+ return;
12141
+ }
12142
+ const hasRequestedTitle = Object.prototype.hasOwnProperty.call(requestedProps, "title") || Object.prototype.hasOwnProperty.call(requestedButtonGeneral, "title");
12143
+ const shouldStripImplicitTitle = (requestedProps.iconOnly === true || requestedButtonGeneral.iconOnly === true) && !hasRequestedTitle;
12144
+ const nextProps = import_lodash.default.cloneDeep(
12145
+ import_lodash.default.isPlainObject(nextPayload.props) ? nextPayload.props : import_lodash.default.isPlainObject(current == null ? void 0 : current.props) ? current.props : {}
12146
+ );
12147
+ const nextStepParams = import_lodash.default.cloneDeep(
12148
+ import_lodash.default.isPlainObject(nextPayload.stepParams) ? nextPayload.stepParams : import_lodash.default.isPlainObject(current == null ? void 0 : current.stepParams) ? current.stepParams : {}
12149
+ );
12150
+ Object.entries(requestedProps).forEach(([key, value]) => {
12151
+ if (Object.prototype.hasOwnProperty.call(requestedButtonGeneral, key)) {
12152
+ return;
12153
+ }
12154
+ import_lodash.default.set(nextStepParams, ["buttonSettings", "general", key], import_lodash.default.cloneDeep(value));
12155
+ });
12156
+ Object.entries(requestedButtonGeneral).forEach(([key, value]) => {
12157
+ if (Object.prototype.hasOwnProperty.call(requestedProps, key)) {
12158
+ return;
12159
+ }
12160
+ nextProps[key] = import_lodash.default.cloneDeep(value);
12161
+ });
12162
+ if (shouldStripImplicitTitle) {
12163
+ delete nextProps.title;
12164
+ if (import_lodash.default.isPlainObject(import_lodash.default.get(nextStepParams, ["buttonSettings", "general"]))) {
12165
+ delete nextStepParams.buttonSettings.general.title;
12166
+ }
12167
+ }
12168
+ nextPayload.props = nextProps;
12169
+ nextPayload.stepParams = nextStepParams;
12170
+ }
12171
+ supportsActionButtonSettingsSync(current) {
12172
+ var _a, _b, _c, _d, _e, _f;
12173
+ const contract = (0, import_catalog.getNodeContract)(current == null ? void 0 : current.use);
12174
+ return ((_b = (_a = contract.domains.props) == null ? void 0 : _a.allowedKeys) == null ? void 0 : _b.includes("iconOnly")) && ((_f = (_e = (_d = (_c = contract.domains.stepParams) == null ? void 0 : _c.groups) == null ? void 0 : _d.buttonSettings) == null ? void 0 : _e.allowedPaths) == null ? void 0 : _f.includes("general.iconOnly"));
12175
+ }
12176
+ pickRequestedActionButtonSettings(input) {
12177
+ const picked = {};
12178
+ if (!import_lodash.default.isPlainObject(input)) {
12179
+ return picked;
12180
+ }
12181
+ ACTION_BUTTON_GENERAL_SETTING_KEYS.forEach((key) => {
12182
+ if (Object.prototype.hasOwnProperty.call(input, key) && !import_lodash.default.isUndefined(input[key])) {
12183
+ picked[key] = import_lodash.default.cloneDeep(input[key]);
12184
+ }
12185
+ });
12186
+ return picked;
12187
+ }
12032
12188
  syncCreatedFieldWrapperTitleFieldStepParams(node) {
12033
12189
  const mirror = (UPDATE_SETTINGS_STEP_PARAM_MIRRORS_BY_USE[(node == null ? void 0 : node.use) || ""] || []).find(
12034
12190
  (item) => item.domain === "props" && item.key === "titleField"
@@ -13694,6 +13850,111 @@ class FlowSurfacesService {
13694
13850
  }
13695
13851
  return target;
13696
13852
  }
13853
+ normalizeExportBlueprintRequest(input) {
13854
+ if (!import_lodash.default.isPlainObject(input)) {
13855
+ (0, import_errors.throwBadRequest)(`flowSurfaces exportBlueprint payload must be an object`);
13856
+ }
13857
+ const unsupportedKeys = Object.keys(input).filter((key) => key !== "target" && key !== "options");
13858
+ if (unsupportedKeys.length) {
13859
+ (0, import_errors.throwBadRequest)(`flowSurfaces exportBlueprint only accepts target and options`);
13860
+ }
13861
+ if (!import_lodash.default.isPlainObject(input.target)) {
13862
+ (0, import_errors.throwBadRequest)(`flowSurfaces exportBlueprint requires target`);
13863
+ }
13864
+ const targetInput = input.target;
13865
+ const target = (0, import_service_utils.buildDefinedPayload)({
13866
+ uid: this.normalizeExportBlueprintLocatorValue(targetInput.uid, "uid"),
13867
+ pageSchemaUid: this.normalizeExportBlueprintLocatorValue(targetInput.pageSchemaUid, "pageSchemaUid"),
13868
+ tabSchemaUid: this.normalizeExportBlueprintLocatorValue(targetInput.tabSchemaUid, "tabSchemaUid"),
13869
+ routeId: this.normalizeExportBlueprintLocatorValue(targetInput.routeId, "routeId")
13870
+ });
13871
+ const unsupportedTargetKeys = Object.keys(targetInput).filter(
13872
+ (key) => !["uid", "pageSchemaUid", "tabSchemaUid", "routeId"].includes(key)
13873
+ );
13874
+ if (unsupportedTargetKeys.length) {
13875
+ (0, import_errors.throwBadRequest)(`flowSurfaces exportBlueprint target only accepts uid, pageSchemaUid, tabSchemaUid or routeId`);
13876
+ }
13877
+ if (!Object.keys(target).length) {
13878
+ (0, import_errors.throwBadRequest)(
13879
+ `flowSurfaces exportBlueprint target requires one of uid, pageSchemaUid, tabSchemaUid or routeId`
13880
+ );
13881
+ }
13882
+ if (Object.keys(target).length > 1) {
13883
+ (0, import_errors.throwBadRequest)(
13884
+ `flowSurfaces exportBlueprint target only accepts exactly one locator: uid, pageSchemaUid, tabSchemaUid or routeId`
13885
+ );
13886
+ }
13887
+ if (target.tabSchemaUid) {
13888
+ (0, import_errors.throwBadRequest)(FLOW_SURFACE_EXPORT_BLUEPRINT_ROOT_ONLY_MESSAGE);
13889
+ }
13890
+ return {
13891
+ target,
13892
+ unsupportedPolicy: this.normalizeExportBlueprintUnsupportedPolicy(input.options)
13893
+ };
13894
+ }
13895
+ normalizeExportBlueprintUnsupportedPolicy(input) {
13896
+ if (import_lodash.default.isUndefined(input)) {
13897
+ return "error";
13898
+ }
13899
+ if (!import_lodash.default.isPlainObject(input)) {
13900
+ (0, import_errors.throwBadRequest)(`flowSurfaces exportBlueprint options must be an object`);
13901
+ }
13902
+ const options = input;
13903
+ const unsupportedKeys = Object.keys(options).filter((key) => key !== "unsupported");
13904
+ if (unsupportedKeys.length) {
13905
+ (0, import_errors.throwBadRequest)(`flowSurfaces exportBlueprint options only accepts unsupported`);
13906
+ }
13907
+ const policy = options.unsupported;
13908
+ if (import_lodash.default.isUndefined(policy)) {
13909
+ return "error";
13910
+ }
13911
+ if (policy === "error" || policy === "warn") {
13912
+ return policy;
13913
+ }
13914
+ (0, import_errors.throwBadRequest)(`flowSurfaces exportBlueprint options.unsupported must be 'error' or 'warn'`);
13915
+ }
13916
+ normalizeExportBlueprintLocatorValue(value, key) {
13917
+ if (import_lodash.default.isNil(value)) {
13918
+ return void 0;
13919
+ }
13920
+ if (typeof value !== "string" && typeof value !== "number") {
13921
+ (0, import_errors.throwBadRequest)(`flowSurfaces exportBlueprint target.${key} must be a string`);
13922
+ }
13923
+ const normalized = String(value).trim();
13924
+ return normalized || void 0;
13925
+ }
13926
+ readRouteString(route, key) {
13927
+ var _a;
13928
+ const routeRecord = route;
13929
+ const value = ((_a = routeRecord == null ? void 0 : routeRecord.get) == null ? void 0 : _a.call(routeRecord, key)) ?? (routeRecord == null ? void 0 : routeRecord[key]);
13930
+ const normalized = typeof value === "string" ? value.trim() : "";
13931
+ return normalized || void 0;
13932
+ }
13933
+ resolveExportBlueprintPageSchemaUid(target, resolved) {
13934
+ const pageSchemaUid = this.readRouteString(resolved.pageRoute, "schemaUid") || (target.pageSchemaUid ? String(target.pageSchemaUid).trim() : "");
13935
+ if (!pageSchemaUid) {
13936
+ (0, import_errors.throwBadRequest)(FLOW_SURFACE_EXPORT_BLUEPRINT_ROOT_ONLY_MESSAGE);
13937
+ }
13938
+ return pageSchemaUid;
13939
+ }
13940
+ async assertExportBlueprintRootTarget(target, resolved, pageSchemaUid, transaction) {
13941
+ const targetUid = target.uid ? String(target.uid).trim() : "";
13942
+ if (!targetUid) {
13943
+ return;
13944
+ }
13945
+ if (targetUid === pageSchemaUid) {
13946
+ return;
13947
+ }
13948
+ const rootPageModel = await this.repository.findModelByParentId(pageSchemaUid, {
13949
+ transaction,
13950
+ subKey: "page",
13951
+ includeAsyncNode: false
13952
+ });
13953
+ if ((rootPageModel == null ? void 0 : rootPageModel.uid) && targetUid === String(rootPageModel.uid).trim()) {
13954
+ return;
13955
+ }
13956
+ (0, import_errors.throwBadRequest)(FLOW_SURFACE_EXPORT_BLUEPRINT_ROOT_ONLY_MESSAGE);
13957
+ }
13697
13958
  normalizeContextPath(path) {
13698
13959
  if (import_lodash.default.isUndefined(path) || import_lodash.default.isNull(path)) {
13699
13960
  return void 0;
@@ -18441,13 +18702,14 @@ ${AI_EMPLOYEE_CURRENT_RECORD_PROMPT_VARIABLE}` : AI_EMPLOYEE_CURRENT_RECORD_PROM
18441
18702
  }
18442
18703
  const normalizedDefaultFilter = (0, import_service_utils.hasOwnDefined)(changes, "defaultFilter") ? this.normalizeFilterActionDefaultFilterValue(changes.defaultFilter) : void 0;
18443
18704
  const stepParams = {};
18444
- if ((0, import_service_utils.hasDefinedValue)(changes, ["title", "tooltip", "icon", "type", "danger", "color", "linkageRules"])) {
18705
+ if ((0, import_service_utils.hasDefinedValue)(changes, ["title", "tooltip", "icon", "iconOnly", "type", "danger", "color", "linkageRules"])) {
18445
18706
  stepParams.buttonSettings = {
18446
- ...(0, import_service_utils.hasDefinedValue)(changes, ["title", "tooltip", "icon", "type", "danger", "color"]) ? {
18707
+ ...(0, import_service_utils.hasDefinedValue)(changes, ["title", "tooltip", "icon", "iconOnly", "type", "danger", "color"]) ? {
18447
18708
  general: (0, import_service_utils.buildDefinedPayload)({
18448
18709
  title: changes.title,
18449
18710
  tooltip: changes.tooltip,
18450
18711
  icon: changes.icon,
18712
+ iconOnly: changes.iconOnly,
18451
18713
  type: changes.type,
18452
18714
  danger: changes.danger,
18453
18715
  color: changes.color
@@ -18657,6 +18919,7 @@ ${AI_EMPLOYEE_CURRENT_RECORD_PROMPT_VARIABLE}` : AI_EMPLOYEE_CURRENT_RECORD_PROM
18657
18919
  title: changes.title,
18658
18920
  tooltip: changes.tooltip,
18659
18921
  icon: changes.icon,
18922
+ iconOnly: changes.iconOnly,
18660
18923
  type: changes.type,
18661
18924
  htmlType: changes.htmlType,
18662
18925
  position: changes.position,
@@ -18786,6 +19049,11 @@ ${AI_EMPLOYEE_CURRENT_RECORD_PROMPT_VARIABLE}` : AI_EMPLOYEE_CURRENT_RECORD_PROM
18786
19049
  useStrictOnly: input.useStrictOnly
18787
19050
  });
18788
19051
  }
19052
+ isCollectionTitleField(collection, fieldName) {
19053
+ const normalizedFieldName = String(fieldName || "").trim();
19054
+ const titleFieldName = String((0, import_service_helpers.getCollectionTitleFieldName)(collection) || "").trim();
19055
+ return !!normalizedFieldName && normalizedFieldName === titleFieldName;
19056
+ }
18789
19057
  resolveAssociationLeafDisplaySemantics(field, dataSourceKey, enabledPackages) {
18790
19058
  const registeredBinding = this.resolveRegisteredFieldBinding({
18791
19059
  containerUse: "DetailsItemModel",
@@ -18821,6 +19089,9 @@ ${AI_EMPLOYEE_CURRENT_RECORD_PROMPT_VARIABLE}` : AI_EMPLOYEE_CURRENT_RECORD_PROM
18821
19089
  }
18822
19090
  buildFieldMenuDirectCandidates(input) {
18823
19091
  const collection = this.getCollection(input.resourceInit.dataSourceKey, input.resourceInit.collectionName);
19092
+ const explicitDefaultFieldPaths = (0, import_default_action_popup.collectFlowSurfaceDefaultActionPopupFieldGroupFieldPaths)(
19093
+ input.defaultFieldGroups
19094
+ );
18824
19095
  return (0, import_service_helpers.getCollectionFields)(collection).flatMap((field) => {
18825
19096
  var _a;
18826
19097
  const fieldName = (0, import_service_helpers.getFieldName)(field);
@@ -18831,6 +19102,9 @@ ${AI_EMPLOYEE_CURRENT_RECORD_PROMPT_VARIABLE}` : AI_EMPLOYEE_CURRENT_RECORD_PROM
18831
19102
  if (input.generatedPopupOnly && !(0, import_default_action_popup.isFlowSurfaceDefaultActionPopupBusinessField)(field)) {
18832
19103
  return [];
18833
19104
  }
19105
+ if ((0, import_relation_backing_foreign_key.isRelationBackingForeignKeyField)(collection, field) && !explicitDefaultFieldPaths.has(fieldName)) {
19106
+ return [];
19107
+ }
18834
19108
  if (input.mode === "table" && ((_a = field == null ? void 0 : field.options) == null ? void 0 : _a.treeChildren)) {
18835
19109
  return [];
18836
19110
  }
@@ -18918,6 +19192,9 @@ ${AI_EMPLOYEE_CURRENT_RECORD_PROMPT_VARIABLE}` : AI_EMPLOYEE_CURRENT_RECORD_PROM
18918
19192
  if (!targetFieldName) {
18919
19193
  continue;
18920
19194
  }
19195
+ if ((0, import_relation_backing_foreign_key.isRelationBackingForeignKeyField)(targetCollection, targetField) && !this.isCollectionTitleField(targetCollection, targetFieldName)) {
19196
+ continue;
19197
+ }
18921
19198
  nextCandidates.push({
18922
19199
  field: targetField,
18923
19200
  fieldPath: `${associationPathName}.${targetFieldName}`,
@@ -19092,7 +19369,7 @@ ${AI_EMPLOYEE_CURRENT_RECORD_PROMPT_VARIABLE}` : AI_EMPLOYEE_CURRENT_RECORD_PROM
19092
19369
  const getFields = (targetCollection) => (0, import_service_helpers.getCollectionFields)(targetCollection);
19093
19370
  const isFilterFieldVisible = (field) => (0, import_service_helpers.getFieldFilterable)(field) !== false && !!(0, import_service_helpers.getFieldInterface)(field);
19094
19371
  const directFields = getFields(collection).filter(
19095
- (field) => ["FilterFormBlockModel", "FilterFormGridModel", "FilterFormItemModel"].includes(input.ownerUse) ? isFilterFieldVisible(field) : !!(0, import_service_helpers.getFieldInterface)(field)
19372
+ (field) => !(0, import_relation_backing_foreign_key.isRelationBackingForeignKeyField)(collection, field) && (["FilterFormBlockModel", "FilterFormGridModel", "FilterFormItemModel"].includes(input.ownerUse) ? isFilterFieldVisible(field) : !!(0, import_service_helpers.getFieldInterface)(field))
19096
19373
  );
19097
19374
  if (!directFields.length && !collection) {
19098
19375
  return [];
@@ -19106,9 +19383,13 @@ ${AI_EMPLOYEE_CURRENT_RECORD_PROMPT_VARIABLE}` : AI_EMPLOYEE_CURRENT_RECORD_PROM
19106
19383
  if (!(0, import_service_helpers.isAssociationField)(field) || !targetCollection) {
19107
19384
  return [];
19108
19385
  }
19109
- return getFields(targetCollection).filter(
19110
- (targetField) => ["FilterFormBlockModel", "FilterFormGridModel", "FilterFormItemModel"].includes(input.ownerUse) ? isFilterFieldVisible(targetField) : !!(0, import_service_helpers.getFieldInterface)(targetField)
19111
- ).map((targetField) => ({
19386
+ return getFields(targetCollection).filter((targetField) => {
19387
+ const targetFieldName = (0, import_service_helpers.getFieldName)(targetField);
19388
+ if ((0, import_relation_backing_foreign_key.isRelationBackingForeignKeyField)(targetCollection, targetField) && !this.isCollectionTitleField(targetCollection, targetFieldName)) {
19389
+ return false;
19390
+ }
19391
+ return ["FilterFormBlockModel", "FilterFormGridModel", "FilterFormItemModel"].includes(input.ownerUse) ? isFilterFieldVisible(targetField) : !!(0, import_service_helpers.getFieldInterface)(targetField);
19392
+ }).map((targetField) => ({
19112
19393
  field: targetField,
19113
19394
  fieldPath: `${(0, import_service_helpers.getFieldName)(field)}.${(0, import_service_helpers.getFieldName)(targetField)}`,
19114
19395
  associationPathName: (0, import_service_helpers.getFieldName)(field),
@@ -89,6 +89,9 @@ class VariableRegistry {
89
89
  }
90
90
  const GLOBAL_KEY = "__ncbVarRegistry__";
91
91
  const g = typeof globalThis !== "undefined" ? globalThis : global;
92
+ if (g[GLOBAL_KEY] && typeof g[GLOBAL_KEY] === "object") {
93
+ Object.setPrototypeOf(g[GLOBAL_KEY], VariableRegistry.prototype);
94
+ }
92
95
  if (!g[GLOBAL_KEY]) {
93
96
  g[GLOBAL_KEY] = new VariableRegistry();
94
97
  }