@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
|
@@ -588,12 +588,16 @@ function prepareFlowSurfaceApplyBlueprintDocument(input) {
|
|
|
588
588
|
if (tabs.length > 1 && (page == null ? void 0 : page.enableTabs) === false) {
|
|
589
589
|
(0, import_errors.throwBadRequest)(`flowSurfaces applyBlueprint page.enableTabs cannot be false when tabs.length > 1`);
|
|
590
590
|
}
|
|
591
|
+
const normalizedPage = tabs.length === 1 ? {
|
|
592
|
+
...page || {},
|
|
593
|
+
enableTabs: false
|
|
594
|
+
} : page;
|
|
591
595
|
return {
|
|
592
596
|
version: "1",
|
|
593
597
|
mode,
|
|
594
598
|
...target ? { target } : {},
|
|
595
599
|
...navigation ? { navigation } : {},
|
|
596
|
-
...
|
|
600
|
+
...normalizedPage ? { page: normalizedPage } : {},
|
|
597
601
|
...defaults ? { defaults } : {},
|
|
598
602
|
tabs,
|
|
599
603
|
assets,
|
|
@@ -119,6 +119,10 @@ const FILTER_GROUP_SCHEMA = {
|
|
|
119
119
|
additionalProperties: false,
|
|
120
120
|
"x-flowSurfaceFormat": "filter-group"
|
|
121
121
|
};
|
|
122
|
+
const LINKAGE_RULES_SCHEMA = {
|
|
123
|
+
type: "array",
|
|
124
|
+
"x-flowSurfaceFormat": "linkage-rules"
|
|
125
|
+
};
|
|
122
126
|
const DEFAULT_DIRECT_EVENTS = ["beforeRender"];
|
|
123
127
|
const ACTION_DIRECT_EVENTS = ["click", "beforeRender"];
|
|
124
128
|
const ACTION_OBJECT_EVENTS = ["click"];
|
|
@@ -207,7 +211,7 @@ const ACTION_BUTTON_SETTINGS_GROUP = {
|
|
|
207
211
|
"general.type": STRING_SCHEMA,
|
|
208
212
|
"general.danger": BOOLEAN_SCHEMA,
|
|
209
213
|
"general.color": STRING_SCHEMA,
|
|
210
|
-
"linkageRules.value":
|
|
214
|
+
"linkageRules.value": LINKAGE_RULES_SCHEMA
|
|
211
215
|
}
|
|
212
216
|
};
|
|
213
217
|
const TRIGGER_WORKFLOWS_SETTINGS_GROUP = {
|
|
@@ -302,7 +306,7 @@ const EVENT_SETTINGS_GROUP = {
|
|
|
302
306
|
allowedPaths: ["linkageRules.value"],
|
|
303
307
|
eventBindingSteps: ["linkageRules"],
|
|
304
308
|
pathSchemas: {
|
|
305
|
-
"linkageRules.value":
|
|
309
|
+
"linkageRules.value": LINKAGE_RULES_SCHEMA
|
|
306
310
|
}
|
|
307
311
|
};
|
|
308
312
|
const CREATE_FORM_SETTINGS_EVENT_ONLY_GROUP = {
|
|
@@ -323,7 +327,7 @@ const DETAILS_SETTINGS_GROUP = {
|
|
|
323
327
|
...FORM_LAYOUT_PATH_SCHEMAS,
|
|
324
328
|
"dataScope.filter": FILTER_GROUP_SCHEMA,
|
|
325
329
|
"defaultSorting.sort": ARRAY_SCHEMA,
|
|
326
|
-
"linkageRules.value":
|
|
330
|
+
"linkageRules.value": LINKAGE_RULES_SCHEMA
|
|
327
331
|
}
|
|
328
332
|
};
|
|
329
333
|
const FILTER_FORM_BLOCK_SETTINGS_GROUP = {
|
|
@@ -350,7 +354,7 @@ const BLOCK_CARD_SETTINGS_GROUP = {
|
|
|
350
354
|
"titleDescription.description": STRING_SCHEMA,
|
|
351
355
|
"blockHeight.heightMode": BLOCK_HEIGHT_MODE_SCHEMA,
|
|
352
356
|
"blockHeight.height": NUMBER_SCHEMA,
|
|
353
|
-
"linkageRules.value":
|
|
357
|
+
"linkageRules.value": LINKAGE_RULES_SCHEMA
|
|
354
358
|
}
|
|
355
359
|
};
|
|
356
360
|
const CALENDAR_SETTINGS_GROUP = {
|
|
@@ -2191,7 +2195,7 @@ CALENDAR_READONLY_ACTION_CONTRACT.domains.stepParams = groupedDomain({
|
|
|
2191
2195
|
mergeStrategy: "deep",
|
|
2192
2196
|
eventBindingSteps: ["linkageRules"],
|
|
2193
2197
|
pathSchemas: {
|
|
2194
|
-
"linkageRules.value":
|
|
2198
|
+
"linkageRules.value": LINKAGE_RULES_SCHEMA
|
|
2195
2199
|
}
|
|
2196
2200
|
}
|
|
2197
2201
|
});
|
|
@@ -64,7 +64,91 @@ __export(chart_config_exports, {
|
|
|
64
64
|
module.exports = __toCommonJS(chart_config_exports);
|
|
65
65
|
var import_lodash = __toESM(require("lodash"));
|
|
66
66
|
var import_errors = require("./errors");
|
|
67
|
+
var import_filter_group = require("./filter-group");
|
|
67
68
|
const CHART_REPAIR_HINT = "This is a chart payload shape problem. Repair the current chart query/visual mappings and keep the chart block type. Do not change this block type to table, jsBlock, actionPanel, gridCard, or another block type. KPI / summary numbers should use jsBlock; charts are for trends, distributions, rankings, and visual analysis.";
|
|
69
|
+
const CHART_FORBIDDEN_FALLBACKS = [
|
|
70
|
+
"table",
|
|
71
|
+
"list",
|
|
72
|
+
"jsBlock",
|
|
73
|
+
"actionPanel",
|
|
74
|
+
"gridCard",
|
|
75
|
+
"markdown",
|
|
76
|
+
"drop chart",
|
|
77
|
+
"defer chart"
|
|
78
|
+
];
|
|
79
|
+
const CHART_REPAIR_STEPS = [
|
|
80
|
+
"Keep the block type as chart.",
|
|
81
|
+
"Repair the chart query and visual mappings on the current chart payload.",
|
|
82
|
+
"Retry the chart payload instead of replacing the chart with another block type, omitting it, or deferring it."
|
|
83
|
+
];
|
|
84
|
+
const CHART_EXPECTED_SHAPE = {
|
|
85
|
+
settings: {
|
|
86
|
+
query: {
|
|
87
|
+
mode: "builder",
|
|
88
|
+
resource: {
|
|
89
|
+
dataSourceKey: "main",
|
|
90
|
+
collectionName: "employees"
|
|
91
|
+
},
|
|
92
|
+
measures: [
|
|
93
|
+
{
|
|
94
|
+
field: "id",
|
|
95
|
+
aggregation: "count",
|
|
96
|
+
alias: "employeeCount"
|
|
97
|
+
}
|
|
98
|
+
]
|
|
99
|
+
},
|
|
100
|
+
visual: {
|
|
101
|
+
mode: "basic",
|
|
102
|
+
type: "bar",
|
|
103
|
+
mappings: {
|
|
104
|
+
x: "status",
|
|
105
|
+
y: "employeeCount"
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
function withChartRepairDetails(details = {}) {
|
|
111
|
+
return {
|
|
112
|
+
...details,
|
|
113
|
+
requiredBlockType: "chart",
|
|
114
|
+
fixStrategy: "repair_same_block_type",
|
|
115
|
+
repairHint: CHART_REPAIR_HINT,
|
|
116
|
+
repairSteps: CHART_REPAIR_STEPS,
|
|
117
|
+
expectedShape: CHART_EXPECTED_SHAPE,
|
|
118
|
+
repairExample: {
|
|
119
|
+
settings: {
|
|
120
|
+
query: {
|
|
121
|
+
mode: "builder",
|
|
122
|
+
resource: {
|
|
123
|
+
dataSourceKey: "main",
|
|
124
|
+
collectionName: "<collectionName>"
|
|
125
|
+
},
|
|
126
|
+
measures: [
|
|
127
|
+
{
|
|
128
|
+
field: "id",
|
|
129
|
+
aggregation: "count",
|
|
130
|
+
alias: "recordCount"
|
|
131
|
+
}
|
|
132
|
+
],
|
|
133
|
+
dimensions: [
|
|
134
|
+
{
|
|
135
|
+
field: "<dimensionField>"
|
|
136
|
+
}
|
|
137
|
+
]
|
|
138
|
+
},
|
|
139
|
+
visual: {
|
|
140
|
+
mode: "basic",
|
|
141
|
+
type: "bar",
|
|
142
|
+
mappings: {
|
|
143
|
+
x: "<dimensionField>",
|
|
144
|
+
y: "recordCount"
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
forbiddenFallbacks: CHART_FORBIDDEN_FALLBACKS
|
|
150
|
+
};
|
|
151
|
+
}
|
|
68
152
|
function withChartRepairMessage(message) {
|
|
69
153
|
return `${message}. ${CHART_REPAIR_HINT}`;
|
|
70
154
|
}
|
|
@@ -86,10 +170,6 @@ const CHART_SORT_DIRECTIONS = ["asc", "desc"];
|
|
|
86
170
|
const CHART_SORT_NULLS = ["default", "first", "last"];
|
|
87
171
|
const CHART_LABEL_TYPES = ["value", "percent"];
|
|
88
172
|
const CHART_FUNNEL_SORTS = ["descending", "ascending"];
|
|
89
|
-
const EMPTY_FILTER_GROUP = {
|
|
90
|
-
logic: "$and",
|
|
91
|
-
items: []
|
|
92
|
-
};
|
|
93
173
|
const CHART_SAFE_DEFAULT_HINTS = [
|
|
94
174
|
{
|
|
95
175
|
key: "builder_basic_minimal",
|
|
@@ -375,6 +455,17 @@ function normalizeFieldPathValue(input, label, options = {}) {
|
|
|
375
455
|
}
|
|
376
456
|
throw new import_errors.FlowSurfaceBadRequestError(`${label} must be a string or string[]`);
|
|
377
457
|
}
|
|
458
|
+
function normalizeChartQueryFieldPathValue(input, label, options = {}) {
|
|
459
|
+
const normalized = normalizeFieldPathValue(input, label, options);
|
|
460
|
+
if (typeof normalized !== "string" || !normalized.includes(".")) {
|
|
461
|
+
return normalized;
|
|
462
|
+
}
|
|
463
|
+
const segments = normalized.split(".").map((segment) => segment.trim());
|
|
464
|
+
if (segments.some((segment) => !segment)) {
|
|
465
|
+
throw new import_errors.FlowSurfaceBadRequestError(`${label} cannot contain empty path segments`);
|
|
466
|
+
}
|
|
467
|
+
return segments;
|
|
468
|
+
}
|
|
378
469
|
function aliasOfFieldValue(input) {
|
|
379
470
|
if (Array.isArray(input)) {
|
|
380
471
|
return input.filter(Boolean).map((item) => String(item)).join(".");
|
|
@@ -406,7 +497,7 @@ function fromPersistedOrder(input) {
|
|
|
406
497
|
return CHART_SORT_DIRECTION_SET.has(normalized) ? normalized : void 0;
|
|
407
498
|
}
|
|
408
499
|
function createEmptyFilterGroup() {
|
|
409
|
-
return import_lodash.default.cloneDeep(
|
|
500
|
+
return import_lodash.default.cloneDeep(import_filter_group.FLOW_SURFACE_EMPTY_FILTER_GROUP);
|
|
410
501
|
}
|
|
411
502
|
function assertAllowedKeys(input, allowed, label) {
|
|
412
503
|
const unknownKeys = Object.keys(input).filter((key) => !allowed.has(key));
|
|
@@ -482,25 +573,29 @@ function normalizeMergedChartResource(query, options = {}) {
|
|
|
482
573
|
function normalizeChartMeasure(input, index) {
|
|
483
574
|
const label = `chart query.measures[${index}]`;
|
|
484
575
|
const normalized = ensurePlainObject(input, label);
|
|
576
|
+
const field = normalizeChartQueryFieldPathValue(normalized.field, `${label}.field`, { required: true });
|
|
577
|
+
const alias = normalizeOptionalTrimmedString(normalized.alias, `${label}.alias`);
|
|
485
578
|
const aggregation = normalizeOptionalEnumValue(
|
|
486
579
|
normalized.aggregation,
|
|
487
580
|
CHART_QUERY_AGGREGATION_SET,
|
|
488
581
|
`${label}.aggregation`
|
|
489
582
|
);
|
|
490
583
|
return buildDefinedObject({
|
|
491
|
-
field
|
|
584
|
+
field,
|
|
492
585
|
aggregation,
|
|
493
|
-
alias:
|
|
586
|
+
alias: alias || (Array.isArray(field) && field.length > 1 ? aliasOfFieldValue(field) : void 0),
|
|
494
587
|
distinct: normalizeOptionalBoolean(normalized.distinct, `${label}.distinct`)
|
|
495
588
|
});
|
|
496
589
|
}
|
|
497
590
|
function normalizeChartDimension(input, index) {
|
|
498
591
|
const label = `chart query.dimensions[${index}]`;
|
|
499
592
|
const normalized = ensurePlainObject(input, label);
|
|
593
|
+
const field = normalizeChartQueryFieldPathValue(normalized.field, `${label}.field`, { required: true });
|
|
594
|
+
const alias = normalizeOptionalTrimmedString(normalized.alias, `${label}.alias`);
|
|
500
595
|
return buildDefinedObject({
|
|
501
|
-
field
|
|
596
|
+
field,
|
|
502
597
|
format: normalizeOptionalTrimmedString(normalized.format, `${label}.format`),
|
|
503
|
-
alias:
|
|
598
|
+
alias: alias || (Array.isArray(field) && field.length > 1 ? aliasOfFieldValue(field) : void 0)
|
|
504
599
|
});
|
|
505
600
|
}
|
|
506
601
|
function normalizeBuilderCountMeasureFieldForRuntime(measure, dimensions) {
|
|
@@ -511,6 +606,12 @@ function normalizeBuilderCountMeasureFieldForRuntime(measure, dimensions) {
|
|
|
511
606
|
if (!fallbackDimension) {
|
|
512
607
|
return measure;
|
|
513
608
|
}
|
|
609
|
+
if (Array.isArray(fallbackDimension.field) && fallbackDimension.field.length > 1) {
|
|
610
|
+
return measure;
|
|
611
|
+
}
|
|
612
|
+
if (typeof fallbackDimension.field === "string" && fallbackDimension.field.includes(".")) {
|
|
613
|
+
return measure;
|
|
614
|
+
}
|
|
514
615
|
return {
|
|
515
616
|
...measure,
|
|
516
617
|
field: import_lodash.default.cloneDeep(fallbackDimension.field)
|
|
@@ -525,18 +626,113 @@ function normalizeChartSortingItem(input, index) {
|
|
|
525
626
|
`${label}.${hasOwn(normalized, "direction") ? "direction" : "order"}`
|
|
526
627
|
);
|
|
527
628
|
return buildDefinedObject({
|
|
528
|
-
field:
|
|
629
|
+
field: normalizeChartQueryFieldPathValue(normalized.field, `${label}.field`, { required: true }),
|
|
529
630
|
order: toPersistedOrder(direction),
|
|
530
631
|
nulls: normalizeOptionalEnumValue(normalized.nulls, CHART_SORT_NULLS_SET, `${label}.nulls`)
|
|
531
632
|
});
|
|
532
633
|
}
|
|
634
|
+
function isFilterGroupLike(input) {
|
|
635
|
+
return import_lodash.default.isPlainObject(input) && isBackendQueryLogicKey(input.logic) && Array.isArray(input.items);
|
|
636
|
+
}
|
|
637
|
+
function assertFilterGroupKeys(input, label) {
|
|
638
|
+
if (!isFilterGroupLike(input)) {
|
|
639
|
+
return;
|
|
640
|
+
}
|
|
641
|
+
const unsupportedKeys = Object.keys(input).filter((key) => key !== "logic" && key !== "items");
|
|
642
|
+
if (unsupportedKeys.length) {
|
|
643
|
+
throw new import_errors.FlowSurfaceBadRequestError(`${label} does not support: ${unsupportedKeys.join(", ")}`);
|
|
644
|
+
}
|
|
645
|
+
if (Array.isArray(input.items)) {
|
|
646
|
+
input.items.forEach((item, index) => {
|
|
647
|
+
assertFilterGroupKeys(item, `${label}.items[${index}]`);
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
function isBackendQueryLogicKey(key) {
|
|
652
|
+
return key === "$and" || key === "$or";
|
|
653
|
+
}
|
|
654
|
+
function getBackendQueryLogicKey(input, label) {
|
|
655
|
+
const keys = Object.keys(input);
|
|
656
|
+
const logicKeys = keys.filter(isBackendQueryLogicKey);
|
|
657
|
+
if (!logicKeys.length) {
|
|
658
|
+
return void 0;
|
|
659
|
+
}
|
|
660
|
+
if (logicKeys.length > 1 || keys.length > 1) {
|
|
661
|
+
throw new import_errors.FlowSurfaceBadRequestError(
|
|
662
|
+
`${label}: cannot convert backend query filter with mixed logical and field conditions`
|
|
663
|
+
);
|
|
664
|
+
}
|
|
665
|
+
return logicKeys[0];
|
|
666
|
+
}
|
|
667
|
+
function convertBackendFieldConditionToFilterItems(field, condition, label) {
|
|
668
|
+
if (!field.trim() || field.startsWith("$")) {
|
|
669
|
+
throw new import_errors.FlowSurfaceBadRequestError(`${label}: cannot convert backend query filter field "${field}"`);
|
|
670
|
+
}
|
|
671
|
+
if (!import_lodash.default.isPlainObject(condition)) {
|
|
672
|
+
throw new import_errors.FlowSurfaceBadRequestError(`${label}.${field}: backend query filter condition must be an object`);
|
|
673
|
+
}
|
|
674
|
+
const operators = Object.keys(condition);
|
|
675
|
+
if (!operators.length) {
|
|
676
|
+
throw new import_errors.FlowSurfaceBadRequestError(`${label}.${field}: backend query filter condition cannot be empty`);
|
|
677
|
+
}
|
|
678
|
+
return operators.map((operator) => {
|
|
679
|
+
if (!operator.startsWith("$")) {
|
|
680
|
+
(0, import_filter_group.assertFlowSurfaceFilterOperator)(operator, `${label}.${field}.${operator}`);
|
|
681
|
+
}
|
|
682
|
+
if (!operator.startsWith("$") || isBackendQueryLogicKey(operator)) {
|
|
683
|
+
throw new import_errors.FlowSurfaceBadRequestError(
|
|
684
|
+
`${label}.${field}: cannot convert backend query filter operator "${operator}"`
|
|
685
|
+
);
|
|
686
|
+
}
|
|
687
|
+
return {
|
|
688
|
+
path: field,
|
|
689
|
+
operator,
|
|
690
|
+
value: import_lodash.default.cloneDeep(condition[operator])
|
|
691
|
+
};
|
|
692
|
+
});
|
|
693
|
+
}
|
|
694
|
+
function convertBackendQueryFilterToFilterGroup(input, label) {
|
|
695
|
+
const logicKey = getBackendQueryLogicKey(input, label);
|
|
696
|
+
if (logicKey) {
|
|
697
|
+
const operands = input[logicKey];
|
|
698
|
+
if (!Array.isArray(operands)) {
|
|
699
|
+
throw new import_errors.FlowSurfaceBadRequestError(`${label}.${logicKey}: backend query filter operands must be an array`);
|
|
700
|
+
}
|
|
701
|
+
return {
|
|
702
|
+
logic: logicKey,
|
|
703
|
+
items: operands.map(
|
|
704
|
+
(operand, index) => convertBackendQueryOperandToFilterItem(operand, `${label}.${logicKey}[${index}]`)
|
|
705
|
+
)
|
|
706
|
+
};
|
|
707
|
+
}
|
|
708
|
+
return {
|
|
709
|
+
logic: "$and",
|
|
710
|
+
items: Object.entries(input).flatMap(
|
|
711
|
+
([field, condition]) => convertBackendFieldConditionToFilterItems(field, condition, label)
|
|
712
|
+
)
|
|
713
|
+
};
|
|
714
|
+
}
|
|
715
|
+
function convertBackendQueryOperandToFilterItem(input, label) {
|
|
716
|
+
if (isFilterGroupLike(input)) {
|
|
717
|
+
throw new import_errors.FlowSurfaceBadRequestError(`${label}: cannot mix filter groups with backend query filters`);
|
|
718
|
+
}
|
|
719
|
+
const group = convertBackendQueryFilterToFilterGroup(ensurePlainObject(input, label), label);
|
|
720
|
+
if (group.logic === "$and" && group.items.length === 1) {
|
|
721
|
+
return group.items[0];
|
|
722
|
+
}
|
|
723
|
+
return group;
|
|
724
|
+
}
|
|
533
725
|
function normalizeFilterGroupValue(input, label) {
|
|
534
726
|
if (import_lodash.default.isUndefined(input) || import_lodash.default.isNull(input)) {
|
|
535
727
|
return void 0;
|
|
536
728
|
}
|
|
537
729
|
const normalized = ensurePlainObject(input, label);
|
|
538
|
-
|
|
539
|
-
|
|
730
|
+
assertFilterGroupKeys(normalized, label);
|
|
731
|
+
const filterGroup = !Object.keys(normalized).length || isFilterGroupLike(normalized) ? (0, import_filter_group.normalizeFlowSurfaceFilterGroupValue)(normalized, label, { strictDateValues: true }) : (0, import_filter_group.normalizeFlowSurfaceFilterGroupValue)(convertBackendQueryFilterToFilterGroup(normalized, label), label, {
|
|
732
|
+
strictDateValues: true
|
|
733
|
+
});
|
|
734
|
+
validateFilterGroupPaths(filterGroup, label);
|
|
735
|
+
return filterGroup;
|
|
540
736
|
}
|
|
541
737
|
function validateFilterGroupPaths(input, label) {
|
|
542
738
|
const items = Array.isArray(input == null ? void 0 : input.items) ? input.items : [];
|
|
@@ -568,6 +764,7 @@ function inferQueryMode(query) {
|
|
|
568
764
|
}
|
|
569
765
|
function validateLooseChartQuery(query) {
|
|
570
766
|
inferQueryMode(query);
|
|
767
|
+
validateChartQueryFilterOperators(query);
|
|
571
768
|
if (!hasOwn(query, "resource") || !hasOwn(query, "collectionPath")) {
|
|
572
769
|
return;
|
|
573
770
|
}
|
|
@@ -582,6 +779,11 @@ function validateLooseChartQuery(query) {
|
|
|
582
779
|
);
|
|
583
780
|
}
|
|
584
781
|
}
|
|
782
|
+
function validateChartQueryFilterOperators(query) {
|
|
783
|
+
if (hasOwn(query, "filter")) {
|
|
784
|
+
normalizeFilterGroupValue(query.filter, "chart query.filter");
|
|
785
|
+
}
|
|
786
|
+
}
|
|
585
787
|
function canStrictNormalizeChartQuery(query) {
|
|
586
788
|
validateLooseChartQuery(query);
|
|
587
789
|
const mode = inferQueryMode(query);
|
|
@@ -605,7 +807,10 @@ function mergeChartQuerySection(current, patch) {
|
|
|
605
807
|
const nextMode = inferQueryMode(normalizedPatch);
|
|
606
808
|
const modeChanged = currentMode && currentMode !== nextMode;
|
|
607
809
|
const base = modeChanged ? {} : current || {};
|
|
608
|
-
const merged = mergeReplaceArrays(base, normalizedPatch);
|
|
810
|
+
const merged = mergeReplaceArrays(base, import_lodash.default.omit(normalizedPatch, ["filter"]));
|
|
811
|
+
if (hasOwn(normalizedPatch, "filter")) {
|
|
812
|
+
merged.filter = import_lodash.default.cloneDeep(normalizedPatch.filter);
|
|
813
|
+
}
|
|
609
814
|
if (nextMode !== "builder") {
|
|
610
815
|
return merged;
|
|
611
816
|
}
|
|
@@ -1092,10 +1297,9 @@ function assertBasicVisualMappingsAgainstBuilderQuery(builderVisual, query) {
|
|
|
1092
1297
|
),
|
|
1093
1298
|
void 0,
|
|
1094
1299
|
{
|
|
1095
|
-
details: {
|
|
1096
|
-
repairHint: CHART_REPAIR_HINT,
|
|
1300
|
+
details: withChartRepairDetails({
|
|
1097
1301
|
allowedOutputs: Array.from(allowedOutputs)
|
|
1098
|
-
}
|
|
1302
|
+
})
|
|
1099
1303
|
}
|
|
1100
1304
|
);
|
|
1101
1305
|
}
|
|
@@ -165,7 +165,7 @@ class FlowSurfaceContractGuard {
|
|
|
165
165
|
if (typeof on === "string" && !allowedDirectEvents.has(eventName)) {
|
|
166
166
|
(0, import_errors.throwBadRequest)(`flowSurfaces flow '${key}' event '${eventName}' is not allowed on '${node == null ? void 0 : node.use}'`);
|
|
167
167
|
}
|
|
168
|
-
if (typeof on !== "string" && !allowedObjectEvents.has(eventName)) {
|
|
168
|
+
if (typeof on !== "string" && !allowedObjectEvents.has(eventName) && !allowedDirectEvents.has(eventName)) {
|
|
169
169
|
(0, import_errors.throwBadRequest)(`flowSurfaces flow '${key}' event '${eventName}' is not allowed on '${node == null ? void 0 : node.use}'`);
|
|
170
170
|
}
|
|
171
171
|
const phase = onObj == null ? void 0 : onObj.phase;
|
|
@@ -349,33 +349,67 @@ function collectSchemaValueErrors(value, schema, path) {
|
|
|
349
349
|
function normalizeDomainValue(value, contract, context) {
|
|
350
350
|
const normalized = import_lodash.default.cloneDeep(value);
|
|
351
351
|
Object.entries(contract.pathSchemas || {}).forEach(([path, schema]) => {
|
|
352
|
-
if (!import_lodash.default.has(normalized, path)
|
|
352
|
+
if (!import_lodash.default.has(normalized, path)) {
|
|
353
353
|
return;
|
|
354
354
|
}
|
|
355
|
-
|
|
355
|
+
if (isFilterGroupSchema(schema)) {
|
|
356
|
+
import_lodash.default.set(normalized, path, normalizeFilterGroupValue(import_lodash.default.get(normalized, path), context, path));
|
|
357
|
+
} else if (isLinkageRulesSchema(schema)) {
|
|
358
|
+
import_lodash.default.set(normalized, path, normalizeLinkageRulesValue(import_lodash.default.get(normalized, path), context, path));
|
|
359
|
+
}
|
|
356
360
|
});
|
|
357
361
|
return normalized;
|
|
358
362
|
}
|
|
359
363
|
function normalizeGroupValue(value, groupContract, context) {
|
|
360
364
|
const normalized = import_lodash.default.cloneDeep(value);
|
|
361
365
|
Object.entries(groupContract.pathSchemas || {}).forEach(([path, schema]) => {
|
|
362
|
-
if (!import_lodash.default.has(normalized, path)
|
|
366
|
+
if (!import_lodash.default.has(normalized, path)) {
|
|
363
367
|
return;
|
|
364
368
|
}
|
|
365
|
-
|
|
369
|
+
if (isFilterGroupSchema(schema)) {
|
|
370
|
+
import_lodash.default.set(normalized, path, normalizeFilterGroupValue(import_lodash.default.get(normalized, path), context, path));
|
|
371
|
+
} else if (isLinkageRulesSchema(schema)) {
|
|
372
|
+
import_lodash.default.set(normalized, path, normalizeLinkageRulesValue(import_lodash.default.get(normalized, path), context, path));
|
|
373
|
+
}
|
|
366
374
|
});
|
|
367
375
|
return normalized;
|
|
368
376
|
}
|
|
369
377
|
function isFilterGroupSchema(schema) {
|
|
370
378
|
return (schema == null ? void 0 : schema["x-flowSurfaceFormat"]) === "filter-group";
|
|
371
379
|
}
|
|
380
|
+
function isLinkageRulesSchema(schema) {
|
|
381
|
+
return (schema == null ? void 0 : schema["x-flowSurfaceFormat"]) === "linkage-rules";
|
|
382
|
+
}
|
|
372
383
|
function normalizeFilterGroupValue(value, context, path) {
|
|
373
384
|
const domainPath = context.groupKey ? `${context.domain}.${context.groupKey}.${path}` : `${context.domain}.${path}`;
|
|
374
385
|
return (0, import_filter_group.normalizeFlowSurfaceFilterGroupValue)(
|
|
375
386
|
value,
|
|
376
|
-
`flowSurfaces updateSettings domain '${domainPath}' on '${context.use}' expects FilterGroup like ${import_filter_group.FLOW_SURFACE_FILTER_GROUP_EXAMPLE}
|
|
387
|
+
`flowSurfaces updateSettings domain '${domainPath}' on '${context.use}' expects FilterGroup like ${import_filter_group.FLOW_SURFACE_FILTER_GROUP_EXAMPLE}`,
|
|
388
|
+
{ strictDateValues: true }
|
|
377
389
|
);
|
|
378
390
|
}
|
|
391
|
+
function normalizeLinkageRulesValue(value, context, path) {
|
|
392
|
+
if (!Array.isArray(value)) {
|
|
393
|
+
return value;
|
|
394
|
+
}
|
|
395
|
+
return value.map((rule, index) => {
|
|
396
|
+
if (!import_lodash.default.isPlainObject(rule) || !import_lodash.default.has(rule, "condition")) {
|
|
397
|
+
return rule;
|
|
398
|
+
}
|
|
399
|
+
const normalizedRule = import_lodash.default.cloneDeep(rule);
|
|
400
|
+
const domainPath = context.groupKey ? `${context.domain}.${context.groupKey}.${path}[${index}].condition` : `${context.domain}.${path}[${index}].condition`;
|
|
401
|
+
import_lodash.default.set(
|
|
402
|
+
normalizedRule,
|
|
403
|
+
"condition",
|
|
404
|
+
(0, import_filter_group.normalizeFlowSurfaceCompatibleFilterGroupValue)(
|
|
405
|
+
import_lodash.default.get(normalizedRule, "condition"),
|
|
406
|
+
`flowSurfaces updateSettings domain '${domainPath}' on '${context.use}' expects FilterGroup or backend query filter like ${import_filter_group.FLOW_SURFACE_FILTER_GROUP_EXAMPLE}`,
|
|
407
|
+
{ strictDateValues: true }
|
|
408
|
+
)
|
|
409
|
+
);
|
|
410
|
+
return normalizedRule;
|
|
411
|
+
});
|
|
412
|
+
}
|
|
379
413
|
function isContractDefinedFlowGroup(groupContract) {
|
|
380
414
|
if (!groupContract) {
|
|
381
415
|
return false;
|
|
@@ -104,6 +104,8 @@ const FLOW_SURFACE_DEFAULT_BLOCK_ACTIONS = {
|
|
|
104
104
|
],
|
|
105
105
|
calendar: [
|
|
106
106
|
{ type: "filter", scope: "actions" },
|
|
107
|
+
{ type: "turnPages", scope: "actions" },
|
|
108
|
+
{ type: "selectView", scope: "actions" },
|
|
107
109
|
{ type: "refresh", scope: "actions" },
|
|
108
110
|
{
|
|
109
111
|
type: "addNew",
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
export type FlowSurfaceErrorType = 'bad_request' | 'forbidden' | 'conflict' | 'internal_error';
|
|
10
10
|
export interface FlowSurfaceErrorItem {
|
|
11
|
+
index?: number;
|
|
11
12
|
message: string;
|
|
12
13
|
type: FlowSurfaceErrorType;
|
|
13
14
|
code: string;
|
|
@@ -48,6 +49,20 @@ export declare class FlowSurfaceAggregateError extends FlowSurfaceError {
|
|
|
48
49
|
readonly errors: FlowSurfaceErrorItem[];
|
|
49
50
|
constructor(errors: FlowSurfaceErrorItemInput[], message?: string);
|
|
50
51
|
toResponseBody(): {
|
|
52
|
+
message: string;
|
|
53
|
+
errorCount: number;
|
|
54
|
+
details: {
|
|
55
|
+
requiredBlockPolicy?: {
|
|
56
|
+
requiredBlockTypes: string[];
|
|
57
|
+
fixStrategy: string;
|
|
58
|
+
doNotReplaceOrDrop: boolean;
|
|
59
|
+
};
|
|
60
|
+
errorCount: number;
|
|
61
|
+
mustFixAllErrorsBeforeRetry: boolean;
|
|
62
|
+
retryPolicy: string;
|
|
63
|
+
sameWriteRetryRequired: boolean;
|
|
64
|
+
agentInstruction: string;
|
|
65
|
+
};
|
|
51
66
|
errors: FlowSurfaceErrorItem[];
|
|
52
67
|
};
|
|
53
68
|
}
|
|
@@ -88,14 +88,27 @@ class FlowSurfaceInternalError extends FlowSurfaceError {
|
|
|
88
88
|
}
|
|
89
89
|
class FlowSurfaceAggregateError extends FlowSurfaceError {
|
|
90
90
|
errors;
|
|
91
|
-
constructor(errors, message
|
|
92
|
-
const normalizedErrors = errors.map(
|
|
93
|
-
|
|
91
|
+
constructor(errors, message) {
|
|
92
|
+
const normalizedErrors = errors.map(
|
|
93
|
+
(error, index) => normalizeFlowSurfaceErrorItemInput({
|
|
94
|
+
...error,
|
|
95
|
+
index: index + 1
|
|
96
|
+
})
|
|
97
|
+
);
|
|
98
|
+
super(
|
|
99
|
+
message || buildAggregateBadRequestMessage(normalizedErrors.length),
|
|
100
|
+
400,
|
|
101
|
+
"bad_request",
|
|
102
|
+
"FLOW_SURFACE_AUTHORING_VALIDATION_FAILED"
|
|
103
|
+
);
|
|
94
104
|
this.name = "FlowSurfaceAggregateError";
|
|
95
105
|
this.errors = normalizedErrors;
|
|
96
106
|
}
|
|
97
107
|
toResponseBody() {
|
|
98
108
|
return {
|
|
109
|
+
message: this.message,
|
|
110
|
+
errorCount: this.errors.length,
|
|
111
|
+
details: buildAggregateBadRequestDetails(this.errors),
|
|
99
112
|
errors: this.errors
|
|
100
113
|
};
|
|
101
114
|
}
|
|
@@ -162,6 +175,9 @@ function buildDefinedErrorItem(input) {
|
|
|
162
175
|
code: input.code,
|
|
163
176
|
status: input.status
|
|
164
177
|
};
|
|
178
|
+
if (typeof input.index !== "undefined") {
|
|
179
|
+
output.index = input.index;
|
|
180
|
+
}
|
|
165
181
|
if (typeof input.path !== "undefined") {
|
|
166
182
|
output.path = input.path;
|
|
167
183
|
}
|
|
@@ -176,6 +192,7 @@ function buildDefinedErrorItem(input) {
|
|
|
176
192
|
function normalizeFlowSurfaceErrorItemInput(input) {
|
|
177
193
|
return buildDefinedErrorItem({
|
|
178
194
|
message: input.message,
|
|
195
|
+
index: input.index,
|
|
179
196
|
type: input.type || "bad_request",
|
|
180
197
|
code: input.code || "FLOW_SURFACE_AUTHORING_VALIDATION_ERROR",
|
|
181
198
|
status: input.status || 400,
|
|
@@ -184,6 +201,35 @@ function normalizeFlowSurfaceErrorItemInput(input) {
|
|
|
184
201
|
details: input.details
|
|
185
202
|
});
|
|
186
203
|
}
|
|
204
|
+
function buildAggregateBadRequestMessage(errorCount) {
|
|
205
|
+
return `flowSurfaces authoring validation failed with ${errorCount} error(s); fix all errors before retrying the same write`;
|
|
206
|
+
}
|
|
207
|
+
function buildAggregateBadRequestDetails(errors) {
|
|
208
|
+
const requiredBlockTypes = Array.from(
|
|
209
|
+
new Set(
|
|
210
|
+
errors.map((error) => {
|
|
211
|
+
var _a;
|
|
212
|
+
return (_a = error.details) == null ? void 0 : _a.requiredBlockType;
|
|
213
|
+
}).filter(
|
|
214
|
+
(requiredBlockType) => typeof requiredBlockType === "string" && !!requiredBlockType
|
|
215
|
+
)
|
|
216
|
+
)
|
|
217
|
+
);
|
|
218
|
+
return {
|
|
219
|
+
errorCount: errors.length,
|
|
220
|
+
mustFixAllErrorsBeforeRetry: true,
|
|
221
|
+
retryPolicy: "fix_all_errors_before_retry_same_write",
|
|
222
|
+
sameWriteRetryRequired: true,
|
|
223
|
+
agentInstruction: "Read the complete errors[] array. Fix every listed error in one payload revision before retrying the same write. Do not fix only the first error and immediately retry. Do not drop, defer, or replace required chart, jsBlock, or JS/RunJS work to bypass validation.",
|
|
224
|
+
...requiredBlockTypes.length ? {
|
|
225
|
+
requiredBlockPolicy: {
|
|
226
|
+
requiredBlockTypes,
|
|
227
|
+
fixStrategy: "repair_same_block_type",
|
|
228
|
+
doNotReplaceOrDrop: true
|
|
229
|
+
}
|
|
230
|
+
} : {}
|
|
231
|
+
};
|
|
232
|
+
}
|
|
187
233
|
// Annotate the CommonJS export names for ESM import in node:
|
|
188
234
|
0 && (module.exports = {
|
|
189
235
|
FlowSurfaceAggregateError,
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
export type FlowSurfaceEventFlowRecord = Record<string, unknown>;
|
|
10
|
+
export type FlowSurfaceEventFlowRegistry = Record<string, FlowSurfaceEventFlowRecord>;
|
|
11
|
+
export declare function buildFlowSurfaceEmptyEventCondition(): {
|
|
12
|
+
logic: string;
|
|
13
|
+
items: any[];
|
|
14
|
+
};
|
|
15
|
+
export declare function normalizeFlowSurfaceEventFlowOn(on: unknown): unknown;
|
|
16
|
+
export declare function normalizeFlowSurfaceEventFlow(actionName: string, key: string, flowInput: unknown): FlowSurfaceEventFlowRecord;
|
|
17
|
+
export declare function normalizeFlowSurfaceEventFlowRegistry(actionName: string, flowRegistry: Record<string, unknown>): FlowSurfaceEventFlowRegistry;
|
|
18
|
+
export declare function normalizeFlowSurfaceEventFlowRegistry<T>(actionName: string, flowRegistry: T): T;
|
|
19
|
+
export declare function isFlowSurfaceBeforeAllEventFlow(flow: unknown): boolean;
|