@nocobase/plugin-flow-engine 2.1.0-beta.35 → 2.1.0-beta.36

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 (67) 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/LICENSE +21 -0
  4. package/dist/node_modules/acorn/bin/acorn +4 -0
  5. package/dist/node_modules/acorn/dist/acorn.d.mts +857 -0
  6. package/dist/node_modules/acorn/dist/acorn.d.ts +857 -0
  7. package/dist/node_modules/acorn/dist/acorn.js +1 -0
  8. package/dist/node_modules/acorn/dist/bin.js +90 -0
  9. package/dist/node_modules/acorn/package.json +1 -0
  10. package/dist/node_modules/acorn-jsx/LICENSE +19 -0
  11. package/dist/node_modules/acorn-jsx/index.d.ts +12 -0
  12. package/dist/node_modules/acorn-jsx/index.js +1 -0
  13. package/dist/node_modules/acorn-jsx/package.json +1 -0
  14. package/dist/node_modules/acorn-jsx/xhtml.js +255 -0
  15. package/dist/node_modules/acorn-walk/LICENSE +21 -0
  16. package/dist/node_modules/acorn-walk/dist/walk.d.mts +177 -0
  17. package/dist/node_modules/acorn-walk/dist/walk.d.ts +177 -0
  18. package/dist/node_modules/acorn-walk/dist/walk.js +1 -0
  19. package/dist/node_modules/acorn-walk/node_modules/acorn/bin/acorn +4 -0
  20. package/dist/node_modules/acorn-walk/node_modules/acorn/dist/acorn.d.mts +866 -0
  21. package/dist/node_modules/acorn-walk/node_modules/acorn/dist/acorn.d.ts +866 -0
  22. package/dist/node_modules/acorn-walk/node_modules/acorn/dist/acorn.js +6174 -0
  23. package/dist/node_modules/acorn-walk/node_modules/acorn/dist/bin.js +90 -0
  24. package/dist/node_modules/acorn-walk/node_modules/acorn/package.json +50 -0
  25. package/dist/node_modules/acorn-walk/package.json +1 -0
  26. package/dist/node_modules/ses/package.json +1 -1
  27. package/dist/node_modules/zod/package.json +1 -1
  28. package/dist/server/flow-surfaces/action-scope.d.ts +2 -0
  29. package/dist/server/flow-surfaces/action-scope.js +8 -0
  30. package/dist/server/flow-surfaces/authoring-validation.d.ts +3 -0
  31. package/dist/server/flow-surfaces/authoring-validation.js +317 -9
  32. package/dist/server/flow-surfaces/blueprint/compile-blocks.js +143 -3
  33. package/dist/server/flow-surfaces/blueprint/public-types.d.ts +1 -1
  34. package/dist/server/flow-surfaces/builder.js +54 -1
  35. package/dist/server/flow-surfaces/catalog.js +148 -2
  36. package/dist/server/flow-surfaces/chart-config.d.ts +58 -54
  37. package/dist/server/flow-surfaces/chart-config.js +18 -5
  38. package/dist/server/flow-surfaces/compose-compiler.d.ts +1 -1
  39. package/dist/server/flow-surfaces/compose-runtime.d.ts +1 -0
  40. package/dist/server/flow-surfaces/compose-runtime.js +24 -6
  41. package/dist/server/flow-surfaces/configure-options.js +40 -1
  42. package/dist/server/flow-surfaces/default-block-actions.js +11 -0
  43. package/dist/server/flow-surfaces/index.js +4 -2
  44. package/dist/server/flow-surfaces/node-use-sets.js +2 -0
  45. package/dist/server/flow-surfaces/runjs-authoring/index.d.ts +14 -2
  46. package/dist/server/flow-surfaces/runjs-authoring/index.js +4213 -242
  47. package/dist/server/flow-surfaces/runjs-authoring/nested-runjs-stop/index.d.ts +10 -0
  48. package/dist/server/flow-surfaces/runjs-authoring/nested-runjs-stop/index.js +40 -0
  49. package/dist/server/flow-surfaces/runjs-authoring/rules.js +6 -0
  50. package/dist/server/flow-surfaces/runjs-authoring/source-limit-stop/index.d.ts +10 -0
  51. package/dist/server/flow-surfaces/runjs-authoring/source-limit-stop/index.js +40 -0
  52. package/dist/server/flow-surfaces/runjs-authoring/syntax-stop/index.d.ts +10 -0
  53. package/dist/server/flow-surfaces/runjs-authoring/syntax-stop/index.js +40 -0
  54. package/dist/server/flow-surfaces/runjs-authoring/types.d.ts +1 -1
  55. package/dist/server/flow-surfaces/service-utils.d.ts +1 -1
  56. package/dist/server/flow-surfaces/service-utils.js +3 -0
  57. package/dist/server/flow-surfaces/service.d.ts +61 -3
  58. package/dist/server/flow-surfaces/service.js +1199 -101
  59. package/dist/server/flow-surfaces/support-matrix.d.ts +1 -1
  60. package/dist/server/flow-surfaces/support-matrix.js +13 -1
  61. package/dist/server/flow-surfaces/surface-context.js +4 -13
  62. package/dist/swagger/flow-surfaces.d.ts +147 -0
  63. package/dist/swagger/flow-surfaces.examples.d.ts +194 -1
  64. package/dist/swagger/flow-surfaces.examples.js +75 -3
  65. package/dist/swagger/flow-surfaces.js +180 -7
  66. package/dist/swagger/index.d.ts +147 -0
  67. package/package.json +5 -2
@@ -69,6 +69,8 @@ const FIELD_GRID_BLOCK_TYPES = /* @__PURE__ */ new Set(["createForm", "editForm"
69
69
  const DEFAULT_FORM_BEHAVIOR_REACTION_FORM_BLOCK_TYPES = /* @__PURE__ */ new Set(["createForm", "editForm"]);
70
70
  const SORTABLE_BLOCK_TYPES = /* @__PURE__ */ new Set(["table", "details", "list", "tree", "kanban", "gridCard", "map"]);
71
71
  const CHART_BLOCK_TYPES = /* @__PURE__ */ new Set(["chart"]);
72
+ const COMMENTS_PAGE_SIZE_VALUES = /* @__PURE__ */ new Set([5, 10, 20, 50, 100, 200]);
73
+ const RECORD_HISTORY_INTERNAL_COLLECTIONS = /* @__PURE__ */ new Set(["recordHistories", "recordFieldHistories"]);
72
74
  const ANT_DESIGN_ICON_NAMES = new Set(Object.keys(antDesignIconAsn || {}));
73
75
  const PUBLIC_BLOCK_TYPE_BY_MODEL_USE = {
74
76
  TableBlockModel: "table",
@@ -85,6 +87,7 @@ const PUBLIC_BLOCK_TYPE_BY_MODEL_USE = {
85
87
  ChartBlockModel: "chart",
86
88
  MapBlockModel: "map",
87
89
  CommentsBlockModel: "comments",
90
+ RecordHistoryBlockModel: "recordHistory",
88
91
  JSBlockModel: "jsBlock",
89
92
  MarkdownBlockModel: "markdown",
90
93
  IframeBlockModel: "iframe",
@@ -159,7 +162,8 @@ const TREE_CONNECT_TARGET_BLOCK_USES = /* @__PURE__ */ new Set([
159
162
  "GridCardBlockModel",
160
163
  "ChartBlockModel",
161
164
  "MapBlockModel",
162
- "CommentsBlockModel"
165
+ "CommentsBlockModel",
166
+ "RecordHistoryBlockModel"
163
167
  ]);
164
168
  const HIDDEN_POPUP_SETTINGS_KEYS_BY_BLOCK_TYPE = {
165
169
  calendar: ["quickCreatePopup", "eventPopup"],
@@ -169,6 +173,7 @@ const SUPPORTED_DEFAULT_FILTER_OPERATORS = buildSupportedDefaultFilterOperators(
169
173
  const ACTION_TYPE_ALIASES = /* @__PURE__ */ new Map([
170
174
  ["addchild", "addChild"],
171
175
  ["addnew", "addNew"],
176
+ ["aiemployee", "aiEmployee"],
172
177
  ["bulkupdate", "bulkUpdate"],
173
178
  ["jsitem", "jsItem"],
174
179
  ["selectview", "selectView"],
@@ -192,6 +197,7 @@ const CALENDAR_ACTION_TYPE_ALIASES = /* @__PURE__ */ new Map([
192
197
  const KANBAN_ACTION_TYPE_ALIASES = /* @__PURE__ */ new Map([
193
198
  ["filter", "filter"],
194
199
  ["addnew", "addNew"],
200
+ ["aiemployee", "aiEmployee"],
195
201
  ["popup", "popup"],
196
202
  ["refresh", "refresh"],
197
203
  ["js", "js"],
@@ -283,7 +289,7 @@ async function collectFlowSurfaceAuthoringErrors(actionName, values, context = {
283
289
  collectDefaultsShapeErrors(values == null ? void 0 : values.defaults, "$.defaults", errors);
284
290
  collectDefaultCollectionFieldGroupSemanticErrors(values == null ? void 0 : values.defaults, validationContext, errors);
285
291
  collectDefaultFormBehaviorCompletenessErrors(actionName, values, validationContext, errors);
286
- collectApplyBlueprintChartAssetErrors(actionName, values, errors);
292
+ collectApplyBlueprintChartAssetErrors(actionName, values, validationContext, errors);
287
293
  if (actionName === "configure") {
288
294
  await collectConfigureErrors(values, errors, validationContext);
289
295
  errors.push(...(0, import_runjs_authoring.collectRunJsAuthoringErrors)(actionName, values, validationContext));
@@ -422,13 +428,13 @@ function getAuthoringBlocks(actionName, values) {
422
428
  }
423
429
  return [];
424
430
  }
425
- function collectApplyBlueprintChartAssetErrors(actionName, values, errors) {
431
+ function collectApplyBlueprintChartAssetErrors(actionName, values, context, errors) {
426
432
  var _a;
427
433
  if (actionName !== "applyBlueprint") {
428
434
  return;
429
435
  }
430
436
  const chartAssets = _.isPlainObject((_a = values == null ? void 0 : values.assets) == null ? void 0 : _a.charts) ? values.assets.charts : {};
431
- collectChartAssetRegistryErrors(chartAssets, "$.assets.charts", errors);
437
+ collectChartAssetRegistryErrors(chartAssets, "$.assets.charts", context, errors);
432
438
  _.castArray((values == null ? void 0 : values.tabs) || []).forEach((tab, tabIndex) => {
433
439
  collectChartAssetBlockListErrors(tab == null ? void 0 : tab.blocks, `$.tabs[${tabIndex}].blocks`, chartAssets, errors);
434
440
  });
@@ -519,7 +525,7 @@ function collectChartBlockAssetReferenceErrors(block, path, chartAssets, errors)
519
525
  });
520
526
  }
521
527
  }
522
- function collectChartAssetRegistryErrors(charts, path, errors) {
528
+ function collectChartAssetRegistryErrors(charts, path, context, errors) {
523
529
  if (!_.isPlainObject(charts)) {
524
530
  return;
525
531
  }
@@ -533,11 +539,11 @@ function collectChartAssetRegistryErrors(charts, path, errors) {
533
539
  });
534
540
  return;
535
541
  }
536
- collectChartAssetQueryErrors(asset, assetPath, errors);
542
+ collectChartAssetQueryErrors(asset, assetPath, context, errors);
537
543
  collectChartAssetVisualErrors(asset, assetPath, errors);
538
544
  });
539
545
  }
540
- function collectChartAssetQueryErrors(asset, path, errors) {
546
+ function collectChartAssetQueryErrors(asset, path, context, errors) {
541
547
  const query = asset.query;
542
548
  if (!_.isPlainObject(query)) {
543
549
  pushAuthoringError(errors, {
@@ -563,9 +569,9 @@ function collectChartAssetQueryErrors(asset, path, errors) {
563
569
  collectSqlChartAssetQueryErrors(query, path, errors);
564
570
  return;
565
571
  }
566
- collectBuilderChartAssetQueryErrors(query, path, errors);
572
+ collectBuilderChartAssetQueryErrors(query, path, context, errors);
567
573
  }
568
- function collectBuilderChartAssetQueryErrors(query, path, errors) {
574
+ function collectBuilderChartAssetQueryErrors(query, path, context, errors) {
569
575
  const resource = _.isPlainObject(query.resource) ? query.resource : null;
570
576
  if (!String((resource == null ? void 0 : resource.collectionName) || "").trim()) {
571
577
  pushAuthoringError(errors, {
@@ -588,6 +594,97 @@ function collectBuilderChartAssetQueryErrors(query, path, errors) {
588
594
  "chart-builder-query-forbidden-keys",
589
595
  errors
590
596
  );
597
+ collectBuilderChartAssetFieldErrors(query, path, context, errors);
598
+ }
599
+ function normalizeChartAssetFieldPath(input) {
600
+ if (Array.isArray(input)) {
601
+ return input.map((item) => String(item || "").trim()).filter(Boolean).join(".");
602
+ }
603
+ return String(input || "").trim();
604
+ }
605
+ function collectBuilderChartAssetFieldErrors(query, path, context, errors) {
606
+ const resource = _.isPlainObject(query.resource) ? query.resource : null;
607
+ const collectionName = String((resource == null ? void 0 : resource.collectionName) || "").trim();
608
+ if (!collectionName || typeof context.getCollection !== "function") {
609
+ return;
610
+ }
611
+ const dataSourceKey = String((resource == null ? void 0 : resource.dataSourceKey) || "main").trim() || "main";
612
+ const collection = context.getCollection(dataSourceKey, collectionName);
613
+ if (!collection) {
614
+ return;
615
+ }
616
+ const selections = [
617
+ ..._.castArray(query.measures || []).map((selection, index) => ({
618
+ selection,
619
+ fieldPath: `${path}.query.measures[${index}].field`
620
+ })),
621
+ ..._.castArray(query.dimensions || []).map((selection, index) => ({
622
+ selection,
623
+ fieldPath: `${path}.query.dimensions[${index}].field`
624
+ }))
625
+ ];
626
+ for (const item of selections) {
627
+ if (!_.isPlainObject(item.selection)) {
628
+ continue;
629
+ }
630
+ const fieldPath = normalizeChartAssetFieldPath(item.selection.field);
631
+ if (!fieldPath) {
632
+ continue;
633
+ }
634
+ const field = (0, import_service_helpers.resolveFieldFromCollection)(collection, fieldPath);
635
+ if (!field) {
636
+ if (collectionHasConcreteField(collection, fieldPath)) {
637
+ continue;
638
+ }
639
+ pushAuthoringError(errors, {
640
+ path: item.fieldPath,
641
+ ruleId: "chart-builder-query-field-unknown",
642
+ message: `flowSurfaces authoring ${item.fieldPath} references unknown field '${fieldPath}' on collection '${dataSourceKey}.${collectionName}'`,
643
+ details: {
644
+ fieldPath,
645
+ dataSourceKey,
646
+ collectionName
647
+ }
648
+ });
649
+ continue;
650
+ }
651
+ if (!fieldPath.includes(".") && (0, import_service_helpers.isAssociationField)(field)) {
652
+ const suggestion = resolveChartBuilderAssociationSubfieldSuggestion(
653
+ fieldPath,
654
+ field,
655
+ dataSourceKey,
656
+ context.getCollection
657
+ );
658
+ pushAuthoringError(errors, {
659
+ path: item.fieldPath,
660
+ ruleId: "chart-builder-query-association-field-requires-subfield",
661
+ message: `flowSurfaces authoring ${item.fieldPath} references association field '${fieldPath}' directly; use scalar subfield '${suggestion.suggestedFieldPath}' for builder charts`,
662
+ details: {
663
+ fieldPath,
664
+ dataSourceKey,
665
+ collectionName,
666
+ ...suggestion
667
+ }
668
+ });
669
+ }
670
+ }
671
+ }
672
+ function resolveChartBuilderAssociationSubfieldSuggestion(fieldPath, field, dataSourceKey, getCollection) {
673
+ try {
674
+ const resolved = (0, import_association_title_field.resolveAssociationSafeTitleField)(field, dataSourceKey, getCollection, { fieldPath });
675
+ const titleField = (resolved == null ? void 0 : resolved.fieldName) ? String(resolved.fieldName).trim() : "";
676
+ if (titleField) {
677
+ return {
678
+ suggestedFieldPath: `${fieldPath}.${titleField}`,
679
+ suggestedTitleField: titleField,
680
+ targetCollectionName: (0, import_service_helpers.getCollectionName)(resolved == null ? void 0 : resolved.targetCollection) || void 0
681
+ };
682
+ }
683
+ } catch {
684
+ }
685
+ return {
686
+ suggestedFieldPath: `${fieldPath}.<field>`
687
+ };
591
688
  }
592
689
  function collectSqlChartAssetQueryErrors(query, path, errors) {
593
690
  if (!String(query.sql || "").trim()) {
@@ -3089,6 +3186,8 @@ function collectBlockErrors(block, path, errors, localKeys, context) {
3089
3186
  context
3090
3187
  );
3091
3188
  collectSemanticBindingErrors(block, blockType, path, errors, context);
3189
+ collectCommentsBlockErrors(block, blockType, path, errors, context);
3190
+ collectRecordHistoryBlockErrors(block, blockType, path, errors, context);
3092
3191
  collectChartDisplayTitleErrors(block, blockType, path, errors);
3093
3192
  collectTreeTableExplicitFieldsErrors(block, blockType, path, errors, context);
3094
3193
  collectTreeConnectFieldsErrors((_a = block.settings) == null ? void 0 : _a.connectFields, `${path}.settings.connectFields`, errors);
@@ -3387,6 +3486,8 @@ async function collectConfigureErrors(values, errors, context) {
3387
3486
  collectSortingAliasErrors(changes, "$.changes", hostBlockType, errors);
3388
3487
  collectDefaultFilterErrors(changes.defaultFilter, "$.changes.defaultFilter", errors, changesBlock, context);
3389
3488
  collectSemanticBindingErrors(changesBlock, hostBlockType, "$.changes", errors, context);
3489
+ collectCommentsBlockErrors(changesBlock, hostBlockType, "$.changes", errors, context);
3490
+ collectRecordHistoryBlockErrors(changesBlock, hostBlockType, "$.changes", errors, context);
3390
3491
  collectChartDisplayTitleErrors(changes, hostBlockType, "$.changes", errors);
3391
3492
  collectGridCardSettingsErrors(changes, hostBlockType, "$.changes", errors, { directSettings: true });
3392
3493
  collectAssignValuesErrors(changes.assignValues, "$.changes.assignValues", errors, changesBlock, context);
@@ -4083,6 +4184,184 @@ function collectSemanticBindingErrors(block, blockType, blockPath, errors, conte
4083
4184
  });
4084
4185
  });
4085
4186
  }
4187
+ function collectCommentsBlockErrors(block, blockType, blockPath, errors, context) {
4188
+ var _a;
4189
+ if (blockType !== "comments") {
4190
+ return;
4191
+ }
4192
+ const settings = _.isPlainObject(block.settings) ? block.settings : block;
4193
+ const settingsPath = _.isPlainObject(block.settings) ? `${blockPath}.settings` : blockPath;
4194
+ if (_.isPlainObject(settings) && hasOwnDefined(settings, "pageSize")) {
4195
+ const pageSize = Number(settings.pageSize);
4196
+ if (!COMMENTS_PAGE_SIZE_VALUES.has(pageSize)) {
4197
+ pushAuthoringError(errors, {
4198
+ path: `${settingsPath}.pageSize`,
4199
+ ruleId: "comments-pageSize-unsupported",
4200
+ message: `flowSurfaces authoring ${settingsPath}.pageSize must be one of ${Array.from(
4201
+ COMMENTS_PAGE_SIZE_VALUES
4202
+ ).join(", ")}`
4203
+ });
4204
+ }
4205
+ }
4206
+ const binding = getResourceBinding(block);
4207
+ if (context.isPopupSurface) {
4208
+ if (binding && binding !== "associatedrecords") {
4209
+ const rawBinding = String(((_a = block == null ? void 0 : block.resource) == null ? void 0 : _a.binding) || (block == null ? void 0 : block.binding) || "").trim() || (binding === "currentrecord" ? "currentRecord" : binding);
4210
+ pushAuthoringError(errors, {
4211
+ path: `${blockPath}.resource.binding`,
4212
+ ruleId: "comments-popup-binding-unsupported",
4213
+ message: `flowSurfaces authoring ${blockPath} comments blocks in popups do not support resource.binding='${rawBinding}'; use resource.binding='associatedRecords'`
4214
+ });
4215
+ return;
4216
+ }
4217
+ if (binding === "associatedrecords") {
4218
+ collectCommentsAssociationFieldErrors(block, blockPath, errors, context);
4219
+ }
4220
+ return;
4221
+ }
4222
+ if (binding === "associatedrecords" || binding === "currentrecord") {
4223
+ pushAuthoringError(errors, {
4224
+ path: `${blockPath}.resource.binding`,
4225
+ ruleId: "comments-page-binding-unsupported",
4226
+ message: `flowSurfaces authoring ${blockPath} comments blocks outside popups require a direct comment template collection resource`
4227
+ });
4228
+ return;
4229
+ }
4230
+ const collection = getBlockCollection(block, context);
4231
+ if (collection && !isCommentTemplateCollection(collection)) {
4232
+ pushAuthoringError(errors, {
4233
+ path: `${blockPath}.resource.collectionName`,
4234
+ ruleId: "comments-collection-template-required",
4235
+ message: `flowSurfaces authoring ${blockPath} comments block requires a comment template collection`,
4236
+ details: {
4237
+ collection: (0, import_service_helpers.getCollectionName)(collection)
4238
+ }
4239
+ });
4240
+ }
4241
+ }
4242
+ function collectCommentsAssociationFieldErrors(block, blockPath, errors, context) {
4243
+ const associationFieldName = getResourceAssociationFieldName(block);
4244
+ if (!associationFieldName || !context.getCollection) {
4245
+ return;
4246
+ }
4247
+ const sourceCollectionName = String(context.currentCollectionName || context.hostCollectionName || "").trim();
4248
+ if (!sourceCollectionName) {
4249
+ return;
4250
+ }
4251
+ const dataSourceKey = getBlockDataSourceKey(block, context);
4252
+ const sourceCollection = context.getCollection(dataSourceKey, sourceCollectionName);
4253
+ const associationField = sourceCollection ? (0, import_service_helpers.resolveFieldFromCollection)(sourceCollection, (0, import_service_helpers.normalizeFieldPath)(associationFieldName)) : null;
4254
+ if (!associationField || !(0, import_service_helpers.isAssociationField)(associationField)) {
4255
+ return;
4256
+ }
4257
+ const fieldType = String((0, import_service_helpers.getFieldType)(associationField) || "").trim().toLowerCase();
4258
+ const targetCollection = (0, import_service_helpers.resolveFieldTargetCollection)(
4259
+ associationField,
4260
+ dataSourceKey,
4261
+ (nextDataSourceKey, collectionName) => {
4262
+ var _a;
4263
+ return (_a = context.getCollection) == null ? void 0 : _a.call(context, nextDataSourceKey, collectionName);
4264
+ }
4265
+ );
4266
+ if ((fieldType === "hasmany" || fieldType === "belongstomany") && targetCollection && isCommentTemplateCollection(targetCollection)) {
4267
+ return;
4268
+ }
4269
+ pushAuthoringError(errors, {
4270
+ path: `${blockPath}.resource.associationField`,
4271
+ ruleId: "comments-association-field-unsupported",
4272
+ message: `flowSurfaces authoring ${blockPath} associationField '${associationFieldName}' is not available; comments popup blocks require a hasMany or belongsToMany associationField targeting a comment template collection`,
4273
+ details: {
4274
+ associationField: associationFieldName,
4275
+ fieldType,
4276
+ targetCollection: (0, import_service_helpers.getCollectionName)(targetCollection)
4277
+ }
4278
+ });
4279
+ }
4280
+ function collectRecordHistoryBlockErrors(block, blockType, blockPath, errors, context) {
4281
+ if (blockType !== "recordHistory") {
4282
+ return;
4283
+ }
4284
+ const settings = _.isPlainObject(block.settings) ? block.settings : block;
4285
+ const settingsPath = _.isPlainObject(block.settings) ? `${blockPath}.settings` : blockPath;
4286
+ collectRecordHistorySettingsErrors(settings, settingsPath, errors);
4287
+ const binding = getResourceBinding(block);
4288
+ if (binding === "associatedrecords") {
4289
+ pushAuthoringError(errors, {
4290
+ path: `${blockPath}.resource.binding`,
4291
+ ruleId: "recordHistory-association-resource-unsupported",
4292
+ message: `flowSurfaces authoring ${blockPath} recordHistory blocks do not support resource.binding='associatedRecords'`
4293
+ });
4294
+ }
4295
+ if (binding === "currentrecord" && (!context.isPopupSurface || context.popupScene !== "one")) {
4296
+ pushAuthoringError(errors, {
4297
+ path: `${blockPath}.resource.binding`,
4298
+ ruleId: "recordHistory-currentRecord-popup-required",
4299
+ message: `flowSurfaces authoring ${blockPath} recordHistory resource.binding='currentRecord' is only supported in one-record popup/details scenes`
4300
+ });
4301
+ }
4302
+ const collectionName = getBlockCollectionName(block, context);
4303
+ if (!collectionName) {
4304
+ return;
4305
+ }
4306
+ if (RECORD_HISTORY_INTERNAL_COLLECTIONS.has(collectionName)) {
4307
+ pushAuthoringError(errors, {
4308
+ path: `${blockPath}.resource.collectionName`,
4309
+ ruleId: "recordHistory-internal-collection-unsupported",
4310
+ message: `flowSurfaces authoring ${blockPath} recordHistory does not support internal collection '${collectionName}'`
4311
+ });
4312
+ return;
4313
+ }
4314
+ const collection = getBlockCollection(block, context);
4315
+ if (!collection) {
4316
+ return;
4317
+ }
4318
+ const filterTargetKey = getRecordHistoryDeclaredFilterTargetKey(collection);
4319
+ if (!filterTargetKey || !collectionHasConcreteField(collection, filterTargetKey)) {
4320
+ pushAuthoringError(errors, {
4321
+ path: `${blockPath}.resource.collectionName`,
4322
+ ruleId: "recordHistory-filterTargetKey-required",
4323
+ message: `flowSurfaces authoring ${blockPath} recordHistory requires a real filterTargetKey`,
4324
+ details: {
4325
+ collection: collectionName,
4326
+ filterTargetKey
4327
+ }
4328
+ });
4329
+ }
4330
+ }
4331
+ function collectRecordHistorySettingsErrors(settings, settingsPath, errors) {
4332
+ var _a;
4333
+ if (!_.isPlainObject(settings)) {
4334
+ return;
4335
+ }
4336
+ if (hasOwnDefined(settings, "sortOrder")) {
4337
+ const order = String(((_a = settings.sortOrder) == null ? void 0 : _a.order) || "").trim();
4338
+ if (!_.isPlainObject(settings.sortOrder) || order !== "asc" && order !== "desc") {
4339
+ pushAuthoringError(errors, {
4340
+ path: `${settingsPath}.sortOrder.order`,
4341
+ ruleId: "recordHistory-sortOrder-unsupported",
4342
+ message: `flowSurfaces authoring ${settingsPath}.sortOrder.order must be 'asc' or 'desc'`
4343
+ });
4344
+ }
4345
+ }
4346
+ if (hasOwnDefined(settings, "expand")) {
4347
+ if (!_.isPlainObject(settings.expand) || typeof settings.expand.expand !== "boolean") {
4348
+ pushAuthoringError(errors, {
4349
+ path: `${settingsPath}.expand.expand`,
4350
+ ruleId: "recordHistory-expand-invalid",
4351
+ message: `flowSurfaces authoring ${settingsPath}.expand.expand must be a boolean`
4352
+ });
4353
+ }
4354
+ }
4355
+ if (hasOwnDefined(settings, "template")) {
4356
+ if (!_.isPlainObject(settings.template) || settings.template.apply !== "current") {
4357
+ pushAuthoringError(errors, {
4358
+ path: `${settingsPath}.template.apply`,
4359
+ ruleId: "recordHistory-template-unsupported",
4360
+ message: `flowSurfaces authoring ${settingsPath}.template only supports apply='current'`
4361
+ });
4362
+ }
4363
+ }
4364
+ }
4086
4365
  function collectChartDisplayTitleErrors(block, blockType, blockPath, errors) {
4087
4366
  if (blockType !== "chart" || !_.isPlainObject((block == null ? void 0 : block.settings) || block)) {
4088
4367
  return;
@@ -5350,10 +5629,39 @@ function getResourceBinding(block) {
5350
5629
  var _a;
5351
5630
  return String(((_a = block == null ? void 0 : block.resource) == null ? void 0 : _a.binding) || (block == null ? void 0 : block.binding) || "").trim().toLowerCase();
5352
5631
  }
5632
+ function getResourceAssociationFieldName(block) {
5633
+ var _a, _b;
5634
+ return String(
5635
+ (block == null ? void 0 : block.associationField) || ((_a = block == null ? void 0 : block.resource) == null ? void 0 : _a.associationField) || ((_b = block == null ? void 0 : block.resource) == null ? void 0 : _b.associationPathName) || ""
5636
+ ).trim();
5637
+ }
5353
5638
  function getFieldTargetName(field) {
5354
5639
  var _a;
5355
5640
  return String((field == null ? void 0 : field.target) || ((_a = field == null ? void 0 : field.options) == null ? void 0 : _a.target) || "").trim();
5356
5641
  }
5642
+ function isCommentTemplateCollection(collection) {
5643
+ var _a;
5644
+ return (collection == null ? void 0 : collection.template) === "comment" || ((_a = collection == null ? void 0 : collection.options) == null ? void 0 : _a.template) === "comment";
5645
+ }
5646
+ function getRecordHistoryDeclaredFilterTargetKey(collection) {
5647
+ var _a, _b;
5648
+ const raw = Array.isArray(collection == null ? void 0 : collection.filterTargetKey) ? collection.filterTargetKey[0] : !_.isUndefined(collection == null ? void 0 : collection.filterTargetKey) ? collection.filterTargetKey : Array.isArray((_a = collection == null ? void 0 : collection.options) == null ? void 0 : _a.filterTargetKey) ? collection.options.filterTargetKey[0] : (_b = collection == null ? void 0 : collection.options) == null ? void 0 : _b.filterTargetKey;
5649
+ return String(raw || "").trim();
5650
+ }
5651
+ function collectionHasConcreteField(collection, fieldName) {
5652
+ var _a, _b, _c, _d, _e, _f;
5653
+ const normalized = String(fieldName || "").trim();
5654
+ if (!normalized) {
5655
+ return false;
5656
+ }
5657
+ const modelAttributes = (typeof ((_a = collection == null ? void 0 : collection.model) == null ? void 0 : _a.getAttributes) === "function" ? collection.model.getAttributes() : null) || ((_b = collection == null ? void 0 : collection.model) == null ? void 0 : _b.rawAttributes) || ((_c = collection == null ? void 0 : collection.model) == null ? void 0 : _c.attributes) || {};
5658
+ const primaryKeyAttributes = _.castArray(
5659
+ ((_d = collection == null ? void 0 : collection.model) == null ? void 0 : _d.primaryKeyAttributes) || ((_e = collection == null ? void 0 : collection.model) == null ? void 0 : _e.primaryKeyAttribute) || []
5660
+ );
5661
+ const modelAttribute = modelAttributes == null ? void 0 : modelAttributes[normalized];
5662
+ const isModelPrimaryKey = primaryKeyAttributes.includes(normalized) || !!(modelAttribute == null ? void 0 : modelAttribute.primaryKey);
5663
+ return !!((0, import_service_helpers.resolveFieldFromCollection)(collection, normalized) || ((_f = collection == null ? void 0 : collection.getField) == null ? void 0 : _f.call(collection, normalized)) || (0, import_service_helpers.getCollectionFields)(collection).some((field) => (0, import_service_helpers.getFieldName)(field) === normalized) || isModelPrimaryKey);
5664
+ }
5357
5665
  function collectDefaultFilterFieldPathError(rawFieldPath, path, block, context, errors) {
5358
5666
  const fieldPath = String(rawFieldPath || "").trim();
5359
5667
  if (!fieldPath || fieldPath.startsWith("$") || fieldPath.startsWith("{{")) {
@@ -67,6 +67,8 @@ const APPLY_BLUEPRINT_BLOCK_TYPE_ENUM = [
67
67
  "markdown",
68
68
  "iframe",
69
69
  "chart",
70
+ "comments",
71
+ "recordHistory",
70
72
  "actionPanel",
71
73
  "jsBlock",
72
74
  "tree"
@@ -169,7 +171,7 @@ const APPLY_BLUEPRINT_BLOCK_RESOURCE_SHORTHAND_KEYS = [
169
171
  "binding",
170
172
  "associationField"
171
173
  ];
172
- const APPLY_BLUEPRINT_RECORD_CAPABLE_BLOCK_TYPES = /* @__PURE__ */ new Set(["table", "details", "list", "gridCard"]);
174
+ const APPLY_BLUEPRINT_RECORD_CAPABLE_BLOCK_TYPES = /* @__PURE__ */ new Set(["table", "details", "list", "gridCard", "comments"]);
173
175
  const APPLY_BLUEPRINT_FIELD_GRID_BLOCK_TYPES = /* @__PURE__ */ new Set(["createForm", "editForm", "details", "filterForm"]);
174
176
  const APPLY_BLUEPRINT_FIELD_GROUP_BLOCK_TYPES = /* @__PURE__ */ new Set(["createForm", "editForm", "details"]);
175
177
  const APPLY_BLUEPRINT_AUTO_PROMOTED_RECORD_ACTION_TYPES = /* @__PURE__ */ new Set([
@@ -182,6 +184,7 @@ const APPLY_BLUEPRINT_AUTO_PROMOTED_RECORD_ACTION_TYPES = /* @__PURE__ */ new Se
182
184
  const APPLY_BLUEPRINT_DEFAULT_POPUP_ACTION_TYPES = /* @__PURE__ */ new Set(["addNew", "addChild", "view", "edit"]);
183
185
  const APPLY_BLUEPRINT_BLOCK_TYPES = new Set(APPLY_BLUEPRINT_BLOCK_TYPE_ENUM);
184
186
  const APPLY_BLUEPRINT_ADD_CHILD_RECORD_ACTION_ERROR = "type 'addChild' must be authored under recordActions and is only valid when the live target catalog.recordActions exposes it for a tree collection table with treeTable enabled";
187
+ const AI_EMPLOYEE_ACTION_TYPE = "aiEmployee";
185
188
  function assertNoBlockLevelLayout(input, context) {
186
189
  if (Object.prototype.hasOwnProperty.call(input, "layout")) {
187
190
  (0, import_errors.throwBadRequest)(`${context}.layout is not supported; layout is only allowed on tabs[] and popup`);
@@ -1452,6 +1455,58 @@ function collectTreeConnectTargetKeys(settings, context) {
1452
1455
  return normalizedTarget;
1453
1456
  }).filter(Boolean);
1454
1457
  }
1458
+ function collectAIEmployeeWorkContextTargetKeys(value, context) {
1459
+ if (import_lodash.default.isUndefined(value) || value === null) {
1460
+ return [];
1461
+ }
1462
+ if (!Array.isArray(value)) {
1463
+ (0, import_errors.throwBadRequest)(`${context} must be an array`);
1464
+ }
1465
+ return value.map((item, index) => {
1466
+ if (!import_lodash.default.isPlainObject(item)) {
1467
+ (0, import_errors.throwBadRequest)(`${context}[${index}] must be an object`);
1468
+ }
1469
+ if (!Object.prototype.hasOwnProperty.call(item, "target")) {
1470
+ return "";
1471
+ }
1472
+ if (typeof item.target !== "string") {
1473
+ (0, import_errors.throwBadRequest)(`${context}[${index}].target must be 'self' or a string block key`);
1474
+ }
1475
+ const normalizedTarget = item.target.trim();
1476
+ if (!normalizedTarget || normalizedTarget === "self") {
1477
+ return "";
1478
+ }
1479
+ return (0, import_service_utils.normalizeFlowSurfaceComposeKey)(normalizedTarget, `${context}[${index}].target`);
1480
+ }).filter(Boolean);
1481
+ }
1482
+ function collectAIEmployeeActionSettingsTargetKeys(settings, context) {
1483
+ if (!import_lodash.default.isPlainObject(settings)) {
1484
+ return [];
1485
+ }
1486
+ const targets = [];
1487
+ if (Object.prototype.hasOwnProperty.call(settings, "workContext")) {
1488
+ targets.push(...collectAIEmployeeWorkContextTargetKeys(settings.workContext, `${context}.workContext`));
1489
+ }
1490
+ if (Object.prototype.hasOwnProperty.call(settings, "tasks")) {
1491
+ if (!Array.isArray(settings.tasks)) {
1492
+ (0, import_errors.throwBadRequest)(`${context}.tasks must be an array`);
1493
+ }
1494
+ settings.tasks.forEach((task, taskIndex) => {
1495
+ if (!import_lodash.default.isPlainObject(task)) {
1496
+ (0, import_errors.throwBadRequest)(`${context}.tasks[${taskIndex}] must be an object`);
1497
+ }
1498
+ if (import_lodash.default.isPlainObject(task.message) && Object.prototype.hasOwnProperty.call(task.message, "workContext")) {
1499
+ targets.push(
1500
+ ...collectAIEmployeeWorkContextTargetKeys(
1501
+ task.message.workContext,
1502
+ `${context}.tasks[${taskIndex}].message.workContext`
1503
+ )
1504
+ );
1505
+ }
1506
+ });
1507
+ }
1508
+ return targets;
1509
+ }
1455
1510
  function compileTreeConnectSettingsTargets(settings, localBlockKeys, context) {
1456
1511
  if (!import_lodash.default.isPlainObject(settings == null ? void 0 : settings.connectFields) || !Array.isArray(settings.connectFields.targets)) {
1457
1512
  return settings;
@@ -1472,6 +1527,73 @@ function compileTreeConnectSettingsTargets(settings, localBlockKeys, context) {
1472
1527
  });
1473
1528
  return nextSettings;
1474
1529
  }
1530
+ function compileAIEmployeeWorkContextTargets(value, localBlockKeys, context) {
1531
+ if (import_lodash.default.isUndefined(value) || value === null) {
1532
+ return [];
1533
+ }
1534
+ if (!Array.isArray(value)) {
1535
+ (0, import_errors.throwBadRequest)(`${context} must be an array`);
1536
+ }
1537
+ return value.map((item, index) => {
1538
+ if (!import_lodash.default.isPlainObject(item)) {
1539
+ (0, import_errors.throwBadRequest)(`${context}[${index}] must be an object`);
1540
+ }
1541
+ if (!Object.prototype.hasOwnProperty.call(item, "target")) {
1542
+ return item;
1543
+ }
1544
+ if (typeof item.target !== "string") {
1545
+ (0, import_errors.throwBadRequest)(`${context}[${index}].target must be 'self' or a string block key`);
1546
+ }
1547
+ const normalizedTarget = item.target.trim();
1548
+ if (!normalizedTarget || normalizedTarget === "self") {
1549
+ return item;
1550
+ }
1551
+ return {
1552
+ ...item,
1553
+ target: resolveTargetBlockKey(item.target, localBlockKeys, `${context}[${index}].target`)
1554
+ };
1555
+ });
1556
+ }
1557
+ function compileAIEmployeeActionSettingsTargets(settings, localBlockKeys, context) {
1558
+ if (!import_lodash.default.isPlainObject(settings)) {
1559
+ return settings;
1560
+ }
1561
+ let nextSettings = settings;
1562
+ if (Object.prototype.hasOwnProperty.call(settings, "workContext")) {
1563
+ nextSettings = nextSettings === settings ? import_lodash.default.cloneDeep(settings) : nextSettings;
1564
+ nextSettings.workContext = compileAIEmployeeWorkContextTargets(
1565
+ settings.workContext,
1566
+ localBlockKeys,
1567
+ `${context}.settings.workContext`
1568
+ );
1569
+ }
1570
+ if (Object.prototype.hasOwnProperty.call(settings, "tasks")) {
1571
+ if (!Array.isArray(settings.tasks)) {
1572
+ (0, import_errors.throwBadRequest)(`${context}.settings.tasks must be an array`);
1573
+ }
1574
+ nextSettings = nextSettings === settings ? import_lodash.default.cloneDeep(settings) : nextSettings;
1575
+ nextSettings.tasks = settings.tasks.map((task, taskIndex) => {
1576
+ if (!import_lodash.default.isPlainObject(task)) {
1577
+ (0, import_errors.throwBadRequest)(`${context}.settings.tasks[${taskIndex}] must be an object`);
1578
+ }
1579
+ if (!import_lodash.default.isPlainObject(task.message) || !Object.prototype.hasOwnProperty.call(task.message, "workContext")) {
1580
+ return task;
1581
+ }
1582
+ return {
1583
+ ...task,
1584
+ message: {
1585
+ ...task.message,
1586
+ workContext: compileAIEmployeeWorkContextTargets(
1587
+ task.message.workContext,
1588
+ localBlockKeys,
1589
+ `${context}.settings.tasks[${taskIndex}].message.workContext`
1590
+ )
1591
+ }
1592
+ };
1593
+ });
1594
+ }
1595
+ return nextSettings;
1596
+ }
1475
1597
  function compileField(input, index, scopePrefix, assets, localBlockKeys, context, popupDefaultsMetadata, defaults, getCollection, popupOptions = {}) {
1476
1598
  if (typeof input === "string") {
1477
1599
  const fieldPath2 = (0, import_private_utils.assertNonEmptyString)(input, `${context}[${index}]`);
@@ -1549,7 +1671,7 @@ function compileField(input, index, scopePrefix, assets, localBlockKeys, context
1549
1671
  popup
1550
1672
  });
1551
1673
  }
1552
- function compileAction(input, index, scopePrefix, assets, context, popupDefaultsMetadata, defaults, getCollection, options = {}) {
1674
+ function compileAction(input, index, scopePrefix, assets, localBlockKeys, context, popupDefaultsMetadata, defaults, getCollection, options = {}) {
1553
1675
  var _a, _b, _c, _d, _e, _f;
1554
1676
  const buildActionKey = (localKey2, isExplicit, keyContext) => {
1555
1677
  const key2 = (0, import_service_utils.normalizeFlowSurfaceComposeKey)((0, import_private_utils.buildScopedKey)(scopePrefix, localKey2), keyContext);
@@ -1589,9 +1711,12 @@ function compileAction(input, index, scopePrefix, assets, context, popupDefaults
1589
1711
  const localKey = (0, import_private_utils.normalizeBlueprintLocalKey)(input.key, `${type}_${index + 1}`, `${context}[${index}].key`);
1590
1712
  const key = buildActionKey(localKey, !!hasExplicitKey, `${context}[${index}].key`);
1591
1713
  let settings = resolveAssetSettings(input.settings, input, assets, `${context}[${index}]`);
1592
- if ((0, import_private_utils.readOptionalString)(input.title) && import_lodash.default.isUndefined(settings.title)) {
1714
+ if (type !== AI_EMPLOYEE_ACTION_TYPE && (0, import_private_utils.readOptionalString)(input.title) && import_lodash.default.isUndefined(settings.title)) {
1593
1715
  settings.title = (0, import_private_utils.readOptionalString)(input.title);
1594
1716
  }
1717
+ if (type === AI_EMPLOYEE_ACTION_TYPE) {
1718
+ settings = compileAIEmployeeActionSettingsTargets(settings, localBlockKeys, `${context}[${index}]`);
1719
+ }
1595
1720
  const popupResult = compilePopup(input.popup, `${key}.popup`, assets, `${context}[${index}].popup`, defaults, {
1596
1721
  ownerActionType: type,
1597
1722
  getCollection,
@@ -1734,6 +1859,19 @@ function compileBlocks(input, scopePrefix, assets, context, defaults, requiredEx
1734
1859
  (0, import_service_utils.normalizeFlowSurfaceComposeKey)(field.target, `${context}[${index}].fields[${fieldIndex}].target`)
1735
1860
  );
1736
1861
  });
1862
+ const collectActionTargets = (items, slot) => {
1863
+ items.forEach((action, actionIndex) => {
1864
+ if (readApplyBlueprintActionType(action) !== AI_EMPLOYEE_ACTION_TYPE || !import_lodash.default.isPlainObject(action)) {
1865
+ return;
1866
+ }
1867
+ collectAIEmployeeActionSettingsTargetKeys(
1868
+ action.settings,
1869
+ `${context}[${index}].${slot}[${actionIndex}]`
1870
+ ).forEach((targetKey) => referencedBlockKeys.add(targetKey));
1871
+ });
1872
+ };
1873
+ collectActionTargets(readOptionalItems(block.actions, `${context}[${index}].actions`), "actions");
1874
+ collectActionTargets(readOptionalItems(block.recordActions, `${context}[${index}].recordActions`), "recordActions");
1737
1875
  });
1738
1876
  rawBlocks.forEach((block, index) => {
1739
1877
  if (!import_lodash.default.isPlainObject(block)) {
@@ -1876,6 +2014,7 @@ function compileBlocks(input, scopePrefix, assets, context, defaults, requiredEx
1876
2014
  actionIndex,
1877
2015
  key,
1878
2016
  assets,
2017
+ blockKeysByLocalKey,
1879
2018
  `${blockContext}.actions`,
1880
2019
  popupDefaultsMetadata,
1881
2020
  defaults,
@@ -1900,6 +2039,7 @@ function compileBlocks(input, scopePrefix, assets, context, defaults, requiredEx
1900
2039
  actionIndex,
1901
2040
  key,
1902
2041
  assets,
2042
+ blockKeysByLocalKey,
1903
2043
  `${blockContext}.recordActions`,
1904
2044
  popupDefaultsMetadata,
1905
2045
  defaults,
@@ -170,7 +170,7 @@ export type FlowSurfaceApplyBlueprintActionObjectSpec = {
170
170
  chart?: string;
171
171
  };
172
172
  export type FlowSurfaceApplyBlueprintActionSpec = string | FlowSurfaceApplyBlueprintActionObjectSpec;
173
- export type FlowSurfaceApplyBlueprintBlockType = 'table' | 'createForm' | 'editForm' | 'details' | 'filterForm' | 'calendar' | 'kanban' | 'list' | 'gridCard' | 'markdown' | 'iframe' | 'chart' | 'actionPanel' | 'jsBlock' | 'tree';
173
+ export type FlowSurfaceApplyBlueprintBlockType = 'table' | 'createForm' | 'editForm' | 'details' | 'filterForm' | 'calendar' | 'kanban' | 'list' | 'gridCard' | 'markdown' | 'iframe' | 'chart' | 'comments' | 'recordHistory' | 'actionPanel' | 'jsBlock' | 'tree';
174
174
  export type FlowSurfaceApplyBlueprintBlockSpec = {
175
175
  key?: string;
176
176
  type?: FlowSurfaceApplyBlueprintBlockType;