@nocobase/plugin-flow-engine 2.1.0-alpha.45 → 2.1.0-alpha.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/index.js +1 -1
- package/dist/externalVersion.js +9 -9
- package/dist/node_modules/@ant-design/icons-svg/package.json +1 -1
- package/dist/node_modules/acorn/package.json +1 -1
- package/dist/node_modules/acorn-jsx/package.json +1 -1
- package/dist/node_modules/acorn-walk/package.json +1 -1
- package/dist/node_modules/ses/package.json +1 -1
- package/dist/node_modules/zod/package.json +1 -1
- package/dist/server/flow-surfaces/apply/compiler.js +10 -11
- package/dist/server/flow-surfaces/authoring-validation.d.ts +1 -0
- package/dist/server/flow-surfaces/authoring-validation.js +773 -26
- package/dist/server/flow-surfaces/blueprint/normalize-document.js +5 -1
- package/dist/server/flow-surfaces/catalog.js +9 -5
- package/dist/server/flow-surfaces/chart-config.js +220 -16
- package/dist/server/flow-surfaces/contract-guard.js +40 -6
- package/dist/server/flow-surfaces/default-block-actions.js +2 -0
- package/dist/server/flow-surfaces/errors.d.ts +15 -0
- package/dist/server/flow-surfaces/errors.js +49 -3
- package/dist/server/flow-surfaces/event-flow-normalizer.d.ts +19 -0
- package/dist/server/flow-surfaces/event-flow-normalizer.js +128 -0
- package/dist/server/flow-surfaces/filter-group.d.ts +9 -1
- package/dist/server/flow-surfaces/filter-group.js +402 -3
- package/dist/server/flow-surfaces/public-data-surface-default-filter.js +2 -1
- package/dist/server/flow-surfaces/route-sync.js +19 -2
- package/dist/server/flow-surfaces/runjs-authoring/ast/bindings.d.ts +66 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/bindings.js +661 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/execution.d.ts +20 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/execution.js +275 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/parser.d.ts +16 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/parser.js +130 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/react-values.d.ts +20 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/react-values.js +401 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/request-config.d.ts +21 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/request-config.js +199 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/source.d.ts +70 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/source.js +895 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/static-bindings.d.ts +23 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/static-bindings.js +618 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/static-values.d.ts +196 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/static-values.js +1777 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/walk.d.ts +10 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/walk.js +55 -0
- package/dist/server/flow-surfaces/runjs-authoring/collectors.d.ts +12 -0
- package/dist/server/flow-surfaces/runjs-authoring/collectors.js +589 -0
- package/dist/server/flow-surfaces/runjs-authoring/index.d.ts +2 -25
- package/dist/server/flow-surfaces/runjs-authoring/index.js +5 -11138
- package/dist/server/flow-surfaces/runjs-authoring/inspect.d.ts +13 -0
- package/dist/server/flow-surfaces/runjs-authoring/inspect.js +149 -0
- package/dist/server/flow-surfaces/runjs-authoring/internal-types.d.ts +333 -0
- package/dist/server/flow-surfaces/runjs-authoring/internal-types.js +36 -0
- package/dist/server/flow-surfaces/runjs-authoring/rules.js +2 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/constants.d.ts +67 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/constants.js +757 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/errors.d.ts +22 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/errors.js +91 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/source-budget.d.ts +16 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/source-budget.js +115 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/surface.d.ts +19 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/surface.js +140 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/types.d.ts +91 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/types.js +24 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/ctx-api.d.ts +138 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/ctx-api.js +1779 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/filter.d.ts +10 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/filter.js +1583 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/index.d.ts +195 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/index.js +463 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/react-render.d.ts +48 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/react-render.js +379 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/react.d.ts +26 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/react.js +1441 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/resource.d.ts +23 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/resource.js +1427 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/source-patterns.d.ts +91 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/source-patterns.js +889 -0
- package/dist/server/flow-surfaces/runjs-authoring/types.d.ts +1 -1
- package/dist/server/flow-surfaces/runjs-authoring/unknown-global-stop/index.d.ts +10 -0
- package/dist/server/flow-surfaces/runjs-authoring/unknown-global-stop/index.js +40 -0
- package/dist/server/flow-surfaces/runjs-authoring/validators/index.d.ts +12 -0
- package/dist/server/flow-surfaces/runjs-authoring/validators/index.js +887 -0
- package/dist/server/flow-surfaces/service-helpers.d.ts +29 -0
- package/dist/server/flow-surfaces/service-helpers.js +105 -0
- package/dist/server/flow-surfaces/service-utils.d.ts +15 -3
- package/dist/server/flow-surfaces/service-utils.js +6 -5
- package/dist/server/flow-surfaces/service.d.ts +7 -1
- package/dist/server/flow-surfaces/service.js +488 -94
- package/dist/server/flow-surfaces/types.d.ts +3 -0
- package/dist/server/repository.d.ts +12 -1
- package/dist/server/repository.js +195 -23
- package/dist/swagger/flow-surfaces.d.ts +175 -0
- package/dist/swagger/flow-surfaces.js +130 -51
- package/dist/swagger/index.d.ts +175 -0
- package/package.json +2 -2
|
@@ -60,6 +60,7 @@ var import_association_interfaces = require("./association-interfaces");
|
|
|
60
60
|
var import_defaults = require("./blueprint/defaults");
|
|
61
61
|
var import_runjs_authoring = require("./runjs-authoring");
|
|
62
62
|
var import_configure_options = require("./configure-options");
|
|
63
|
+
var import_filter_group = require("./filter-group");
|
|
63
64
|
const MAIN_BLOCK_UNSUPPORTED_SECTIONS = {
|
|
64
65
|
calendar: ["fields", "fieldGroups", "recordActions", "fieldsLayout"],
|
|
65
66
|
kanban: ["fieldGroups", "recordActions", "fieldsLayout"],
|
|
@@ -83,6 +84,13 @@ const VISIBLE_FIELD_REQUIRED_DATA_BLOCK_TYPES = /* @__PURE__ */ new Set([
|
|
|
83
84
|
"kanban"
|
|
84
85
|
]);
|
|
85
86
|
const VISIBLE_FIELD_MINIMUM_DATA_BLOCK_TYPES = /* @__PURE__ */ new Set(["table", "list", "gridCard", "details"]);
|
|
87
|
+
const IMPLICIT_RELATION_TITLE_FIELD_DISPLAY_BLOCK_TYPES = /* @__PURE__ */ new Set(["table", "list", "gridCard", "details"]);
|
|
88
|
+
const IMPLICIT_RELATION_TITLE_FIELD_CONTAINER_USE_BY_BLOCK_TYPE = {
|
|
89
|
+
details: "DetailsItemModel",
|
|
90
|
+
gridCard: "GridCardItemModel",
|
|
91
|
+
list: "ListItemModel",
|
|
92
|
+
table: "TableColumnModel"
|
|
93
|
+
};
|
|
86
94
|
const RICH_COLLECTION_VISIBLE_FIELD_THRESHOLD = import_public_data_surface_default_filter.FLOW_SURFACE_DEFAULT_FILTER_REQUIRED_FIELD_COUNT * 2;
|
|
87
95
|
const RICH_DATA_BLOCK_VISIBLE_FIELD_MINIMUM = 3;
|
|
88
96
|
const NON_BUSINESS_VISIBLE_FIELD_NAMES = /* @__PURE__ */ new Set([
|
|
@@ -163,10 +171,36 @@ const JS_BLOCK_ALLOWED_SETTINGS_KEYS = /* @__PURE__ */ new Set(["title", "descri
|
|
|
163
171
|
const JS_BLOCK_TOP_LEVEL_JS_KEYS = ["code", "version"];
|
|
164
172
|
const JS_BLOCK_INTERNAL_AUTHORING_KEYS = ["props", "decoratorProps", "flowRegistry", "stepParams"];
|
|
165
173
|
const JS_BLOCK_REPAIR_HINT = "This is a jsBlock payload shape problem. Repair this jsBlock using inline settings.code/settings.version, or applyBlueprint assets.scripts.<key>.code plus block.script. Do not change this block type to table, chart, actionPanel, gridCard, or another block type.";
|
|
166
|
-
const CHART_REPAIR_HINT = "This is a chart payload shape problem.
|
|
174
|
+
const CHART_REPAIR_HINT = "This is a chart payload shape problem. Keep using chart and repair this chart using assets.charts.<key>.query/visual plus block.chart, or localized settings.query/settings.visual. Do not change this block type to table, jsBlock, actionPanel, gridCard, or another block type, and do not drop or defer the chart. KPI / summary numbers should use jsBlock; charts are for trends, distributions, rankings, and visual analysis.";
|
|
175
|
+
const REPAIR_ALL_ERRORS_AGENT_INSTRUCTION = "If this response contains errors[], fix every listed error in one payload revision before retrying the same write. Do not fix only this error and immediately retry.";
|
|
176
|
+
const JS_BLOCK_AGENT_INSTRUCTION = `${REPAIR_ALL_ERRORS_AGENT_INSTRUCTION} Do not skip, drop, defer, or replace this required jsBlock. Repair it as jsBlock.`;
|
|
177
|
+
const CHART_AGENT_INSTRUCTION = `${REPAIR_ALL_ERRORS_AGENT_INSTRUCTION} Do not skip, drop, defer, or replace this required chart. Repair it as chart.`;
|
|
178
|
+
const VISIBLE_DATA_BLOCK_FIELDS_REPAIR_HINT = "Add direct visible collection fields to this block. Do not rely on defaults.collections.*.fieldGroups, action-only fields, dividers, or generated popup/form defaults as a substitute for visible block fields.";
|
|
179
|
+
const JS_BLOCK_FORBIDDEN_FALLBACKS = [
|
|
180
|
+
"table",
|
|
181
|
+
"list",
|
|
182
|
+
"chart",
|
|
183
|
+
"actionPanel",
|
|
184
|
+
"gridCard",
|
|
185
|
+
"markdown",
|
|
186
|
+
"drop jsBlock",
|
|
187
|
+
"defer jsBlock"
|
|
188
|
+
];
|
|
189
|
+
const CHART_FORBIDDEN_FALLBACKS = [
|
|
190
|
+
"table",
|
|
191
|
+
"list",
|
|
192
|
+
"jsBlock",
|
|
193
|
+
"actionPanel",
|
|
194
|
+
"gridCard",
|
|
195
|
+
"markdown",
|
|
196
|
+
"drop chart",
|
|
197
|
+
"defer chart"
|
|
198
|
+
];
|
|
167
199
|
const CHART_QUERY_MODE_SET = new Set(import_chart_config.CHART_QUERY_MODES);
|
|
168
200
|
const CHART_VISUAL_MODE_SET = new Set(import_chart_config.CHART_VISUAL_MODES);
|
|
169
201
|
const CHART_BASIC_VISUAL_TYPE_SET = new Set(import_chart_config.CHART_BASIC_VISUAL_TYPES);
|
|
202
|
+
const CHART_BASIC_VISUAL_TYPE_LIST = import_chart_config.CHART_BASIC_VISUAL_TYPES.join(", ");
|
|
203
|
+
const STRICT_LOCALIZED_CHART_ACTIONS = /* @__PURE__ */ new Set(["compose", "addBlocks"]);
|
|
170
204
|
const CHART_VISUAL_LEGACY_BUILDER_KEYS = /* @__PURE__ */ new Set([
|
|
171
205
|
"xField",
|
|
172
206
|
"yField",
|
|
@@ -201,6 +235,7 @@ const CHART_SQL_QUERY_FORBIDDEN_KEYS = /* @__PURE__ */ new Set([
|
|
|
201
235
|
"offset"
|
|
202
236
|
]);
|
|
203
237
|
const CHART_CUSTOM_VISUAL_FORBIDDEN_KEYS = /* @__PURE__ */ new Set(["type", "mappings", "style"]);
|
|
238
|
+
const CHART_DEFAULT_DATA_SOURCE_KEY = "main";
|
|
204
239
|
const JS_ITEM_COLLECTION_ACTION_HOST_BLOCK_TYPES = /* @__PURE__ */ new Set(["table", "list", "gridCard", "calendar", "kanban"]);
|
|
205
240
|
const JS_ITEM_RECORD_ACTION_HOST_BLOCK_TYPES = /* @__PURE__ */ new Set(["table", "details", "list", "gridCard"]);
|
|
206
241
|
const JS_ITEM_FORM_ACTION_HOST_BLOCK_TYPES = /* @__PURE__ */ new Set(["createForm", "editForm"]);
|
|
@@ -396,6 +431,14 @@ async function collectFlowSurfaceAuthoringErrors(actionName, values, context = {
|
|
|
396
431
|
if (!_.isPlainObject(values)) {
|
|
397
432
|
return errors;
|
|
398
433
|
}
|
|
434
|
+
validationContext.getDefaultFieldGroups = validationContext.getDefaultFieldGroups || ((dataSourceKey, collectionName) => {
|
|
435
|
+
var _a2;
|
|
436
|
+
return (_a2 = (0, import_defaults.resolveFlowSurfaceApplyBlueprintDefaultCollection)({
|
|
437
|
+
metadata: values == null ? void 0 : values.defaults,
|
|
438
|
+
dataSourceKey,
|
|
439
|
+
collectionName
|
|
440
|
+
}).collectionDefaults) == null ? void 0 : _a2.fieldGroups;
|
|
441
|
+
});
|
|
399
442
|
if (actionName === "applyBlueprint" && _.isPlainObject((_a = values == null ? void 0 : values.assets) == null ? void 0 : _a.scripts)) {
|
|
400
443
|
validationContext.applyBlueprintScriptAssets = values.assets.scripts;
|
|
401
444
|
}
|
|
@@ -408,7 +451,7 @@ async function collectFlowSurfaceAuthoringErrors(actionName, values, context = {
|
|
|
408
451
|
collectApplyBlueprintChartAssetErrors(actionName, values, validationContext, errors);
|
|
409
452
|
if (actionName === "configure") {
|
|
410
453
|
await collectConfigureErrors(values, errors, validationContext);
|
|
411
|
-
|
|
454
|
+
appendRunJsAuthoringErrors(actionName, values, validationContext, errors);
|
|
412
455
|
if (!validationContext.skipGeneratedPopupDefaultFieldGroups) {
|
|
413
456
|
collectGeneratedPopupDefaultFieldGroupErrors(actionName, values, validationContext, errors);
|
|
414
457
|
}
|
|
@@ -429,9 +472,42 @@ async function collectFlowSurfaceAuthoringErrors(actionName, values, context = {
|
|
|
429
472
|
if (!validationContext.skipGeneratedPopupDefaultFieldGroups) {
|
|
430
473
|
collectGeneratedPopupDefaultFieldGroupErrors(actionName, values, validationContext, errors);
|
|
431
474
|
}
|
|
432
|
-
|
|
475
|
+
appendRunJsAuthoringErrors(actionName, values, validationContext, errors);
|
|
433
476
|
return errors;
|
|
434
477
|
}
|
|
478
|
+
function appendRunJsAuthoringErrors(actionName, values, context, errors) {
|
|
479
|
+
try {
|
|
480
|
+
errors.push(...(0, import_runjs_authoring.collectRunJsAuthoringErrors)(actionName, values, context));
|
|
481
|
+
} catch (error) {
|
|
482
|
+
if (shouldKeepExistingChartAuthoringErrors(error, errors)) {
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
if (isChartBadRequestError(error)) {
|
|
486
|
+
pushChartBadRequestAuthoringError(errors, error, actionName === "configure" ? "$.changes" : "$");
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
throw error;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
function isChartBadRequestError(error) {
|
|
493
|
+
return error instanceof import_errors.FlowSurfaceBadRequestError && String(error.message || "").startsWith("chart ");
|
|
494
|
+
}
|
|
495
|
+
function shouldKeepExistingChartAuthoringErrors(error, errors) {
|
|
496
|
+
return isChartBadRequestError(error) && errors.some((item) => {
|
|
497
|
+
var _a;
|
|
498
|
+
return ((_a = item.details) == null ? void 0 : _a.repairHint) === CHART_REPAIR_HINT;
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
function pushChartBadRequestAuthoringError(errors, error, fallbackPath) {
|
|
502
|
+
var _a, _b, _c;
|
|
503
|
+
const details = _.isPlainObject((_a = error.options) == null ? void 0 : _a.details) ? error.options.details : {};
|
|
504
|
+
pushAuthoringError(errors, {
|
|
505
|
+
path: typeof ((_b = error.options) == null ? void 0 : _b.path) === "string" && error.options.path ? error.options.path : fallbackPath,
|
|
506
|
+
ruleId: typeof ((_c = error.options) == null ? void 0 : _c.ruleId) === "string" && error.options.ruleId ? error.options.ruleId : "chart-configure-invalid",
|
|
507
|
+
message: error.message,
|
|
508
|
+
details: withChartRepairHint(details)
|
|
509
|
+
});
|
|
510
|
+
}
|
|
435
511
|
async function collectNavigationGroupErrors(actionName, values, context, errors) {
|
|
436
512
|
var _a;
|
|
437
513
|
if (actionName !== "applyBlueprint" || (values == null ? void 0 : values.mode) !== "create" || !_.isPlainObject((_a = values == null ? void 0 : values.navigation) == null ? void 0 : _a.group)) {
|
|
@@ -644,13 +720,41 @@ function collectChartAssetBlockTreeErrors(block, path, chartAssets, errors) {
|
|
|
644
720
|
function withJsBlockRepairHint(details = {}) {
|
|
645
721
|
return {
|
|
646
722
|
...details,
|
|
647
|
-
|
|
723
|
+
requiredBlockType: "jsBlock",
|
|
724
|
+
fixStrategy: "repair_same_block_type",
|
|
725
|
+
repairHint: JS_BLOCK_REPAIR_HINT,
|
|
726
|
+
agentInstruction: JS_BLOCK_AGENT_INSTRUCTION,
|
|
727
|
+
repairExample: {
|
|
728
|
+
inlineBlock: {
|
|
729
|
+
type: "jsBlock",
|
|
730
|
+
settings: {
|
|
731
|
+
code: 'ctx.render("Replace this with the required rendered UI");'
|
|
732
|
+
}
|
|
733
|
+
},
|
|
734
|
+
assetBlock: {
|
|
735
|
+
assets: {
|
|
736
|
+
scripts: {
|
|
737
|
+
scriptKey: {
|
|
738
|
+
code: 'ctx.render("Replace this with the required rendered UI");'
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
},
|
|
742
|
+
block: {
|
|
743
|
+
type: "jsBlock",
|
|
744
|
+
script: "scriptKey"
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
},
|
|
748
|
+
forbiddenFallbacks: JS_BLOCK_FORBIDDEN_FALLBACKS
|
|
648
749
|
};
|
|
649
750
|
}
|
|
650
751
|
function withChartRepairHint(details = {}) {
|
|
651
752
|
return {
|
|
652
753
|
...details,
|
|
754
|
+
requiredBlockType: "chart",
|
|
755
|
+
fixStrategy: "repair_same_block_type",
|
|
653
756
|
repairHint: CHART_REPAIR_HINT,
|
|
757
|
+
agentInstruction: CHART_AGENT_INSTRUCTION,
|
|
654
758
|
repairSteps: [
|
|
655
759
|
"Keep the block type as chart.",
|
|
656
760
|
"Define assets.charts.<key>.query and assets.charts.<key>.visual.",
|
|
@@ -658,6 +762,58 @@ function withChartRepairHint(details = {}) {
|
|
|
658
762
|
"Retry the chart payload instead of replacing the chart with another block type or omitting it."
|
|
659
763
|
],
|
|
660
764
|
expectedShape: {
|
|
765
|
+
settings: {
|
|
766
|
+
query: {
|
|
767
|
+
mode: "builder",
|
|
768
|
+
resource: {
|
|
769
|
+
dataSourceKey: "main",
|
|
770
|
+
collectionName: "employees"
|
|
771
|
+
},
|
|
772
|
+
measures: [
|
|
773
|
+
{
|
|
774
|
+
field: "id",
|
|
775
|
+
aggregation: "count",
|
|
776
|
+
alias: "employeeCount"
|
|
777
|
+
}
|
|
778
|
+
]
|
|
779
|
+
},
|
|
780
|
+
visual: {
|
|
781
|
+
mode: "basic",
|
|
782
|
+
type: "bar",
|
|
783
|
+
mappings: {
|
|
784
|
+
x: "status",
|
|
785
|
+
y: "employeeCount"
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
},
|
|
789
|
+
legacySettings: {
|
|
790
|
+
configure: {
|
|
791
|
+
query: {
|
|
792
|
+
mode: "builder",
|
|
793
|
+
resource: {
|
|
794
|
+
dataSourceKey: "main",
|
|
795
|
+
collectionName: "employees"
|
|
796
|
+
},
|
|
797
|
+
measures: [
|
|
798
|
+
{
|
|
799
|
+
field: "id",
|
|
800
|
+
aggregation: "count",
|
|
801
|
+
alias: "employeeCount"
|
|
802
|
+
}
|
|
803
|
+
]
|
|
804
|
+
},
|
|
805
|
+
chart: {
|
|
806
|
+
option: {
|
|
807
|
+
mode: "basic",
|
|
808
|
+
builder: {
|
|
809
|
+
type: "bar",
|
|
810
|
+
xField: "status",
|
|
811
|
+
yField: "employeeCount"
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
},
|
|
661
817
|
assets: {
|
|
662
818
|
charts: {
|
|
663
819
|
chartKey: {
|
|
@@ -671,9 +827,245 @@ function withChartRepairHint(details = {}) {
|
|
|
671
827
|
chart: "chartKey"
|
|
672
828
|
}
|
|
673
829
|
},
|
|
674
|
-
|
|
830
|
+
repairExample: {
|
|
831
|
+
settings: {
|
|
832
|
+
query: {
|
|
833
|
+
mode: "builder",
|
|
834
|
+
resource: {
|
|
835
|
+
dataSourceKey: "main",
|
|
836
|
+
collectionName: "<collectionName>"
|
|
837
|
+
},
|
|
838
|
+
measures: [
|
|
839
|
+
{
|
|
840
|
+
field: "id",
|
|
841
|
+
aggregation: "count",
|
|
842
|
+
alias: "recordCount"
|
|
843
|
+
}
|
|
844
|
+
],
|
|
845
|
+
dimensions: [
|
|
846
|
+
{
|
|
847
|
+
field: "<dimensionField>"
|
|
848
|
+
}
|
|
849
|
+
]
|
|
850
|
+
},
|
|
851
|
+
visual: {
|
|
852
|
+
mode: "basic",
|
|
853
|
+
type: "bar",
|
|
854
|
+
mappings: {
|
|
855
|
+
x: "<dimensionField>",
|
|
856
|
+
y: "recordCount"
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
},
|
|
860
|
+
assets: {
|
|
861
|
+
charts: {
|
|
862
|
+
chartKey: {
|
|
863
|
+
query: {
|
|
864
|
+
mode: "builder",
|
|
865
|
+
resource: {
|
|
866
|
+
dataSourceKey: "main",
|
|
867
|
+
collectionName: "<collectionName>"
|
|
868
|
+
},
|
|
869
|
+
measures: [
|
|
870
|
+
{
|
|
871
|
+
field: "id",
|
|
872
|
+
aggregation: "count",
|
|
873
|
+
alias: "recordCount"
|
|
874
|
+
}
|
|
875
|
+
],
|
|
876
|
+
dimensions: [
|
|
877
|
+
{
|
|
878
|
+
field: "<dimensionField>"
|
|
879
|
+
}
|
|
880
|
+
]
|
|
881
|
+
},
|
|
882
|
+
visual: {
|
|
883
|
+
mode: "basic",
|
|
884
|
+
type: "bar",
|
|
885
|
+
mappings: {
|
|
886
|
+
x: "<dimensionField>",
|
|
887
|
+
y: "recordCount"
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
},
|
|
893
|
+
block: {
|
|
894
|
+
type: "chart",
|
|
895
|
+
chart: "chartKey"
|
|
896
|
+
}
|
|
897
|
+
},
|
|
898
|
+
forbiddenFallbacks: CHART_FORBIDDEN_FALLBACKS
|
|
899
|
+
};
|
|
900
|
+
}
|
|
901
|
+
function withUnsupportedChartVisualTypeHint(details = {}) {
|
|
902
|
+
const jsBlockHint = `Supported basic chart visual types are: ${CHART_BASIC_VISUAL_TYPE_LIST}. If the required visualization cannot be represented by these chart types, use a jsBlock instead.`;
|
|
903
|
+
return {
|
|
904
|
+
...details,
|
|
905
|
+
fixStrategy: "use_supported_chart_type_or_jsBlock",
|
|
906
|
+
repairHint: jsBlockHint,
|
|
907
|
+
agentInstruction: `${REPAIR_ALL_ERRORS_AGENT_INSTRUCTION} Use one of the supported chart visual types, or use a jsBlock when the requested visualization is outside the chart plugin capabilities.`,
|
|
908
|
+
supportedVisualTypes: [...import_chart_config.CHART_BASIC_VISUAL_TYPES],
|
|
909
|
+
alternativeBlockType: "jsBlock",
|
|
910
|
+
alternativeHint: jsBlockHint,
|
|
911
|
+
forbiddenFallbacks: CHART_FORBIDDEN_FALLBACKS.filter((item) => item !== "jsBlock")
|
|
912
|
+
};
|
|
913
|
+
}
|
|
914
|
+
function collectLocalizedChartSettingsErrors(block, blockType, path, errors, context) {
|
|
915
|
+
if (blockType !== "chart" || !STRICT_LOCALIZED_CHART_ACTIONS.has(context.authoringActionName)) {
|
|
916
|
+
return;
|
|
917
|
+
}
|
|
918
|
+
const settingsPath = `${path}.settings`;
|
|
919
|
+
if (!_.isUndefined(block.settings) && !_.isPlainObject(block.settings)) {
|
|
920
|
+
pushAuthoringError(errors, {
|
|
921
|
+
path: settingsPath,
|
|
922
|
+
ruleId: "chart-localized-settings-invalid",
|
|
923
|
+
message: `flowSurfaces authoring ${settingsPath} must be an object for compose/addBlocks chart blocks`,
|
|
924
|
+
details: withChartRepairHint()
|
|
925
|
+
});
|
|
926
|
+
return;
|
|
927
|
+
}
|
|
928
|
+
const settings = _.isPlainObject(block.settings) ? block.settings : {};
|
|
929
|
+
if (hasOwn(settings, "configure")) {
|
|
930
|
+
if (["query", "visual", "events"].some((key) => hasOwn(settings, key))) {
|
|
931
|
+
pushAuthoringError(errors, {
|
|
932
|
+
path: settingsPath,
|
|
933
|
+
ruleId: "chart-localized-settings-mixed-configure",
|
|
934
|
+
message: `flowSurfaces authoring ${settingsPath} cannot mix legacy configure with query/visual/events`,
|
|
935
|
+
details: withChartRepairHint()
|
|
936
|
+
});
|
|
937
|
+
return;
|
|
938
|
+
}
|
|
939
|
+
collectLocalizedLegacyChartConfigureErrors(settings.configure, `${settingsPath}.configure`, errors);
|
|
940
|
+
return;
|
|
941
|
+
}
|
|
942
|
+
if (!hasOwn(settings, "query") && !hasOwn(settings, "visual")) {
|
|
943
|
+
return;
|
|
944
|
+
}
|
|
945
|
+
collectChartAssetQueryErrors(settings, settingsPath, context, errors);
|
|
946
|
+
collectChartAssetVisualErrors(settings, settingsPath, errors);
|
|
947
|
+
}
|
|
948
|
+
function collectLocalizedLegacyChartConfigureErrors(configure, path, errors) {
|
|
949
|
+
if (!_.isPlainObject(configure)) {
|
|
950
|
+
pushAuthoringError(errors, {
|
|
951
|
+
path,
|
|
952
|
+
ruleId: "chart-configure-invalid",
|
|
953
|
+
message: `flowSurfaces authoring ${path} must be an object`,
|
|
954
|
+
details: withChartRepairHint()
|
|
955
|
+
});
|
|
956
|
+
return;
|
|
957
|
+
}
|
|
958
|
+
collectLegacyChartQueryCompatibilityErrors(configure.query, `${path}.query`, errors);
|
|
959
|
+
}
|
|
960
|
+
function collectLegacyChartQueryCompatibilityErrors(query, path, errors) {
|
|
961
|
+
if (!_.isPlainObject(query)) {
|
|
962
|
+
return;
|
|
963
|
+
}
|
|
964
|
+
collectChartQueryFilterOperatorErrors(query, path, errors);
|
|
965
|
+
const hasResource = hasOwn(query, "resource");
|
|
966
|
+
const hasCollectionPath = hasOwn(query, "collectionPath");
|
|
967
|
+
if (!hasResource && !hasCollectionPath) {
|
|
968
|
+
return;
|
|
969
|
+
}
|
|
970
|
+
const resource = hasResource ? normalizeLegacyChartResourceForValidation(query.resource, `${path}.resource`, errors) : void 0;
|
|
971
|
+
const collectionPathResource = hasCollectionPath ? normalizeLegacyChartCollectionPathResourceForValidation(query.collectionPath, `${path}.collectionPath`, errors) : void 0;
|
|
972
|
+
if (hasResource && hasCollectionPath && resource && collectionPathResource && !_.isEqual(resource, collectionPathResource)) {
|
|
973
|
+
pushAuthoringError(errors, {
|
|
974
|
+
path,
|
|
975
|
+
ruleId: "chart-legacy-query-resource-conflict",
|
|
976
|
+
message: `flowSurfaces authoring ${path}.resource and ${path}.collectionPath must reference the same collection`,
|
|
977
|
+
details: withChartRepairHint({
|
|
978
|
+
resource,
|
|
979
|
+
collectionPathResource
|
|
980
|
+
})
|
|
981
|
+
});
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
function normalizeLegacyChartCollectionPathResource(collectionPath) {
|
|
985
|
+
if (!Array.isArray(collectionPath)) {
|
|
986
|
+
return void 0;
|
|
987
|
+
}
|
|
988
|
+
const collectionName = normalizeLegacyChartRequiredString(collectionPath[1]);
|
|
989
|
+
if (!collectionName) {
|
|
990
|
+
return void 0;
|
|
991
|
+
}
|
|
992
|
+
const dataSourceKey = normalizeLegacyChartCollectionPathDataSourceKey(collectionPath[0]);
|
|
993
|
+
if (!dataSourceKey) {
|
|
994
|
+
return void 0;
|
|
995
|
+
}
|
|
996
|
+
return {
|
|
997
|
+
dataSourceKey,
|
|
998
|
+
collectionName
|
|
999
|
+
};
|
|
1000
|
+
}
|
|
1001
|
+
function normalizeLegacyChartResourceForValidation(resource, path, errors) {
|
|
1002
|
+
if (!_.isPlainObject(resource)) {
|
|
1003
|
+
pushAuthoringError(errors, {
|
|
1004
|
+
path,
|
|
1005
|
+
ruleId: "chart-legacy-query-resource-invalid",
|
|
1006
|
+
message: `flowSurfaces authoring ${path} must be an object with string collectionName`,
|
|
1007
|
+
details: withChartRepairHint()
|
|
1008
|
+
});
|
|
1009
|
+
return void 0;
|
|
1010
|
+
}
|
|
1011
|
+
const collectionName = normalizeLegacyChartRequiredString(resource.collectionName);
|
|
1012
|
+
if (!collectionName) {
|
|
1013
|
+
pushAuthoringError(errors, {
|
|
1014
|
+
path: `${path}.collectionName`,
|
|
1015
|
+
ruleId: "chart-legacy-query-resource-invalid",
|
|
1016
|
+
message: `flowSurfaces authoring ${path}.collectionName must be a non-empty string`,
|
|
1017
|
+
details: withChartRepairHint()
|
|
1018
|
+
});
|
|
1019
|
+
return void 0;
|
|
1020
|
+
}
|
|
1021
|
+
const dataSourceKey = normalizeLegacyChartResourceDataSourceKey(resource.dataSourceKey);
|
|
1022
|
+
if (!dataSourceKey) {
|
|
1023
|
+
pushAuthoringError(errors, {
|
|
1024
|
+
path: `${path}.dataSourceKey`,
|
|
1025
|
+
ruleId: "chart-legacy-query-resource-invalid",
|
|
1026
|
+
message: `flowSurfaces authoring ${path}.dataSourceKey must be a non-empty string when provided`,
|
|
1027
|
+
details: withChartRepairHint()
|
|
1028
|
+
});
|
|
1029
|
+
return void 0;
|
|
1030
|
+
}
|
|
1031
|
+
return {
|
|
1032
|
+
dataSourceKey,
|
|
1033
|
+
collectionName
|
|
675
1034
|
};
|
|
676
1035
|
}
|
|
1036
|
+
function normalizeLegacyChartCollectionPathResourceForValidation(collectionPath, path, errors) {
|
|
1037
|
+
const resource = normalizeLegacyChartCollectionPathResource(collectionPath);
|
|
1038
|
+
if (!resource) {
|
|
1039
|
+
pushAuthoringError(errors, {
|
|
1040
|
+
path,
|
|
1041
|
+
ruleId: "chart-legacy-query-collection-path-invalid",
|
|
1042
|
+
message: `flowSurfaces authoring ${path} must be [dataSourceKey, collectionName] with string values and a non-empty collectionName`,
|
|
1043
|
+
details: withChartRepairHint()
|
|
1044
|
+
});
|
|
1045
|
+
}
|
|
1046
|
+
return resource;
|
|
1047
|
+
}
|
|
1048
|
+
function normalizeLegacyChartRequiredString(input) {
|
|
1049
|
+
if (typeof input !== "string") {
|
|
1050
|
+
return void 0;
|
|
1051
|
+
}
|
|
1052
|
+
return input.trim() || void 0;
|
|
1053
|
+
}
|
|
1054
|
+
function normalizeLegacyChartResourceDataSourceKey(input) {
|
|
1055
|
+
if (_.isUndefined(input) || _.isNull(input)) {
|
|
1056
|
+
return CHART_DEFAULT_DATA_SOURCE_KEY;
|
|
1057
|
+
}
|
|
1058
|
+
return normalizeLegacyChartRequiredString(input);
|
|
1059
|
+
}
|
|
1060
|
+
function normalizeLegacyChartCollectionPathDataSourceKey(input) {
|
|
1061
|
+
if (_.isUndefined(input) || _.isNull(input)) {
|
|
1062
|
+
return CHART_DEFAULT_DATA_SOURCE_KEY;
|
|
1063
|
+
}
|
|
1064
|
+
if (typeof input === "string" && !input.trim()) {
|
|
1065
|
+
return CHART_DEFAULT_DATA_SOURCE_KEY;
|
|
1066
|
+
}
|
|
1067
|
+
return normalizeLegacyChartRequiredString(input);
|
|
1068
|
+
}
|
|
677
1069
|
function collectChartBlockAssetReferenceErrors(block, path, chartAssets, errors) {
|
|
678
1070
|
if (!CHART_BLOCK_TYPES.has(String((block == null ? void 0 : block.type) || "").trim())) {
|
|
679
1071
|
return;
|
|
@@ -781,8 +1173,85 @@ function collectBuilderChartAssetQueryErrors(query, path, context, errors) {
|
|
|
781
1173
|
errors,
|
|
782
1174
|
withChartRepairHint()
|
|
783
1175
|
);
|
|
1176
|
+
collectChartQueryFilterOperatorErrors(query, `${path}.query`, errors);
|
|
784
1177
|
collectBuilderChartAssetFieldErrors(query, path, context, errors);
|
|
785
1178
|
}
|
|
1179
|
+
function collectChartQueryFilterOperatorErrors(query, path, errors) {
|
|
1180
|
+
if (!_.isPlainObject(query) || !hasOwn(query, "filter")) {
|
|
1181
|
+
return;
|
|
1182
|
+
}
|
|
1183
|
+
collectChartFilterOperatorErrors(query.filter, `${path}.filter`, errors);
|
|
1184
|
+
}
|
|
1185
|
+
function collectChartFilterOperatorErrors(filter, path, errors) {
|
|
1186
|
+
if (_.isUndefined(filter) || _.isNull(filter) || !_.isPlainObject(filter)) {
|
|
1187
|
+
return;
|
|
1188
|
+
}
|
|
1189
|
+
if (Array.isArray(filter.items)) {
|
|
1190
|
+
collectChartFilterGroupOperatorErrors(filter.items, `${path}.items`, errors);
|
|
1191
|
+
return;
|
|
1192
|
+
}
|
|
1193
|
+
collectBackendQueryFilterOperatorErrors(filter, path, errors);
|
|
1194
|
+
}
|
|
1195
|
+
function collectChartFilterGroupOperatorErrors(items, path, errors) {
|
|
1196
|
+
items.forEach((item, index) => {
|
|
1197
|
+
const itemPath = `${path}[${index}]`;
|
|
1198
|
+
if (!_.isPlainObject(item)) {
|
|
1199
|
+
return;
|
|
1200
|
+
}
|
|
1201
|
+
if (Array.isArray(item.items)) {
|
|
1202
|
+
collectChartFilterGroupOperatorErrors(item.items, `${itemPath}.items`, errors);
|
|
1203
|
+
return;
|
|
1204
|
+
}
|
|
1205
|
+
if (hasOwn(item, "operator")) {
|
|
1206
|
+
collectChartFilterOperatorError(item.operator, `${itemPath}.operator`, errors);
|
|
1207
|
+
collectChartFilterDateValueError(item.operator, item.value, `${itemPath}.value`, errors);
|
|
1208
|
+
}
|
|
1209
|
+
});
|
|
1210
|
+
}
|
|
1211
|
+
function collectBackendQueryFilterOperatorErrors(filter, path, errors) {
|
|
1212
|
+
Object.entries(filter).forEach(([field, condition]) => {
|
|
1213
|
+
const fieldPath = `${path}.${field}`;
|
|
1214
|
+
if ((field === "$and" || field === "$or") && Array.isArray(condition)) {
|
|
1215
|
+
condition.forEach(
|
|
1216
|
+
(operand, index) => collectChartFilterOperatorErrors(operand, `${fieldPath}[${index}]`, errors)
|
|
1217
|
+
);
|
|
1218
|
+
return;
|
|
1219
|
+
}
|
|
1220
|
+
if (!_.isPlainObject(condition)) {
|
|
1221
|
+
return;
|
|
1222
|
+
}
|
|
1223
|
+
Object.keys(condition).forEach((operator) => {
|
|
1224
|
+
if (operator === "$and" || operator === "$or") {
|
|
1225
|
+
collectChartFilterOperatorErrors({ [operator]: condition[operator] }, fieldPath, errors);
|
|
1226
|
+
return;
|
|
1227
|
+
}
|
|
1228
|
+
collectChartFilterOperatorError(operator, `${fieldPath}.${operator}`, errors);
|
|
1229
|
+
collectChartFilterDateValueError(operator, condition[operator], `${fieldPath}.${operator}`, errors);
|
|
1230
|
+
});
|
|
1231
|
+
});
|
|
1232
|
+
}
|
|
1233
|
+
function collectChartFilterOperatorError(operator, path, errors) {
|
|
1234
|
+
try {
|
|
1235
|
+
(0, import_filter_group.assertFlowSurfaceFilterOperator)(operator, path);
|
|
1236
|
+
} catch (error) {
|
|
1237
|
+
if (error instanceof import_errors.FlowSurfaceBadRequestError) {
|
|
1238
|
+
pushChartBadRequestAuthoringError(errors, error, path);
|
|
1239
|
+
return;
|
|
1240
|
+
}
|
|
1241
|
+
throw error;
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
function collectChartFilterDateValueError(operator, value, path, errors) {
|
|
1245
|
+
try {
|
|
1246
|
+
(0, import_filter_group.normalizeFlowSurfaceStrictFilterDateValue)(operator, value, path);
|
|
1247
|
+
} catch (error) {
|
|
1248
|
+
if (error instanceof import_errors.FlowSurfaceBadRequestError) {
|
|
1249
|
+
pushChartBadRequestAuthoringError(errors, error, path);
|
|
1250
|
+
return;
|
|
1251
|
+
}
|
|
1252
|
+
throw error;
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
786
1255
|
function normalizeChartAssetFieldPath(input) {
|
|
787
1256
|
if (Array.isArray(input)) {
|
|
788
1257
|
return input.map((item) => String(item || "").trim()).filter(Boolean).join(".");
|
|
@@ -790,6 +1259,7 @@ function normalizeChartAssetFieldPath(input) {
|
|
|
790
1259
|
return String(input || "").trim();
|
|
791
1260
|
}
|
|
792
1261
|
function collectBuilderChartAssetFieldErrors(query, path, context, errors) {
|
|
1262
|
+
var _a, _b, _c, _d, _e;
|
|
793
1263
|
const resource = _.isPlainObject(query.resource) ? query.resource : null;
|
|
794
1264
|
const collectionName = String((resource == null ? void 0 : resource.collectionName) || "").trim();
|
|
795
1265
|
if (!collectionName || typeof context.getCollection !== "function") {
|
|
@@ -803,10 +1273,12 @@ function collectBuilderChartAssetFieldErrors(query, path, context, errors) {
|
|
|
803
1273
|
const selections = [
|
|
804
1274
|
..._.castArray(query.measures || []).map((selection, index) => ({
|
|
805
1275
|
selection,
|
|
1276
|
+
kind: "measure",
|
|
806
1277
|
fieldPath: `${path}.query.measures[${index}].field`
|
|
807
1278
|
})),
|
|
808
1279
|
..._.castArray(query.dimensions || []).map((selection, index) => ({
|
|
809
1280
|
selection,
|
|
1281
|
+
kind: "dimension",
|
|
810
1282
|
fieldPath: `${path}.query.dimensions[${index}].field`
|
|
811
1283
|
}))
|
|
812
1284
|
];
|
|
@@ -818,24 +1290,80 @@ function collectBuilderChartAssetFieldErrors(query, path, context, errors) {
|
|
|
818
1290
|
if (!fieldPath) {
|
|
819
1291
|
continue;
|
|
820
1292
|
}
|
|
1293
|
+
const fieldPathParts = fieldPath.split(".").filter(Boolean);
|
|
1294
|
+
const isCountMeasureSelection = item.kind === "measure" && String(((_a = item.selection) == null ? void 0 : _a.aggregation) || "").trim() === "count" && !((_b = item.selection) == null ? void 0 : _b.distinct);
|
|
1295
|
+
if (fieldPathParts.length > 1 && !isCountMeasureSelection) {
|
|
1296
|
+
const directAssociationPath = fieldPathParts[0];
|
|
1297
|
+
const directAssociationField = (0, import_service_helpers.resolveFieldFromCollection)(collection, directAssociationPath);
|
|
1298
|
+
const directAssociationTargetCollection = directAssociationField && (0, import_service_helpers.isAssociationField)(directAssociationField) ? (0, import_service_helpers.resolveFieldTargetCollection)(
|
|
1299
|
+
directAssociationField,
|
|
1300
|
+
dataSourceKey,
|
|
1301
|
+
(resolvedDataSourceKey, targetCollection) => {
|
|
1302
|
+
var _a2;
|
|
1303
|
+
return (_a2 = context.getCollection) == null ? void 0 : _a2.call(context, resolvedDataSourceKey, targetCollection);
|
|
1304
|
+
}
|
|
1305
|
+
) : null;
|
|
1306
|
+
const invalidDirectSubfield = directAssociationTargetCollection ? (0, import_service_helpers.getInvalidChartBuilderRelationDirectSubfieldDetails)({
|
|
1307
|
+
associationPathName: directAssociationPath,
|
|
1308
|
+
selectedSubfieldPath: fieldPathParts.slice(1).join("."),
|
|
1309
|
+
targetCollection: directAssociationTargetCollection
|
|
1310
|
+
}) : null;
|
|
1311
|
+
if (invalidDirectSubfield) {
|
|
1312
|
+
pushAuthoringError(errors, {
|
|
1313
|
+
path: item.fieldPath,
|
|
1314
|
+
ruleId: "chart-builder-query-relation-direct-subfield-required",
|
|
1315
|
+
message: `flowSurfaces authoring ${item.fieldPath} must reference a direct scalar child field under relation '${invalidDirectSubfield.associationPath}'. ${(0, import_service_helpers.formatChartBuilderSupportedRelationSubfields)(
|
|
1316
|
+
invalidDirectSubfield.associationPath,
|
|
1317
|
+
invalidDirectSubfield.supportedFields
|
|
1318
|
+
)}`,
|
|
1319
|
+
details: withChartRepairHint({
|
|
1320
|
+
fieldPath,
|
|
1321
|
+
dataSourceKey,
|
|
1322
|
+
collectionName,
|
|
1323
|
+
...invalidDirectSubfield
|
|
1324
|
+
})
|
|
1325
|
+
});
|
|
1326
|
+
continue;
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
821
1329
|
const field = (0, import_service_helpers.resolveFieldFromCollection)(collection, fieldPath);
|
|
1330
|
+
const associationPath = fieldPath.includes(".") ? fieldPath.split(".").slice(0, -1).join(".") : "";
|
|
1331
|
+
const leafFieldName = fieldPath.split(".").slice(-1)[0];
|
|
1332
|
+
const associationField = associationPath ? (0, import_service_helpers.resolveFieldFromCollection)(collection, associationPath) : null;
|
|
1333
|
+
const associationTargetCollection = associationField && (0, import_service_helpers.isAssociationField)(associationField) ? (0, import_service_helpers.resolveFieldTargetCollection)(
|
|
1334
|
+
associationField,
|
|
1335
|
+
dataSourceKey,
|
|
1336
|
+
(resolvedDataSourceKey, targetCollection) => {
|
|
1337
|
+
var _a2;
|
|
1338
|
+
return (_a2 = context.getCollection) == null ? void 0 : _a2.call(context, resolvedDataSourceKey, targetCollection);
|
|
1339
|
+
}
|
|
1340
|
+
) : null;
|
|
1341
|
+
const leafModelAttributes = (0, import_service_helpers.getCollectionModelAttributes)(associationTargetCollection || collection);
|
|
1342
|
+
const hasLeafModelAttribute = Object.prototype.hasOwnProperty.call(leafModelAttributes, leafFieldName);
|
|
1343
|
+
const isCountMeasureRelationSubfield = item.kind === "measure" && String(((_c = item.selection) == null ? void 0 : _c.aggregation) || "").trim() === "count" && !((_d = item.selection) == null ? void 0 : _d.distinct) && associationField && (0, import_service_helpers.isAssociationField)(associationField);
|
|
1344
|
+
const unsupportedRelationSubfield = associationTargetCollection ? (0, import_service_helpers.getUnsupportedChartBuilderRelationSubfieldDetails)({
|
|
1345
|
+
associationPathName: associationPath,
|
|
1346
|
+
leafFieldName,
|
|
1347
|
+
leafField: field,
|
|
1348
|
+
targetCollection: associationTargetCollection
|
|
1349
|
+
}) : null;
|
|
822
1350
|
if (!field) {
|
|
823
|
-
|
|
1351
|
+
const hasConcreteField = associationTargetCollection ? hasLeafModelAttribute || collectionHasConcreteField(associationTargetCollection, leafFieldName) : collectionHasConcreteField(collection, fieldPath);
|
|
1352
|
+
if (!hasConcreteField) {
|
|
1353
|
+
pushAuthoringError(errors, {
|
|
1354
|
+
path: item.fieldPath,
|
|
1355
|
+
ruleId: "chart-builder-query-field-unknown",
|
|
1356
|
+
message: `flowSurfaces authoring ${item.fieldPath} references unknown field '${fieldPath}' on collection '${dataSourceKey}.${collectionName}'`,
|
|
1357
|
+
details: withChartRepairHint({
|
|
1358
|
+
fieldPath,
|
|
1359
|
+
dataSourceKey,
|
|
1360
|
+
collectionName
|
|
1361
|
+
})
|
|
1362
|
+
});
|
|
824
1363
|
continue;
|
|
825
1364
|
}
|
|
826
|
-
pushAuthoringError(errors, {
|
|
827
|
-
path: item.fieldPath,
|
|
828
|
-
ruleId: "chart-builder-query-field-unknown",
|
|
829
|
-
message: `flowSurfaces authoring ${item.fieldPath} references unknown field '${fieldPath}' on collection '${dataSourceKey}.${collectionName}'`,
|
|
830
|
-
details: withChartRepairHint({
|
|
831
|
-
fieldPath,
|
|
832
|
-
dataSourceKey,
|
|
833
|
-
collectionName
|
|
834
|
-
})
|
|
835
|
-
});
|
|
836
|
-
continue;
|
|
837
1365
|
}
|
|
838
|
-
if (!fieldPath.includes(".") && (0, import_service_helpers.isAssociationField)(field)) {
|
|
1366
|
+
if (!fieldPath.includes(".") && field && (0, import_service_helpers.isAssociationField)(field)) {
|
|
839
1367
|
const suggestion = resolveChartBuilderAssociationSubfieldSuggestion(
|
|
840
1368
|
fieldPath,
|
|
841
1369
|
field,
|
|
@@ -854,6 +1382,43 @@ function collectBuilderChartAssetFieldErrors(query, path, context, errors) {
|
|
|
854
1382
|
})
|
|
855
1383
|
});
|
|
856
1384
|
}
|
|
1385
|
+
if (isCountMeasureRelationSubfield) {
|
|
1386
|
+
pushAuthoringError(errors, {
|
|
1387
|
+
path: item.fieldPath,
|
|
1388
|
+
ruleId: "chart-builder-query-count-measure-relation-subfield",
|
|
1389
|
+
message: `flowSurfaces authoring ${item.fieldPath} counts relation subfield '${fieldPath}'; count a scalar base field such as 'id' and keep '${fieldPath}' as a dimension`,
|
|
1390
|
+
details: withChartRepairHint({
|
|
1391
|
+
fieldPath,
|
|
1392
|
+
dataSourceKey,
|
|
1393
|
+
collectionName,
|
|
1394
|
+
suggestedMeasure: {
|
|
1395
|
+
field: "id",
|
|
1396
|
+
aggregation: "count",
|
|
1397
|
+
alias: String(((_e = item.selection) == null ? void 0 : _e.alias) || "").trim() || "recordCount"
|
|
1398
|
+
},
|
|
1399
|
+
suggestedDimension: {
|
|
1400
|
+
field: fieldPath
|
|
1401
|
+
}
|
|
1402
|
+
})
|
|
1403
|
+
});
|
|
1404
|
+
continue;
|
|
1405
|
+
}
|
|
1406
|
+
if (unsupportedRelationSubfield) {
|
|
1407
|
+
pushAuthoringError(errors, {
|
|
1408
|
+
path: item.fieldPath,
|
|
1409
|
+
ruleId: "chart-builder-query-relation-subfield-column-unsupported",
|
|
1410
|
+
message: `flowSurfaces authoring ${item.fieldPath} references relation subfield '${fieldPath}', but current chart builder SQL generation cannot query relation subfield '${unsupportedRelationSubfield.leafFieldName}' because its database column is '${unsupportedRelationSubfield.columnName}'. ${(0, import_service_helpers.formatChartBuilderSupportedRelationSubfields)(
|
|
1411
|
+
associationPath,
|
|
1412
|
+
unsupportedRelationSubfield.supportedFields
|
|
1413
|
+
)}`,
|
|
1414
|
+
details: withChartRepairHint({
|
|
1415
|
+
fieldPath,
|
|
1416
|
+
dataSourceKey,
|
|
1417
|
+
collectionName,
|
|
1418
|
+
...unsupportedRelationSubfield
|
|
1419
|
+
})
|
|
1420
|
+
});
|
|
1421
|
+
}
|
|
857
1422
|
}
|
|
858
1423
|
}
|
|
859
1424
|
function resolveChartBuilderAssociationSubfieldSuggestion(fieldPath, field, dataSourceKey, getCollection) {
|
|
@@ -953,8 +1518,8 @@ function collectChartAssetVisualErrors(asset, path, errors) {
|
|
|
953
1518
|
pushAuthoringError(errors, {
|
|
954
1519
|
path: `${path}.visual.type`,
|
|
955
1520
|
ruleId: "chart-visual-type-unsupported",
|
|
956
|
-
message: `flowSurfaces authoring ${path}.visual.type '${type}' is not supported
|
|
957
|
-
details:
|
|
1521
|
+
message: `flowSurfaces authoring ${path}.visual.type '${type}' is not supported. Supported basic chart visual types: ${CHART_BASIC_VISUAL_TYPE_LIST}. If these types do not satisfy the requirement, use a jsBlock instead.`,
|
|
1522
|
+
details: withUnsupportedChartVisualTypeHint({
|
|
958
1523
|
type
|
|
959
1524
|
})
|
|
960
1525
|
});
|
|
@@ -3385,10 +3950,13 @@ function collectBlockErrors(block, path, errors, localKeys, context) {
|
|
|
3385
3950
|
collectVisibleDataBlockFieldErrors(block, blockType, path, errors, context);
|
|
3386
3951
|
collectCommentsBlockErrors(block, blockType, path, errors, context);
|
|
3387
3952
|
collectRecordHistoryBlockErrors(block, blockType, path, errors, context);
|
|
3953
|
+
collectLocalizedChartSettingsErrors(block, blockType, path, errors, context);
|
|
3388
3954
|
collectChartDisplayTitleErrors(block, blockType, path, errors);
|
|
3389
3955
|
collectTreeTableExplicitFieldsErrors(block, blockType, path, errors, context);
|
|
3390
3956
|
collectTreeConnectFieldsErrors((_a = block.settings) == null ? void 0 : _a.connectFields, `${path}.settings.connectFields`, errors);
|
|
3391
|
-
collectTableSettingsErrors(block, blockType, path, errors
|
|
3957
|
+
collectTableSettingsErrors(block, blockType, path, errors, {
|
|
3958
|
+
deferPublicDataScopeErrors: context.authoringActionName === "addBlocks"
|
|
3959
|
+
});
|
|
3392
3960
|
collectGridCardSettingsErrors(block, blockType, path, errors);
|
|
3393
3961
|
const descendantContext = getBlockDescendantValidationContext(block, context);
|
|
3394
3962
|
collectActionListErrors(block.actions, `${path}.actions`, errors, block, descendantContext, "actions");
|
|
@@ -3646,6 +4214,7 @@ function collectFieldGroupsShapeErrors(fieldGroups, blockPath, errors, block, co
|
|
|
3646
4214
|
if (fieldPath) {
|
|
3647
4215
|
collectUnknownFieldPathError(fieldPath, itemPath, block, context, errors);
|
|
3648
4216
|
}
|
|
4217
|
+
collectImplicitRelationTitleFieldErrors(field, itemPath, block, context, errors);
|
|
3649
4218
|
if (!_.isPlainObject(field)) {
|
|
3650
4219
|
return;
|
|
3651
4220
|
}
|
|
@@ -3695,6 +4264,7 @@ async function collectConfigureErrors(values, errors, context) {
|
|
|
3695
4264
|
collectCommentsBlockErrors(changesBlock, hostBlockType, "$.changes", errors, context);
|
|
3696
4265
|
collectRecordHistoryBlockErrors(changesBlock, hostBlockType, "$.changes", errors, context);
|
|
3697
4266
|
collectChartDisplayTitleErrors(changes, hostBlockType, "$.changes", errors);
|
|
4267
|
+
collectChartConfigureFilterOperatorErrors(changes, hostBlockType, "$.changes", errors);
|
|
3698
4268
|
collectTableSettingsErrors(changes, hostBlockType, "$.changes", errors, { directSettings: true });
|
|
3699
4269
|
collectGridCardSettingsErrors(changes, hostBlockType, "$.changes", errors, { directSettings: true });
|
|
3700
4270
|
collectAssignValuesErrors(changes.assignValues, "$.changes.assignValues", errors, changesBlock, context);
|
|
@@ -3783,6 +4353,23 @@ function collectUnsupportedDefaultFilterOperatorError(operator, path, errors) {
|
|
|
3783
4353
|
}
|
|
3784
4354
|
});
|
|
3785
4355
|
}
|
|
4356
|
+
function collectDefaultFilterDateValueError(operator, value, path, errors) {
|
|
4357
|
+
var _a, _b, _c;
|
|
4358
|
+
try {
|
|
4359
|
+
(0, import_filter_group.normalizeFlowSurfaceStrictFilterDateValue)(operator, value, path);
|
|
4360
|
+
} catch (error) {
|
|
4361
|
+
if (!(error instanceof import_errors.FlowSurfaceBadRequestError)) {
|
|
4362
|
+
throw error;
|
|
4363
|
+
}
|
|
4364
|
+
const details = _.isPlainObject((_a = error.options) == null ? void 0 : _a.details) ? error.options.details : {};
|
|
4365
|
+
pushAuthoringError(errors, {
|
|
4366
|
+
path: typeof ((_b = error.options) == null ? void 0 : _b.path) === "string" && error.options.path ? error.options.path : path,
|
|
4367
|
+
ruleId: typeof ((_c = error.options) == null ? void 0 : _c.ruleId) === "string" && error.options.ruleId ? error.options.ruleId : "filter-group-date-value-invalid",
|
|
4368
|
+
message: error.message,
|
|
4369
|
+
details
|
|
4370
|
+
});
|
|
4371
|
+
}
|
|
4372
|
+
}
|
|
3786
4373
|
function collectTopLevelLayoutErrors(actionName, values, errors) {
|
|
3787
4374
|
if (actionName !== "applyBlueprint") {
|
|
3788
4375
|
return;
|
|
@@ -4377,6 +4964,8 @@ function collectVisibleDataBlockFieldErrors(block, blockType, path, errors, cont
|
|
|
4377
4964
|
blockType,
|
|
4378
4965
|
collection: getBlockCollectionName(block, context),
|
|
4379
4966
|
fieldCount: fieldEntries.length,
|
|
4967
|
+
repairHint: VISIBLE_DATA_BLOCK_FIELDS_REPAIR_HINT,
|
|
4968
|
+
agentInstruction: REPAIR_ALL_ERRORS_AGENT_INSTRUCTION,
|
|
4380
4969
|
...suggestedFields.length ? { suggestion: { fields: suggestedFields } } : {}
|
|
4381
4970
|
}
|
|
4382
4971
|
});
|
|
@@ -4410,6 +4999,8 @@ function collectVisibleDataBlockFieldErrors(block, blockType, path, errors, cont
|
|
|
4410
4999
|
fieldCount: validBusinessFieldNames.length,
|
|
4411
5000
|
requiredFieldCount,
|
|
4412
5001
|
eligibleBusinessFieldCount: eligibleBusinessFields.length,
|
|
5002
|
+
repairHint: VISIBLE_DATA_BLOCK_FIELDS_REPAIR_HINT,
|
|
5003
|
+
agentInstruction: REPAIR_ALL_ERRORS_AGENT_INSTRUCTION,
|
|
4413
5004
|
suggestion: {
|
|
4414
5005
|
fields: eligibleBusinessFields.slice(0, requiredFieldCount)
|
|
4415
5006
|
}
|
|
@@ -4783,6 +5374,15 @@ function collectChartDisplayTitleErrors(block, blockType, blockPath, errors) {
|
|
|
4783
5374
|
message: "Chart block settings do not support displayTitle in the current flowSurfaces runtime; keep settings.title and omit displayTitle."
|
|
4784
5375
|
});
|
|
4785
5376
|
}
|
|
5377
|
+
function collectChartConfigureFilterOperatorErrors(changes, hostBlockType, path, errors) {
|
|
5378
|
+
if (hostBlockType !== "chart" || !_.isPlainObject(changes)) {
|
|
5379
|
+
return;
|
|
5380
|
+
}
|
|
5381
|
+
collectChartQueryFilterOperatorErrors(changes.query, `${path}.query`, errors);
|
|
5382
|
+
if (_.isPlainObject(changes.configure)) {
|
|
5383
|
+
collectChartQueryFilterOperatorErrors(changes.configure.query, `${path}.configure.query`, errors);
|
|
5384
|
+
}
|
|
5385
|
+
}
|
|
4786
5386
|
function visitFilterItems(value, path, errors, block, context = {}) {
|
|
4787
5387
|
if (Array.isArray(value)) {
|
|
4788
5388
|
value.forEach((item, index) => visitFilterItems(item, `${path}[${index}]`, errors, block, context));
|
|
@@ -4797,6 +5397,7 @@ function visitFilterItems(value, path, errors, block, context = {}) {
|
|
|
4797
5397
|
}
|
|
4798
5398
|
if (typeof value.operator === "string") {
|
|
4799
5399
|
collectUnsupportedDefaultFilterOperatorError(value.operator, `${path}.operator`, errors);
|
|
5400
|
+
collectDefaultFilterDateValueError(value.operator, value.value, `${path}.value`, errors);
|
|
4800
5401
|
}
|
|
4801
5402
|
const filterItems = value.items;
|
|
4802
5403
|
if (Array.isArray(filterItems)) {
|
|
@@ -4820,8 +5421,9 @@ function visitFilterItems(value, path, errors, block, context = {}) {
|
|
|
4820
5421
|
}
|
|
4821
5422
|
collectDefaultFilterFieldPathError(key, `${path}.${key}`, block, context, errors);
|
|
4822
5423
|
if (_.isPlainObject(child)) {
|
|
4823
|
-
Object.
|
|
5424
|
+
Object.entries(child).forEach(([operator, operatorValue]) => {
|
|
4824
5425
|
collectUnsupportedDefaultFilterOperatorError(operator, `${path}.${key}.${operator}`, errors);
|
|
5426
|
+
collectDefaultFilterDateValueError(operator, operatorValue, `${path}.${key}.${operator}`, errors);
|
|
4825
5427
|
});
|
|
4826
5428
|
}
|
|
4827
5429
|
});
|
|
@@ -5198,6 +5800,9 @@ function collectTableSettingsErrors(block, blockType, blockPath, errors, options
|
|
|
5198
5800
|
}
|
|
5199
5801
|
pushTableSettingsUnsupportedError(errors, `${settingsPath}.${key}`, key);
|
|
5200
5802
|
});
|
|
5803
|
+
if (!shouldDeferPublicDataScopeErrorsToBatchItem(blockPath, errors, options)) {
|
|
5804
|
+
collectPublicDataScopeErrors(settings.dataScope, `${settingsPath}.dataScope`, errors);
|
|
5805
|
+
}
|
|
5201
5806
|
}
|
|
5202
5807
|
function pushTableSettingsUnsupportedError(errors, path, key) {
|
|
5203
5808
|
pushAuthoringError(errors, {
|
|
@@ -5211,6 +5816,47 @@ function pushTableSettingsUnsupportedError(errors, path, key) {
|
|
|
5211
5816
|
}
|
|
5212
5817
|
});
|
|
5213
5818
|
}
|
|
5819
|
+
function collectPublicDataScopeErrors(value, path, errors) {
|
|
5820
|
+
if (_.isUndefined(value)) {
|
|
5821
|
+
return;
|
|
5822
|
+
}
|
|
5823
|
+
if (value === null || _.isPlainObject(value) && !Object.keys(value).length) {
|
|
5824
|
+
return;
|
|
5825
|
+
}
|
|
5826
|
+
const validationValue = normalizePublicDataScopeValueForValidation(value);
|
|
5827
|
+
try {
|
|
5828
|
+
(0, import_filter_group.assertFlowSurfaceFilterGroupShape)(validationValue);
|
|
5829
|
+
} catch (error) {
|
|
5830
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
5831
|
+
pushAuthoringError(errors, {
|
|
5832
|
+
path,
|
|
5833
|
+
ruleId: "dataScope-filter-group-invalid-shape",
|
|
5834
|
+
message: `flowSurfaces authoring ${path} expects FilterGroup like ${import_filter_group.FLOW_SURFACE_FILTER_GROUP_EXAMPLE}: ${reason}`,
|
|
5835
|
+
details: {
|
|
5836
|
+
repairHint: 'Use settings.dataScope with logic/items, for example {"logic":"$and","items":[{"path":"status","operator":"$eq","value":"Active"}]}; do not use a field-name map.'
|
|
5837
|
+
}
|
|
5838
|
+
});
|
|
5839
|
+
}
|
|
5840
|
+
}
|
|
5841
|
+
function shouldDeferPublicDataScopeErrorsToBatchItem(blockPath, errors, options) {
|
|
5842
|
+
if (options.deferPublicDataScopeErrors !== true) {
|
|
5843
|
+
return false;
|
|
5844
|
+
}
|
|
5845
|
+
if (!/^\$\.blocks\[\d+\]$/.test(blockPath)) {
|
|
5846
|
+
return false;
|
|
5847
|
+
}
|
|
5848
|
+
return !errors.some((error) => error.path === `${blockPath}.settings.dataScope`);
|
|
5849
|
+
}
|
|
5850
|
+
function normalizePublicDataScopeValueForValidation(value) {
|
|
5851
|
+
if (!_.isPlainObject(value)) {
|
|
5852
|
+
return value;
|
|
5853
|
+
}
|
|
5854
|
+
const keys = Object.keys(value);
|
|
5855
|
+
if (keys.length === 1 && keys[0] === "filter") {
|
|
5856
|
+
return value.filter;
|
|
5857
|
+
}
|
|
5858
|
+
return value;
|
|
5859
|
+
}
|
|
5214
5860
|
function collectGridCardSettingsErrors(block, blockType, blockPath, errors, options = {}) {
|
|
5215
5861
|
const hasSettings = _.isPlainObject(block == null ? void 0 : block.settings);
|
|
5216
5862
|
if (!hasSettings && options.directSettings !== true) {
|
|
@@ -5851,6 +6497,7 @@ function collectFieldListErrors(fields, path, errors, localKeys, context, block)
|
|
|
5851
6497
|
if (fieldPath) {
|
|
5852
6498
|
collectUnknownFieldPathError(fieldPath, `${path}[${index}]`, block, context, errors);
|
|
5853
6499
|
}
|
|
6500
|
+
collectImplicitRelationTitleFieldErrors(field, `${path}[${index}]`, block, context, errors);
|
|
5854
6501
|
if (!_.isPlainObject(field)) {
|
|
5855
6502
|
return;
|
|
5856
6503
|
}
|
|
@@ -6171,6 +6818,106 @@ function collectRelationTitleFieldErrors(fieldSpec, path, block, context, errors
|
|
|
6171
6818
|
})
|
|
6172
6819
|
});
|
|
6173
6820
|
}
|
|
6821
|
+
function collectImplicitRelationTitleFieldErrors(fieldSpec, path, block, context, errors) {
|
|
6822
|
+
var _a;
|
|
6823
|
+
if (context.authoringActionName !== "applyBlueprint") {
|
|
6824
|
+
return;
|
|
6825
|
+
}
|
|
6826
|
+
const hostBlockType = String((block == null ? void 0 : block.type) || "").trim();
|
|
6827
|
+
if (!IMPLICIT_RELATION_TITLE_FIELD_DISPLAY_BLOCK_TYPES.has(hostBlockType)) {
|
|
6828
|
+
return;
|
|
6829
|
+
}
|
|
6830
|
+
if (_.isPlainObject(fieldSpec) && fieldSpec.__autoPopupForRelationField === true) {
|
|
6831
|
+
return;
|
|
6832
|
+
}
|
|
6833
|
+
if (_.isPlainObject(fieldSpec) && Object.prototype.hasOwnProperty.call(fieldSpec, "titleField")) {
|
|
6834
|
+
return;
|
|
6835
|
+
}
|
|
6836
|
+
const fieldPath = getFieldPathInput(fieldSpec);
|
|
6837
|
+
if (!fieldPath || fieldPath.includes(".")) {
|
|
6838
|
+
return;
|
|
6839
|
+
}
|
|
6840
|
+
const collection = getBlockCollection(block, context);
|
|
6841
|
+
if (!collection || !context.getCollection) {
|
|
6842
|
+
return;
|
|
6843
|
+
}
|
|
6844
|
+
const resolvedField = (0, import_service_helpers.resolveFieldFromCollection)(collection, (0, import_service_helpers.normalizeFieldPath)(fieldPath));
|
|
6845
|
+
if (!resolvedField || !(0, import_service_helpers.isAssociationField)(resolvedField)) {
|
|
6846
|
+
return;
|
|
6847
|
+
}
|
|
6848
|
+
const dataSourceKey = getBlockDataSourceKey(block, context);
|
|
6849
|
+
if (hasUsableDefaultFieldGroupRelationTitleField({
|
|
6850
|
+
fieldGroups: (_a = context.getDefaultFieldGroups) == null ? void 0 : _a.call(context, dataSourceKey, getBlockCollectionName(block, context)),
|
|
6851
|
+
fieldPath,
|
|
6852
|
+
field: resolvedField,
|
|
6853
|
+
dataSourceKey,
|
|
6854
|
+
context
|
|
6855
|
+
})) {
|
|
6856
|
+
return;
|
|
6857
|
+
}
|
|
6858
|
+
const registeredBinding = (0, import_field_binding_registry.resolveRegisteredFieldBinding)({
|
|
6859
|
+
containerUse: IMPLICIT_RELATION_TITLE_FIELD_CONTAINER_USE_BY_BLOCK_TYPE[hostBlockType],
|
|
6860
|
+
field: resolvedField,
|
|
6861
|
+
dataSourceKey,
|
|
6862
|
+
enabledPackages: context.enabledPackages,
|
|
6863
|
+
getCollection: (resolvedDataSourceKey, targetCollectionName) => {
|
|
6864
|
+
var _a2;
|
|
6865
|
+
return (_a2 = context.getCollection) == null ? void 0 : _a2.call(context, resolvedDataSourceKey, targetCollectionName);
|
|
6866
|
+
},
|
|
6867
|
+
useStrictOnly: true
|
|
6868
|
+
});
|
|
6869
|
+
if (registeredBinding == null ? void 0 : registeredBinding.modelClassName) {
|
|
6870
|
+
return;
|
|
6871
|
+
}
|
|
6872
|
+
try {
|
|
6873
|
+
const resolvedTitleField = (0, import_association_title_field.resolveAssociationSafeTitleField)(resolvedField, dataSourceKey, context.getCollection, {
|
|
6874
|
+
action: context.authoringActionName,
|
|
6875
|
+
path: `${path}.titleField`,
|
|
6876
|
+
fieldPath
|
|
6877
|
+
});
|
|
6878
|
+
if (!(resolvedTitleField == null ? void 0 : resolvedTitleField.fieldName)) {
|
|
6879
|
+
pushAuthoringError(errors, {
|
|
6880
|
+
path: `${path}.titleField`,
|
|
6881
|
+
ruleId: "relation-titleField-unavailable",
|
|
6882
|
+
message: `flowSurfaces authoring ${path} relation field '${fieldPath}' requires an explicit readable titleField`,
|
|
6883
|
+
details: {
|
|
6884
|
+
fieldPath,
|
|
6885
|
+
repairHint: `Use object field form such as {"field":"${fieldPath}","titleField":"<readable target field>"}.`
|
|
6886
|
+
}
|
|
6887
|
+
});
|
|
6888
|
+
}
|
|
6889
|
+
} catch (error) {
|
|
6890
|
+
if (!(error instanceof import_errors.FlowSurfaceBadRequestError)) {
|
|
6891
|
+
throw error;
|
|
6892
|
+
}
|
|
6893
|
+
pushAuthoringError(errors, {
|
|
6894
|
+
path: `${path}.titleField`,
|
|
6895
|
+
ruleId: error.options.ruleId || "relation-titleField-unavailable",
|
|
6896
|
+
message: `flowSurfaces authoring ${path} relation field '${fieldPath}' requires an explicit readable titleField`,
|
|
6897
|
+
details: {
|
|
6898
|
+
...error.options.details || {},
|
|
6899
|
+
fieldPath,
|
|
6900
|
+
repairHint: `Use object field form such as {"field":"${fieldPath}","titleField":"<readable target field>"}.`
|
|
6901
|
+
}
|
|
6902
|
+
});
|
|
6903
|
+
}
|
|
6904
|
+
}
|
|
6905
|
+
function hasUsableDefaultFieldGroupRelationTitleField(input) {
|
|
6906
|
+
const titleField = (0, import_defaults.getFlowSurfaceDefaultFieldGroupRelationTitleFieldOverride)(input.fieldGroups, input.fieldPath);
|
|
6907
|
+
if (!titleField || titleField === "id" || !input.context.getCollection) {
|
|
6908
|
+
return false;
|
|
6909
|
+
}
|
|
6910
|
+
const targetCollection = (0, import_service_helpers.resolveFieldTargetCollection)(
|
|
6911
|
+
input.field,
|
|
6912
|
+
input.dataSourceKey,
|
|
6913
|
+
(dataSourceKey, collectionName) => {
|
|
6914
|
+
var _a, _b;
|
|
6915
|
+
return (_b = (_a = input.context).getCollection) == null ? void 0 : _b.call(_a, dataSourceKey, collectionName);
|
|
6916
|
+
}
|
|
6917
|
+
);
|
|
6918
|
+
const targetField = targetCollection ? (0, import_service_helpers.resolveFieldFromCollection)(targetCollection, titleField) : void 0;
|
|
6919
|
+
return !!targetField && !(0, import_service_helpers.isAssociationField)(targetField);
|
|
6920
|
+
}
|
|
6174
6921
|
function getRelationTitleFieldInvalidReason(titleField, targetField) {
|
|
6175
6922
|
if (titleField === "id") {
|
|
6176
6923
|
return "id";
|
|
@@ -6204,18 +6951,18 @@ function getRecordHistoryDeclaredFilterTargetKey(collection) {
|
|
|
6204
6951
|
return String(raw || "").trim();
|
|
6205
6952
|
}
|
|
6206
6953
|
function collectionHasConcreteField(collection, fieldName) {
|
|
6207
|
-
var _a, _b, _c
|
|
6954
|
+
var _a, _b, _c;
|
|
6208
6955
|
const normalized = String(fieldName || "").trim();
|
|
6209
6956
|
if (!normalized) {
|
|
6210
6957
|
return false;
|
|
6211
6958
|
}
|
|
6212
|
-
const modelAttributes = (
|
|
6959
|
+
const modelAttributes = (0, import_service_helpers.getCollectionModelAttributes)(collection);
|
|
6213
6960
|
const primaryKeyAttributes = _.castArray(
|
|
6214
|
-
((
|
|
6961
|
+
((_a = collection == null ? void 0 : collection.model) == null ? void 0 : _a.primaryKeyAttributes) || ((_b = collection == null ? void 0 : collection.model) == null ? void 0 : _b.primaryKeyAttribute) || []
|
|
6215
6962
|
);
|
|
6216
6963
|
const modelAttribute = modelAttributes == null ? void 0 : modelAttributes[normalized];
|
|
6217
6964
|
const isModelPrimaryKey = primaryKeyAttributes.includes(normalized) || !!(modelAttribute == null ? void 0 : modelAttribute.primaryKey);
|
|
6218
|
-
return !!((0, import_service_helpers.resolveFieldFromCollection)(collection, normalized) || ((
|
|
6965
|
+
return !!((0, import_service_helpers.resolveFieldFromCollection)(collection, normalized) || ((_c = collection == null ? void 0 : collection.getField) == null ? void 0 : _c.call(collection, normalized)) || (0, import_service_helpers.getCollectionFields)(collection).some((field) => (0, import_service_helpers.getFieldName)(field) === normalized) || isModelPrimaryKey);
|
|
6219
6966
|
}
|
|
6220
6967
|
function collectDefaultFilterFieldPathError(rawFieldPath, path, block, context, errors) {
|
|
6221
6968
|
const fieldPath = String(rawFieldPath || "").trim();
|