@nocobase/plugin-flow-engine 2.1.0-alpha.40 → 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 +28 -14
- package/dist/server/flow-surfaces/apply/matching.js +2 -0
- package/dist/server/flow-surfaces/authoring-validation.d.ts +1 -0
- package/dist/server/flow-surfaces/authoring-validation.js +1453 -151
- package/dist/server/flow-surfaces/blueprint/compile-blocks.js +21 -3
- package/dist/server/flow-surfaces/blueprint/compile-plan.js +9 -9
- package/dist/server/flow-surfaces/blueprint/normalize-document.js +5 -1
- package/dist/server/flow-surfaces/catalog.js +26 -9
- package/dist/server/flow-surfaces/chart-config.js +231 -14
- package/dist/server/flow-surfaces/compose-compiler.d.ts +2 -0
- package/dist/server/flow-surfaces/compose-compiler.js +2 -0
- package/dist/server/flow-surfaces/compose-runtime.js +4 -7
- package/dist/server/flow-surfaces/configure-options.js +19 -8
- 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/locator.js +16 -2
- 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/ctx-libs-member-mismatch-stop/index.js +1 -1
- package/dist/server/flow-surfaces/runjs-authoring/index.d.ts +2 -25
- package/dist/server/flow-surfaces/runjs-authoring/index.js +5 -7033
- 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 +17 -3
- package/dist/server/flow-surfaces/service-utils.js +14 -5
- package/dist/server/flow-surfaces/service.d.ts +74 -15
- package/dist/server/flow-surfaces/service.js +1781 -193
- package/dist/server/flow-surfaces/template-service-utils.d.ts +1 -0
- 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 +180 -2
- package/dist/swagger/flow-surfaces.examples.d.ts +11 -37
- package/dist/swagger/flow-surfaces.examples.js +6 -6
- package/dist/swagger/flow-surfaces.js +136 -54
- package/dist/swagger/index.d.ts +180 -2
- package/package.json +2 -2
|
@@ -0,0 +1,1583 @@
|
|
|
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
|
+
|
|
10
|
+
var __create = Object.create;
|
|
11
|
+
var __defProp = Object.defineProperty;
|
|
12
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
13
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
14
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
15
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
16
|
+
var __export = (target, all) => {
|
|
17
|
+
for (var name in all)
|
|
18
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
19
|
+
};
|
|
20
|
+
var __copyProps = (to, from, except, desc) => {
|
|
21
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
22
|
+
for (let key of __getOwnPropNames(from))
|
|
23
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
24
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
25
|
+
}
|
|
26
|
+
return to;
|
|
27
|
+
};
|
|
28
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
29
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
30
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
31
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
32
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
33
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
34
|
+
mod
|
|
35
|
+
));
|
|
36
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
37
|
+
var filter_exports = {};
|
|
38
|
+
__export(filter_exports, {
|
|
39
|
+
collectAstInvalidResourceFilterCalls: () => collectAstInvalidResourceFilterCalls
|
|
40
|
+
});
|
|
41
|
+
module.exports = __toCommonJS(filter_exports);
|
|
42
|
+
var _ = __toESM(require("lodash"));
|
|
43
|
+
var import_errors = require("../../errors");
|
|
44
|
+
var import_service_helpers = require("../../service-helpers");
|
|
45
|
+
var import_filter_group = require("../../filter-group");
|
|
46
|
+
var import_constants = require("../runtime/constants");
|
|
47
|
+
var import_surface = require("../runtime/surface");
|
|
48
|
+
var import_source = require("../ast/source");
|
|
49
|
+
var import_walk = require("../ast/walk");
|
|
50
|
+
var import_bindings = require("../ast/bindings");
|
|
51
|
+
var import_static_values = require("../ast/static-values");
|
|
52
|
+
var import_resource = require("./resource");
|
|
53
|
+
function collectAstInvalidResourceFilterCalls(ast, source, aliases, identifierBindings, ctxMethodAliases, stringBindings, staticFilterValueBindings, context) {
|
|
54
|
+
const entries = [];
|
|
55
|
+
const ctxResourceStates = /* @__PURE__ */ new Map();
|
|
56
|
+
const aliasStates = /* @__PURE__ */ new Map();
|
|
57
|
+
const events = [];
|
|
58
|
+
const scopeKey = (scope) => `${scope.start}:${scope.end}`;
|
|
59
|
+
const aliasKey = (alias) => `${alias.name}:${alias.declarationStart ?? alias.start}`;
|
|
60
|
+
const mergeResourceState = (state, nextState) => {
|
|
61
|
+
state.capability = nextState.capability;
|
|
62
|
+
state.dataSourceKey = nextState.dataSourceKey;
|
|
63
|
+
state.resourceType = nextState.resourceType;
|
|
64
|
+
state.collectionName = nextState.collectionName;
|
|
65
|
+
return state;
|
|
66
|
+
};
|
|
67
|
+
const defaultCtxState = () => ({
|
|
68
|
+
capability: "ctx.resource",
|
|
69
|
+
collectionName: (0, import_surface.normalizeText)(context.currentCollectionName || context.hostCollectionName) || void 0,
|
|
70
|
+
dataSourceKey: (0, import_surface.normalizeText)(context.currentDataSourceKey || context.hostDataSourceKey) || "main",
|
|
71
|
+
resourceType: "unknown"
|
|
72
|
+
});
|
|
73
|
+
const getAliasState = (alias) => {
|
|
74
|
+
const key = aliasKey(alias);
|
|
75
|
+
const current = aliasStates.get(key);
|
|
76
|
+
if (current) {
|
|
77
|
+
return current;
|
|
78
|
+
}
|
|
79
|
+
const initial = alias.capability === "ctx.resource" ? {
|
|
80
|
+
...defaultCtxState(),
|
|
81
|
+
resourceType: alias.resourceType === "unknown" ? defaultCtxState().resourceType : alias.resourceType
|
|
82
|
+
} : {
|
|
83
|
+
capability: alias.capability,
|
|
84
|
+
dataSourceKey: "main",
|
|
85
|
+
resourceType: alias.resourceType
|
|
86
|
+
};
|
|
87
|
+
aliasStates.set(key, initial);
|
|
88
|
+
return initial;
|
|
89
|
+
};
|
|
90
|
+
const setAliasState = (alias, state) => {
|
|
91
|
+
if (alias.resourceType !== "unknown") {
|
|
92
|
+
state.resourceType = alias.resourceType;
|
|
93
|
+
}
|
|
94
|
+
aliasStates.set(aliasKey(alias), state);
|
|
95
|
+
return state;
|
|
96
|
+
};
|
|
97
|
+
const setCtxState = (executionScope, state) => {
|
|
98
|
+
const nextState = {
|
|
99
|
+
...state,
|
|
100
|
+
capability: "ctx.resource"
|
|
101
|
+
};
|
|
102
|
+
ctxResourceStates.set(scopeKey(executionScope), {
|
|
103
|
+
scope: executionScope,
|
|
104
|
+
state: nextState
|
|
105
|
+
});
|
|
106
|
+
return nextState;
|
|
107
|
+
};
|
|
108
|
+
const getCtxState = (executionScope) => {
|
|
109
|
+
var _a, _b;
|
|
110
|
+
const exact = (_a = ctxResourceStates.get(scopeKey(executionScope))) == null ? void 0 : _a.state;
|
|
111
|
+
if (exact) {
|
|
112
|
+
return exact;
|
|
113
|
+
}
|
|
114
|
+
const inherited = (_b = Array.from(ctxResourceStates.values()).filter(({ scope }) => scope.start <= executionScope.start && scope.end >= executionScope.end).sort(
|
|
115
|
+
(left, right) => left.scope.end - left.scope.start - (right.scope.end - right.scope.start) || right.scope.start - left.scope.start
|
|
116
|
+
)[0]) == null ? void 0 : _b.state;
|
|
117
|
+
if (inherited) {
|
|
118
|
+
return inherited;
|
|
119
|
+
}
|
|
120
|
+
return setCtxState(executionScope, defaultCtxState());
|
|
121
|
+
};
|
|
122
|
+
const findDeclaredAlias = (aliasName, index) => aliases.filter((alias) => alias.name === aliasName && (alias.declarationStart ?? alias.start) <= index).sort((left, right) => (right.declarationStart ?? right.start) - (left.declarationStart ?? left.start))[0];
|
|
123
|
+
const resolveStaticStringArg = (node) => {
|
|
124
|
+
const resolved = (0, import_static_values.resolveAstResourceTypeExpression)(node, source, stringBindings, identifierBindings);
|
|
125
|
+
return resolved.status === "resolved" ? resolved.value : void 0;
|
|
126
|
+
};
|
|
127
|
+
const applyStaticResourceStateMethod = (state, method, node) => {
|
|
128
|
+
var _a, _b;
|
|
129
|
+
if (method === "setDataSourceKey") {
|
|
130
|
+
const dataSourceKey = resolveStaticStringArg((_a = node.arguments) == null ? void 0 : _a[0]);
|
|
131
|
+
return {
|
|
132
|
+
...state,
|
|
133
|
+
dataSourceKey: dataSourceKey || ""
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
if (method === "setResourceName") {
|
|
137
|
+
const collectionName = resolveStaticStringArg((_b = node.arguments) == null ? void 0 : _b[0]);
|
|
138
|
+
return {
|
|
139
|
+
...state,
|
|
140
|
+
collectionName
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
return state;
|
|
144
|
+
};
|
|
145
|
+
const getAliasResourceTarget = (alias, executionScope) => ({
|
|
146
|
+
capability: alias.capability,
|
|
147
|
+
state: getAliasState(alias),
|
|
148
|
+
updateState: (nextState) => {
|
|
149
|
+
mergeResourceState(getAliasState(alias), nextState);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
const resolveResourceExpressionTarget = (node, executionScope) => {
|
|
153
|
+
const unwrapped = (0, import_bindings.unwrapAstChainExpression)(node);
|
|
154
|
+
if (!unwrapped) {
|
|
155
|
+
return void 0;
|
|
156
|
+
}
|
|
157
|
+
if ((0, import_resource.isAstCtxResourceMember)(unwrapped, identifierBindings)) {
|
|
158
|
+
return {
|
|
159
|
+
capability: "ctx.resource",
|
|
160
|
+
state: getCtxState(executionScope),
|
|
161
|
+
updateState: (nextState) => mergeResourceState(getCtxState(executionScope), nextState)
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
if (unwrapped.type === "Identifier") {
|
|
165
|
+
const alias = (0, import_static_values.resolveAstAliasBinding)(unwrapped.name, unwrapped.start || 0, aliases, identifierBindings);
|
|
166
|
+
return alias ? getAliasResourceTarget(alias, executionScope) : void 0;
|
|
167
|
+
}
|
|
168
|
+
const factory = (0, import_resource.getAstFlowResourceFactoryCallFromAst)(
|
|
169
|
+
unwrapped,
|
|
170
|
+
ctxMethodAliases,
|
|
171
|
+
source,
|
|
172
|
+
stringBindings,
|
|
173
|
+
identifierBindings
|
|
174
|
+
);
|
|
175
|
+
if (factory) {
|
|
176
|
+
return {
|
|
177
|
+
capability: factory.capability,
|
|
178
|
+
state: {
|
|
179
|
+
capability: factory.capability,
|
|
180
|
+
dataSourceKey: "main",
|
|
181
|
+
resourceType: factory.resourceType
|
|
182
|
+
},
|
|
183
|
+
updateState: _.noop
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
if (unwrapped.type === "CallExpression") {
|
|
187
|
+
const callTarget = getResourceCallTarget(unwrapped, executionScope);
|
|
188
|
+
if (!callTarget || !import_constants.RUNJS_RESOURCE_CHAINABLE_STATE_METHODS.has(callTarget.method)) {
|
|
189
|
+
return void 0;
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
...callTarget,
|
|
193
|
+
state: applyStaticResourceStateMethod(callTarget.state, callTarget.method, unwrapped)
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
return void 0;
|
|
197
|
+
};
|
|
198
|
+
const resolveExpressionState = (node, executionScope) => {
|
|
199
|
+
var _a;
|
|
200
|
+
return (_a = resolveResourceExpressionTarget(node, executionScope)) == null ? void 0 : _a.state;
|
|
201
|
+
};
|
|
202
|
+
const getResourceCallTarget = (node, executionScope) => {
|
|
203
|
+
const callee = (0, import_bindings.unwrapAstChainExpression)(node.callee);
|
|
204
|
+
if (!callee || callee.type !== "MemberExpression") {
|
|
205
|
+
return void 0;
|
|
206
|
+
}
|
|
207
|
+
const method = (0, import_static_values.getAstStaticPropertyName)(callee);
|
|
208
|
+
if (!method) {
|
|
209
|
+
return void 0;
|
|
210
|
+
}
|
|
211
|
+
const objectTarget = resolveResourceExpressionTarget(callee.object, executionScope);
|
|
212
|
+
if (objectTarget) {
|
|
213
|
+
return {
|
|
214
|
+
...objectTarget,
|
|
215
|
+
capability: (0, import_source.getAstSource)(callee, source),
|
|
216
|
+
method
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
return void 0;
|
|
220
|
+
};
|
|
221
|
+
(0, import_walk.walkAstAncestor)(ast, {
|
|
222
|
+
AssignmentExpression(node, ancestors) {
|
|
223
|
+
var _a, _b;
|
|
224
|
+
if (!(0, import_static_values.isAstCtxApiAliasAssignmentOperator)(node.operator)) {
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
const alwaysRuns = (0, import_bindings.isAstAlwaysExecutedInCurrentExecutionScope)(ancestors);
|
|
228
|
+
const executionScope = (0, import_bindings.getAstExecutionScopeRange)(ancestors, source.length);
|
|
229
|
+
if (((_a = node.left) == null ? void 0 : _a.type) === "Identifier") {
|
|
230
|
+
events.push({
|
|
231
|
+
type: "aliasBind",
|
|
232
|
+
aliasName: node.left.name,
|
|
233
|
+
alwaysRuns,
|
|
234
|
+
end: typeof node.end === "number" ? node.end : node.start || 0,
|
|
235
|
+
executionScope,
|
|
236
|
+
index: node.start || 0,
|
|
237
|
+
sourceNode: node.right
|
|
238
|
+
});
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
if (((_b = node.left) == null ? void 0 : _b.type) === "ObjectPattern" && (0, import_static_values.isUnshadowedCtxIdentifier)(node.right, identifierBindings)) {
|
|
242
|
+
(0, import_static_values.collectAstObjectPatternAliases)(node.left, (aliasName, member, aliasNode) => {
|
|
243
|
+
if (member !== "resource") {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
events.push({
|
|
247
|
+
type: "ctxResourceAliasBind",
|
|
248
|
+
aliasName,
|
|
249
|
+
alwaysRuns,
|
|
250
|
+
end: typeof (aliasNode == null ? void 0 : aliasNode.end) === "number" ? aliasNode.end : node.end || node.start || 0,
|
|
251
|
+
executionScope,
|
|
252
|
+
index: typeof (aliasNode == null ? void 0 : aliasNode.start) === "number" ? aliasNode.start : node.start || 0
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
CallExpression(node, ancestors) {
|
|
258
|
+
var _a;
|
|
259
|
+
const executionScope = (0, import_bindings.getAstExecutionScopeRange)(ancestors, source.length);
|
|
260
|
+
const alwaysRuns = (0, import_bindings.isAstAlwaysExecutedInCurrentExecutionScope)(ancestors);
|
|
261
|
+
const ctxMethod = (0, import_static_values.resolveCtxMethodCall)(node, ctxMethodAliases, identifierBindings);
|
|
262
|
+
if ((ctxMethod == null ? void 0 : ctxMethod.method) === "initResource") {
|
|
263
|
+
const resolved = ((_a = node.arguments) == null ? void 0 : _a[0]) ? (0, import_static_values.resolveAstResourceTypeExpression)(node.arguments[0], source, stringBindings, identifierBindings) : void 0;
|
|
264
|
+
events.push({
|
|
265
|
+
type: "initResource",
|
|
266
|
+
alwaysRuns,
|
|
267
|
+
end: typeof node.end === "number" ? node.end : node.start || 0,
|
|
268
|
+
executionScope,
|
|
269
|
+
index: node.start || 0,
|
|
270
|
+
resourceType: (resolved == null ? void 0 : resolved.status) === "resolved" && import_constants.INIT_RESOURCE_CLASS_NAMES.has(resolved.value) ? resolved.value : "unknown"
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
if (!getResourceCallTarget(node, executionScope)) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
events.push({
|
|
277
|
+
type: "resourceCall",
|
|
278
|
+
alwaysRuns,
|
|
279
|
+
end: typeof node.end === "number" ? node.end : node.start || 0,
|
|
280
|
+
executionScope,
|
|
281
|
+
index: node.start || 0,
|
|
282
|
+
node
|
|
283
|
+
});
|
|
284
|
+
},
|
|
285
|
+
VariableDeclarator(node, ancestors) {
|
|
286
|
+
var _a, _b;
|
|
287
|
+
const alwaysRuns = (0, import_bindings.isAstAlwaysExecutedInCurrentExecutionScope)(ancestors);
|
|
288
|
+
const executionScope = (0, import_bindings.getAstExecutionScopeRange)(ancestors, source.length);
|
|
289
|
+
if (((_a = node.id) == null ? void 0 : _a.type) === "Identifier") {
|
|
290
|
+
events.push({
|
|
291
|
+
type: "aliasBind",
|
|
292
|
+
aliasName: node.id.name,
|
|
293
|
+
alwaysRuns,
|
|
294
|
+
end: typeof node.end === "number" ? node.end : node.start || 0,
|
|
295
|
+
executionScope,
|
|
296
|
+
index: node.start || 0,
|
|
297
|
+
sourceNode: node.init
|
|
298
|
+
});
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
if (((_b = node.id) == null ? void 0 : _b.type) === "ObjectPattern" && (0, import_static_values.isUnshadowedCtxIdentifier)(node.init, identifierBindings)) {
|
|
302
|
+
(0, import_static_values.collectAstObjectPatternAliases)(node.id, (aliasName, member, aliasNode) => {
|
|
303
|
+
if (member !== "resource") {
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
events.push({
|
|
307
|
+
type: "ctxResourceAliasBind",
|
|
308
|
+
aliasName,
|
|
309
|
+
alwaysRuns,
|
|
310
|
+
end: typeof (aliasNode == null ? void 0 : aliasNode.end) === "number" ? aliasNode.end : node.end || node.start || 0,
|
|
311
|
+
executionScope,
|
|
312
|
+
index: typeof (aliasNode == null ? void 0 : aliasNode.start) === "number" ? aliasNode.start : node.start || 0
|
|
313
|
+
});
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
ctxResourceStates.clear();
|
|
319
|
+
aliasStates.clear();
|
|
320
|
+
const resourceFilterScopes = Array.from(
|
|
321
|
+
new Map(events.map((event) => [scopeKey(event.executionScope), event.executionScope])).values()
|
|
322
|
+
);
|
|
323
|
+
const resourceFilterScopeDepth = (scope) => resourceFilterScopes.filter(
|
|
324
|
+
(candidate) => candidate.start < scope.start && candidate.end >= scope.end && !(0, import_bindings.isSameAstRange)(candidate, scope)
|
|
325
|
+
).length;
|
|
326
|
+
events.sort(
|
|
327
|
+
(left, right) => resourceFilterScopeDepth(left.executionScope) - resourceFilterScopeDepth(right.executionScope) || left.executionScope.start - right.executionScope.start || left.index - right.index || left.end - right.end
|
|
328
|
+
).forEach((event) => {
|
|
329
|
+
var _a;
|
|
330
|
+
if (event.type === "initResource") {
|
|
331
|
+
if (!event.alwaysRuns) {
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
setCtxState(event.executionScope, {
|
|
335
|
+
capability: "ctx.resource",
|
|
336
|
+
dataSourceKey: "main",
|
|
337
|
+
resourceType: event.resourceType
|
|
338
|
+
});
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
if (event.type === "aliasBind") {
|
|
342
|
+
if (!event.alwaysRuns) {
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
const alias = findDeclaredAlias(event.aliasName, event.index);
|
|
346
|
+
const state = resolveExpressionState(event.sourceNode, event.executionScope);
|
|
347
|
+
if (alias && state) {
|
|
348
|
+
setAliasState(alias, state);
|
|
349
|
+
}
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
if (event.type === "ctxResourceAliasBind") {
|
|
353
|
+
if (!event.alwaysRuns) {
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
const alias = findDeclaredAlias(event.aliasName, event.index);
|
|
357
|
+
if (alias) {
|
|
358
|
+
setAliasState(alias, getCtxState(event.executionScope));
|
|
359
|
+
}
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
const target = getResourceCallTarget(event.node, event.executionScope);
|
|
363
|
+
if (!target) {
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
if (target.method === "setDataSourceKey") {
|
|
367
|
+
if (!event.alwaysRuns) {
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
target.updateState(applyStaticResourceStateMethod(target.state, target.method, event.node));
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
if (target.method === "setResourceName") {
|
|
374
|
+
if (!event.alwaysRuns) {
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
target.updateState(applyStaticResourceStateMethod(target.state, target.method, event.node));
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
const filterArgumentIndex = target.method === "setFilter" ? 0 : target.method === "addFilterGroup" ? 1 : void 0;
|
|
381
|
+
if (typeof filterArgumentIndex !== "number") {
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
const filterArg = resolveRunJsStaticFilterRootNode(
|
|
385
|
+
(_a = event.node.arguments) == null ? void 0 : _a[filterArgumentIndex],
|
|
386
|
+
identifierBindings,
|
|
387
|
+
staticFilterValueBindings
|
|
388
|
+
);
|
|
389
|
+
if (!filterArg) {
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
entries.push(
|
|
393
|
+
...collectAstResourceFilterRootErrors({
|
|
394
|
+
source,
|
|
395
|
+
path: "",
|
|
396
|
+
capability: target.capability,
|
|
397
|
+
dataSourceKey: target.state.dataSourceKey,
|
|
398
|
+
collectionName: target.state.collectionName,
|
|
399
|
+
resourceType: target.state.resourceType,
|
|
400
|
+
filterNode: filterArg,
|
|
401
|
+
context,
|
|
402
|
+
identifierBindings,
|
|
403
|
+
staticFilterValueBindings,
|
|
404
|
+
index: typeof filterArg.node.start === "number" ? filterArg.node.start : event.node.start || 0
|
|
405
|
+
})
|
|
406
|
+
);
|
|
407
|
+
});
|
|
408
|
+
entries.push(
|
|
409
|
+
...collectAstForwardedResourceFilterArgumentErrors({
|
|
410
|
+
ast,
|
|
411
|
+
source,
|
|
412
|
+
identifierBindings,
|
|
413
|
+
stringBindings,
|
|
414
|
+
staticFilterValueBindings,
|
|
415
|
+
context
|
|
416
|
+
})
|
|
417
|
+
);
|
|
418
|
+
return entries;
|
|
419
|
+
}
|
|
420
|
+
function collectAstForwardedResourceFilterArgumentErrors(input) {
|
|
421
|
+
const helpers = collectAstResourceFilterHelpers(input.ast, input.source, input.identifierBindings);
|
|
422
|
+
if (!helpers.length) {
|
|
423
|
+
return [];
|
|
424
|
+
}
|
|
425
|
+
const errors = [];
|
|
426
|
+
(0, import_walk.walkAstAncestor)(input.ast, {
|
|
427
|
+
CallExpression(node) {
|
|
428
|
+
var _a;
|
|
429
|
+
const callee = (0, import_bindings.unwrapAstChainExpression)(node.callee);
|
|
430
|
+
if ((callee == null ? void 0 : callee.type) !== "Identifier") {
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
const helper = (0, import_static_values.resolveAstAliasBinding)(callee.name, node.start || 0, helpers, input.identifierBindings);
|
|
434
|
+
if (!helper) {
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
const filterArg = resolveRunJsStaticFilterRootNode(
|
|
438
|
+
(_a = node.arguments) == null ? void 0 : _a[helper.filterParamIndex],
|
|
439
|
+
input.identifierBindings,
|
|
440
|
+
input.staticFilterValueBindings
|
|
441
|
+
);
|
|
442
|
+
if (!filterArg) {
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
const collectionName = helper.collectionName || resolveAstResourceFilterHelperCollectionName(
|
|
446
|
+
helper,
|
|
447
|
+
node.arguments,
|
|
448
|
+
input.source,
|
|
449
|
+
input.stringBindings,
|
|
450
|
+
input.identifierBindings
|
|
451
|
+
);
|
|
452
|
+
if (!collectionName) {
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
errors.push(
|
|
456
|
+
...collectAstResourceFilterRootErrors({
|
|
457
|
+
source: input.source,
|
|
458
|
+
path: "",
|
|
459
|
+
capability: `${helper.name}.setFilter`,
|
|
460
|
+
dataSourceKey: helper.dataSourceKey || "main",
|
|
461
|
+
collectionName,
|
|
462
|
+
resourceType: helper.resourceType || "unknown",
|
|
463
|
+
filterNode: filterArg,
|
|
464
|
+
context: input.context,
|
|
465
|
+
identifierBindings: input.identifierBindings,
|
|
466
|
+
staticFilterValueBindings: input.staticFilterValueBindings,
|
|
467
|
+
index: typeof filterArg.node.start === "number" ? filterArg.node.start : node.start || 0
|
|
468
|
+
})
|
|
469
|
+
);
|
|
470
|
+
}
|
|
471
|
+
});
|
|
472
|
+
return errors;
|
|
473
|
+
}
|
|
474
|
+
function collectAstResourceFilterHelpers(ast, source, identifierBindings) {
|
|
475
|
+
const helpers = [];
|
|
476
|
+
const addHelper = (name, functionNode, bindingNode, scope) => {
|
|
477
|
+
var _a;
|
|
478
|
+
if (!name || !((_a = functionNode == null ? void 0 : functionNode.params) == null ? void 0 : _a.length)) {
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
const paramNames = functionNode.params.map(import_static_values.getAstBindingIdentifierName);
|
|
482
|
+
const resourceStates = /* @__PURE__ */ new Map();
|
|
483
|
+
const isInsideNestedFunction = (ancestors) => ancestors.some((ancestor) => ancestor !== functionNode.body && (0, import_bindings.isAstFunctionLike)(ancestor));
|
|
484
|
+
const ensureResourceState = (name2, factory) => {
|
|
485
|
+
if (!name2) {
|
|
486
|
+
return void 0;
|
|
487
|
+
}
|
|
488
|
+
const existing = resourceStates.get(name2);
|
|
489
|
+
if (existing) {
|
|
490
|
+
if (factory == null ? void 0 : factory.resourceType) {
|
|
491
|
+
existing.resourceType = factory.resourceType;
|
|
492
|
+
}
|
|
493
|
+
return existing;
|
|
494
|
+
}
|
|
495
|
+
const state = {
|
|
496
|
+
collectionName: "",
|
|
497
|
+
collectionParamNames: /* @__PURE__ */ new Set(),
|
|
498
|
+
dataSourceKey: "main",
|
|
499
|
+
filterParamNames: /* @__PURE__ */ new Set(),
|
|
500
|
+
resourceType: factory == null ? void 0 : factory.resourceType
|
|
501
|
+
};
|
|
502
|
+
resourceStates.set(name2, state);
|
|
503
|
+
return state;
|
|
504
|
+
};
|
|
505
|
+
const getResourceStateForMember = (memberExpression) => {
|
|
506
|
+
const object = (0, import_bindings.unwrapAstChainExpression)(memberExpression == null ? void 0 : memberExpression.object);
|
|
507
|
+
if ((object == null ? void 0 : object.type) !== "Identifier") {
|
|
508
|
+
return void 0;
|
|
509
|
+
}
|
|
510
|
+
return resourceStates.get(object.name);
|
|
511
|
+
};
|
|
512
|
+
const collectResourceAlias = (aliasName, sourceNode) => {
|
|
513
|
+
const factory = (0, import_resource.getAstFlowResourceFactoryCallFromAst)(sourceNode, [], source, [], identifierBindings);
|
|
514
|
+
if (factory) {
|
|
515
|
+
ensureResourceState(aliasName, factory);
|
|
516
|
+
}
|
|
517
|
+
};
|
|
518
|
+
(0, import_walk.walkAstAncestor)(functionNode.body || functionNode, {
|
|
519
|
+
AssignmentExpression(node, ancestors) {
|
|
520
|
+
var _a2;
|
|
521
|
+
if (isInsideNestedFunction(ancestors) || ((_a2 = node.left) == null ? void 0 : _a2.type) !== "Identifier") {
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
collectResourceAlias(node.left.name, node.right);
|
|
525
|
+
},
|
|
526
|
+
CallExpression(node, ancestors) {
|
|
527
|
+
var _a2, _b, _c;
|
|
528
|
+
if (isInsideNestedFunction(ancestors)) {
|
|
529
|
+
return;
|
|
530
|
+
}
|
|
531
|
+
const callee = (0, import_bindings.unwrapAstChainExpression)(node.callee);
|
|
532
|
+
if ((callee == null ? void 0 : callee.type) !== "MemberExpression") {
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
const resourceState = getResourceStateForMember(callee);
|
|
536
|
+
if (!resourceState) {
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
const method = (0, import_static_values.getAstStaticPropertyName)(callee);
|
|
540
|
+
if (method === "setFilter" || method === "addFilterGroup") {
|
|
541
|
+
const arg = (0, import_bindings.unwrapAstChainExpression)((_a2 = node.arguments) == null ? void 0 : _a2[method === "addFilterGroup" ? 1 : 0]);
|
|
542
|
+
if ((arg == null ? void 0 : arg.type) === "Identifier" && paramNames.includes(arg.name)) {
|
|
543
|
+
resourceState.filterParamNames.add(arg.name);
|
|
544
|
+
}
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
if (method === "setResourceName") {
|
|
548
|
+
const arg = (0, import_bindings.unwrapAstChainExpression)((_b = node.arguments) == null ? void 0 : _b[0]);
|
|
549
|
+
if ((arg == null ? void 0 : arg.type) === "Identifier" && paramNames.includes(arg.name)) {
|
|
550
|
+
resourceState.collectionParamNames.add(arg.name);
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
553
|
+
const resolved = (0, import_static_values.resolveAstStaticStringValue)(arg, source);
|
|
554
|
+
if (typeof resolved === "string") {
|
|
555
|
+
resourceState.collectionName = resolved;
|
|
556
|
+
}
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
if (method === "setDataSourceKey") {
|
|
560
|
+
const resolved = (0, import_static_values.resolveAstStaticStringValue)((_c = node.arguments) == null ? void 0 : _c[0], source);
|
|
561
|
+
if (typeof resolved === "string") {
|
|
562
|
+
resourceState.dataSourceKey = resolved;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
},
|
|
566
|
+
VariableDeclarator(node, ancestors) {
|
|
567
|
+
var _a2;
|
|
568
|
+
if (isInsideNestedFunction(ancestors) || ((_a2 = node.id) == null ? void 0 : _a2.type) !== "Identifier") {
|
|
569
|
+
return;
|
|
570
|
+
}
|
|
571
|
+
collectResourceAlias(node.id.name, node.init);
|
|
572
|
+
}
|
|
573
|
+
});
|
|
574
|
+
for (const state of resourceStates.values()) {
|
|
575
|
+
state.filterParamNames.forEach((filterParamName) => {
|
|
576
|
+
const filterParamIndex = paramNames.indexOf(filterParamName);
|
|
577
|
+
if (filterParamIndex < 0) {
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
580
|
+
const collectionParamIndex = Array.from(state.collectionParamNames).map((paramName) => paramNames.indexOf(paramName)).find((index) => index >= 0);
|
|
581
|
+
helpers.push({
|
|
582
|
+
collectionName: state.collectionName,
|
|
583
|
+
collectionParamIndex,
|
|
584
|
+
dataSourceKey: state.dataSourceKey,
|
|
585
|
+
declarationStart: typeof (bindingNode == null ? void 0 : bindingNode.start) === "number" ? bindingNode.start : scope.start,
|
|
586
|
+
filterParamIndex,
|
|
587
|
+
name,
|
|
588
|
+
resourceType: state.resourceType,
|
|
589
|
+
start: scope.start,
|
|
590
|
+
end: scope.end
|
|
591
|
+
});
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
};
|
|
595
|
+
(0, import_walk.walkAstAncestor)(ast, {
|
|
596
|
+
FunctionDeclaration(node, ancestors) {
|
|
597
|
+
var _a;
|
|
598
|
+
if (((_a = node.id) == null ? void 0 : _a.type) !== "Identifier") {
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
addHelper(node.id.name, node, node.id, (0, import_bindings.getAstBindingScopeRange)(ancestors.slice(0, -1), source.length));
|
|
602
|
+
},
|
|
603
|
+
VariableDeclarator(node, ancestors) {
|
|
604
|
+
var _a;
|
|
605
|
+
if (((_a = node.id) == null ? void 0 : _a.type) !== "Identifier" || !(0, import_bindings.isAstFunctionLike)((0, import_bindings.unwrapAstChainExpression)(node.init))) {
|
|
606
|
+
return;
|
|
607
|
+
}
|
|
608
|
+
const declaration = (0, import_bindings.findAstAncestor)(ancestors, "VariableDeclaration");
|
|
609
|
+
addHelper(
|
|
610
|
+
node.id.name,
|
|
611
|
+
(0, import_bindings.unwrapAstChainExpression)(node.init),
|
|
612
|
+
node.id,
|
|
613
|
+
(0, import_bindings.getAstBindingScopeRange)(ancestors, source.length, (declaration == null ? void 0 : declaration.kind) === "var")
|
|
614
|
+
);
|
|
615
|
+
}
|
|
616
|
+
});
|
|
617
|
+
return helpers;
|
|
618
|
+
}
|
|
619
|
+
function resolveAstResourceFilterHelperCollectionName(helper, args, source, stringBindings, identifierBindings) {
|
|
620
|
+
if (typeof helper.collectionParamIndex !== "number") {
|
|
621
|
+
return "";
|
|
622
|
+
}
|
|
623
|
+
const arg = args == null ? void 0 : args[helper.collectionParamIndex];
|
|
624
|
+
if (!arg) {
|
|
625
|
+
return "";
|
|
626
|
+
}
|
|
627
|
+
const resolved = (0, import_static_values.resolveAstResourceTypeExpression)(arg, source, stringBindings, identifierBindings);
|
|
628
|
+
return resolved.status === "resolved" ? resolved.value : "";
|
|
629
|
+
}
|
|
630
|
+
function collectAstResourceFilterRootErrors(input) {
|
|
631
|
+
if (!isRunJsRecordFilterResourceType(input.resourceType)) {
|
|
632
|
+
return [];
|
|
633
|
+
}
|
|
634
|
+
if (input.filterNode.kind === "array") {
|
|
635
|
+
return [buildRunJsResourceFilterShapeError({ ...input, invalidShape: "array" })];
|
|
636
|
+
}
|
|
637
|
+
if (isRunJsFilterGroupObjectNode(input.filterNode.node, input.identifierBindings, input.staticFilterValueBindings)) {
|
|
638
|
+
return [buildRunJsResourceFilterShapeError({ ...input, invalidShape: "filter-group" })];
|
|
639
|
+
}
|
|
640
|
+
return collectAstResourceFilterObjectErrors({
|
|
641
|
+
...input,
|
|
642
|
+
filterObject: input.filterNode.node
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
function collectAstResourceFilterObjectErrors(input) {
|
|
646
|
+
if (!isRunJsRecordFilterResourceType(input.resourceType)) {
|
|
647
|
+
return [];
|
|
648
|
+
}
|
|
649
|
+
if (!input.dataSourceKey || !input.collectionName || !input.context.getCollection) {
|
|
650
|
+
return [];
|
|
651
|
+
}
|
|
652
|
+
const dataSourceKey = input.dataSourceKey;
|
|
653
|
+
const collectionName = input.collectionName;
|
|
654
|
+
const collection = input.context.getCollection(dataSourceKey, collectionName);
|
|
655
|
+
if (!collection) {
|
|
656
|
+
return [
|
|
657
|
+
{
|
|
658
|
+
capability: input.capability,
|
|
659
|
+
collectionName,
|
|
660
|
+
dataSourceKey,
|
|
661
|
+
index: input.index,
|
|
662
|
+
message: `flowSurfaces authoring ${input.capability}(...) references unknown collection '${dataSourceKey}.${collectionName}' while validating setFilter(...)`,
|
|
663
|
+
resourceType: input.resourceType,
|
|
664
|
+
ruleId: "runjs-resource-collection-unknown"
|
|
665
|
+
}
|
|
666
|
+
];
|
|
667
|
+
}
|
|
668
|
+
return collectAstResourceFilterProperties({
|
|
669
|
+
...input,
|
|
670
|
+
collectionName,
|
|
671
|
+
dataSourceKey,
|
|
672
|
+
collection,
|
|
673
|
+
rootCollection: collection
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
function isRunJsRecordFilterResourceType(resourceType) {
|
|
677
|
+
return resourceType === "unknown" || resourceType === "MultiRecordResource" || resourceType === "SingleRecordResource";
|
|
678
|
+
}
|
|
679
|
+
function collectAstResourceFilterProperties(input) {
|
|
680
|
+
var _a;
|
|
681
|
+
const errors = [];
|
|
682
|
+
for (const property of input.filterObject.properties || []) {
|
|
683
|
+
if (!property || property.type === "SpreadElement") {
|
|
684
|
+
continue;
|
|
685
|
+
}
|
|
686
|
+
const key = (0, import_static_values.getAstStaticPropertyName)(property);
|
|
687
|
+
if (!key) {
|
|
688
|
+
continue;
|
|
689
|
+
}
|
|
690
|
+
const keyIndex = typeof ((_a = property.key) == null ? void 0 : _a.start) === "number" ? property.key.start : property.start || 0;
|
|
691
|
+
if (key === "$not") {
|
|
692
|
+
const value2 = resolveRunJsStaticFilterObjectNode(
|
|
693
|
+
property.value,
|
|
694
|
+
input.identifierBindings,
|
|
695
|
+
input.staticFilterValueBindings
|
|
696
|
+
);
|
|
697
|
+
if (value2) {
|
|
698
|
+
errors.push(
|
|
699
|
+
...collectAstResourceFilterProperties({
|
|
700
|
+
...input,
|
|
701
|
+
filterObject: value2
|
|
702
|
+
})
|
|
703
|
+
);
|
|
704
|
+
}
|
|
705
|
+
continue;
|
|
706
|
+
}
|
|
707
|
+
if (key === "$and" || key === "$or") {
|
|
708
|
+
const value2 = resolveRunJsStaticFilterArrayNode(
|
|
709
|
+
property.value,
|
|
710
|
+
input.identifierBindings,
|
|
711
|
+
input.staticFilterValueBindings
|
|
712
|
+
);
|
|
713
|
+
if (value2) {
|
|
714
|
+
for (const element of value2.elements || []) {
|
|
715
|
+
const child = resolveRunJsStaticFilterObjectNode(
|
|
716
|
+
element,
|
|
717
|
+
input.identifierBindings,
|
|
718
|
+
input.staticFilterValueBindings
|
|
719
|
+
);
|
|
720
|
+
if (child) {
|
|
721
|
+
errors.push(
|
|
722
|
+
...collectAstResourceFilterProperties({
|
|
723
|
+
...input,
|
|
724
|
+
filterObject: child
|
|
725
|
+
})
|
|
726
|
+
);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
continue;
|
|
731
|
+
}
|
|
732
|
+
if (key.startsWith("$")) {
|
|
733
|
+
collectAstResourceFilterOperatorErrors(key, keyIndex, input).forEach((entry) => errors.push(entry));
|
|
734
|
+
continue;
|
|
735
|
+
}
|
|
736
|
+
const fieldPath = input.path ? `${input.path}.${key}` : key;
|
|
737
|
+
const resolved = resolveRunJsResourceFilterFieldPath(
|
|
738
|
+
input.rootCollection,
|
|
739
|
+
input.dataSourceKey,
|
|
740
|
+
fieldPath,
|
|
741
|
+
input.context
|
|
742
|
+
);
|
|
743
|
+
if (!resolved.field) {
|
|
744
|
+
errors.push(
|
|
745
|
+
buildRunJsResourceFilterFieldError({
|
|
746
|
+
...input,
|
|
747
|
+
collection: resolved.collection || input.collection,
|
|
748
|
+
fieldPath,
|
|
749
|
+
index: keyIndex
|
|
750
|
+
})
|
|
751
|
+
);
|
|
752
|
+
continue;
|
|
753
|
+
}
|
|
754
|
+
const value = resolveRunJsStaticFilterObjectNode(
|
|
755
|
+
property.value,
|
|
756
|
+
input.identifierBindings,
|
|
757
|
+
input.staticFilterValueBindings
|
|
758
|
+
);
|
|
759
|
+
if (value) {
|
|
760
|
+
errors.push(
|
|
761
|
+
...collectAstResourceFilterValueObjectErrors({
|
|
762
|
+
...input,
|
|
763
|
+
field: resolved.field,
|
|
764
|
+
fieldPath,
|
|
765
|
+
filterObject: value,
|
|
766
|
+
collection: resolved.collection || input.collection
|
|
767
|
+
})
|
|
768
|
+
);
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
return errors;
|
|
772
|
+
}
|
|
773
|
+
function collectAstResourceFilterValueObjectErrors(input) {
|
|
774
|
+
var _a;
|
|
775
|
+
const errors = [];
|
|
776
|
+
if (isRunJsJsonLikeField(input.field)) {
|
|
777
|
+
return errors;
|
|
778
|
+
}
|
|
779
|
+
for (const property of input.filterObject.properties || []) {
|
|
780
|
+
if (!property || property.type === "SpreadElement") {
|
|
781
|
+
continue;
|
|
782
|
+
}
|
|
783
|
+
const key = (0, import_static_values.getAstStaticPropertyName)(property);
|
|
784
|
+
if (!key) {
|
|
785
|
+
continue;
|
|
786
|
+
}
|
|
787
|
+
const keyIndex = typeof ((_a = property.key) == null ? void 0 : _a.start) === "number" ? property.key.start : property.start || 0;
|
|
788
|
+
if (key === "$not") {
|
|
789
|
+
collectAstResourceFilterOperatorErrors(key, keyIndex, input).forEach((entry) => errors.push(entry));
|
|
790
|
+
const value2 = resolveRunJsStaticFilterObjectNode(
|
|
791
|
+
property.value,
|
|
792
|
+
input.identifierBindings,
|
|
793
|
+
input.staticFilterValueBindings
|
|
794
|
+
);
|
|
795
|
+
if (value2) {
|
|
796
|
+
errors.push(
|
|
797
|
+
...collectAstResourceFilterValueObjectErrors({
|
|
798
|
+
...input,
|
|
799
|
+
filterObject: value2
|
|
800
|
+
})
|
|
801
|
+
);
|
|
802
|
+
}
|
|
803
|
+
continue;
|
|
804
|
+
}
|
|
805
|
+
if (key.startsWith("$")) {
|
|
806
|
+
collectAstResourceFilterOperatorErrors(key, keyIndex, input).forEach((entry) => errors.push(entry));
|
|
807
|
+
const invalidDateValue = buildRunJsResourceDateFilterValueError(key, keyIndex, property.value, input);
|
|
808
|
+
if (invalidDateValue) {
|
|
809
|
+
errors.push(invalidDateValue);
|
|
810
|
+
}
|
|
811
|
+
continue;
|
|
812
|
+
}
|
|
813
|
+
if (!(0, import_service_helpers.isAssociationField)(input.field)) {
|
|
814
|
+
errors.push(buildRunJsResourceFilterOperatorError(key, keyIndex, input));
|
|
815
|
+
continue;
|
|
816
|
+
}
|
|
817
|
+
const nestedFieldPath = `${input.fieldPath}.${key}`;
|
|
818
|
+
const resolved = resolveRunJsResourceFilterFieldPath(
|
|
819
|
+
input.rootCollection,
|
|
820
|
+
input.dataSourceKey,
|
|
821
|
+
nestedFieldPath,
|
|
822
|
+
input.context
|
|
823
|
+
);
|
|
824
|
+
if (!resolved.field) {
|
|
825
|
+
errors.push(
|
|
826
|
+
buildRunJsResourceFilterFieldError({
|
|
827
|
+
...input,
|
|
828
|
+
collection: resolved.collection || input.collection,
|
|
829
|
+
fieldPath: nestedFieldPath,
|
|
830
|
+
index: keyIndex
|
|
831
|
+
})
|
|
832
|
+
);
|
|
833
|
+
continue;
|
|
834
|
+
}
|
|
835
|
+
const value = resolveRunJsStaticFilterObjectNode(
|
|
836
|
+
property.value,
|
|
837
|
+
input.identifierBindings,
|
|
838
|
+
input.staticFilterValueBindings
|
|
839
|
+
);
|
|
840
|
+
if (value) {
|
|
841
|
+
errors.push(
|
|
842
|
+
...collectAstResourceFilterValueObjectErrors({
|
|
843
|
+
...input,
|
|
844
|
+
collection: resolved.collection || input.collection,
|
|
845
|
+
field: resolved.field,
|
|
846
|
+
fieldPath: nestedFieldPath,
|
|
847
|
+
filterObject: value
|
|
848
|
+
})
|
|
849
|
+
);
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
return errors;
|
|
853
|
+
}
|
|
854
|
+
function collectAstResourceFilterOperatorErrors(operator, index, input) {
|
|
855
|
+
if (isRunJsSupportedFilterOperator(operator)) {
|
|
856
|
+
return [];
|
|
857
|
+
}
|
|
858
|
+
const suggestedOperator = getSuggestedRunJsFilterOperator(operator);
|
|
859
|
+
return [
|
|
860
|
+
{
|
|
861
|
+
capability: input.capability,
|
|
862
|
+
collectionName: input.collectionName,
|
|
863
|
+
dataSourceKey: input.dataSourceKey,
|
|
864
|
+
fieldPath: input.fieldPath,
|
|
865
|
+
index,
|
|
866
|
+
message: suggestedOperator ? `flowSurfaces authoring ${input.capability}(...) uses unsupported filter operator '${operator}'${input.fieldPath ? ` for field '${input.fieldPath}'` : ""}; use '${suggestedOperator}'` : `flowSurfaces authoring ${input.capability}(...) uses unsupported filter operator '${operator}'`,
|
|
867
|
+
operator,
|
|
868
|
+
resourceType: input.resourceType,
|
|
869
|
+
ruleId: "runjs-resource-filter-operator-invalid",
|
|
870
|
+
suggestedOperator
|
|
871
|
+
}
|
|
872
|
+
];
|
|
873
|
+
}
|
|
874
|
+
function buildRunJsResourceFilterOperatorError(operator, index, input) {
|
|
875
|
+
const suggestedOperator = getSuggestedRunJsFilterOperator(operator);
|
|
876
|
+
if (suggestedOperator) {
|
|
877
|
+
return {
|
|
878
|
+
capability: input.capability,
|
|
879
|
+
collectionName: input.collectionName,
|
|
880
|
+
dataSourceKey: input.dataSourceKey,
|
|
881
|
+
fieldPath: input.fieldPath,
|
|
882
|
+
index,
|
|
883
|
+
message: `flowSurfaces authoring ${input.capability}(...) uses filter operator '${operator}' without '$' for field '${input.fieldPath}'; use '${suggestedOperator}'`,
|
|
884
|
+
operator,
|
|
885
|
+
resourceType: input.resourceType,
|
|
886
|
+
ruleId: "runjs-resource-filter-operator-missing-dollar",
|
|
887
|
+
suggestedOperator
|
|
888
|
+
};
|
|
889
|
+
}
|
|
890
|
+
return {
|
|
891
|
+
capability: input.capability,
|
|
892
|
+
collectionName: input.collectionName,
|
|
893
|
+
dataSourceKey: input.dataSourceKey,
|
|
894
|
+
fieldPath: input.fieldPath,
|
|
895
|
+
index,
|
|
896
|
+
message: `flowSurfaces authoring ${input.capability}(...) uses unsupported filter operator '${operator}' for field '${input.fieldPath}'`,
|
|
897
|
+
operator,
|
|
898
|
+
resourceType: input.resourceType,
|
|
899
|
+
ruleId: "runjs-resource-filter-operator-invalid"
|
|
900
|
+
};
|
|
901
|
+
}
|
|
902
|
+
function buildRunJsResourceDateFilterValueError(operator, index, valueNode, input) {
|
|
903
|
+
if (!isRunJsDateFilterOperator(operator)) {
|
|
904
|
+
return null;
|
|
905
|
+
}
|
|
906
|
+
const valueObject = resolveRunJsStaticFilterObjectNode(
|
|
907
|
+
valueNode,
|
|
908
|
+
input.identifierBindings,
|
|
909
|
+
input.staticFilterValueBindings
|
|
910
|
+
);
|
|
911
|
+
if (valueObject) {
|
|
912
|
+
const unsupportedKeys = collectRunJsUnsupportedDateRangeValueKeys(valueObject);
|
|
913
|
+
if (unsupportedKeys.length) {
|
|
914
|
+
return buildRunJsUnsupportedDateRangeValueError(operator, index, valueObject, unsupportedKeys, input);
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
const resolvedValue = resolveRunJsStaticFilterValue(
|
|
918
|
+
valueNode,
|
|
919
|
+
input.source,
|
|
920
|
+
input.identifierBindings,
|
|
921
|
+
input.staticFilterValueBindings
|
|
922
|
+
);
|
|
923
|
+
if (resolvedValue.status !== "resolved") {
|
|
924
|
+
return null;
|
|
925
|
+
}
|
|
926
|
+
try {
|
|
927
|
+
(0, import_filter_group.normalizeFlowSurfaceStrictFilterDateValue)(operator, resolvedValue.value, `${input.fieldPath}.${operator}`);
|
|
928
|
+
return null;
|
|
929
|
+
} catch (error) {
|
|
930
|
+
return buildRunJsStrictDateFilterValueError(operator, index, resolvedValue.value, input, error);
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
function buildRunJsUnsupportedDateRangeValueError(operator, index, valueObject, unsupportedKeys, input) {
|
|
934
|
+
const suggestedValue = buildSuggestedRunJsDateRangeValue(valueObject, input.source);
|
|
935
|
+
const relativeExample = suggestedValue || { type: "past", number: 7, unit: "day" };
|
|
936
|
+
const examples = {
|
|
937
|
+
relativePeriod: {
|
|
938
|
+
[input.fieldPath]: {
|
|
939
|
+
[operator]: relativeExample
|
|
940
|
+
}
|
|
941
|
+
},
|
|
942
|
+
explicitRange: {
|
|
943
|
+
[input.fieldPath]: {
|
|
944
|
+
$dateBetween: ["YYYY-MM-DD", "YYYY-MM-DD"]
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
};
|
|
948
|
+
const suggestedText = suggestedValue ? `use ${operator}: ${JSON.stringify(suggestedValue)} for this relative period` : `use a frontend relative period object such as ${JSON.stringify(relativeExample)}`;
|
|
949
|
+
const fieldType = String((0, import_service_helpers.getFieldType)(input.field) || "").trim();
|
|
950
|
+
const fieldInterface = String((0, import_service_helpers.getFieldInterface)(input.field) || "").trim();
|
|
951
|
+
return {
|
|
952
|
+
capability: input.capability,
|
|
953
|
+
collectionName: input.collectionName,
|
|
954
|
+
dataSourceKey: input.dataSourceKey,
|
|
955
|
+
examples,
|
|
956
|
+
fieldPath: input.fieldPath,
|
|
957
|
+
index,
|
|
958
|
+
message: `flowSurfaces authoring ${input.capability}(...) uses invalid date filter value for field '${input.fieldPath}' with operator '${operator}': ${unsupportedKeys.join(
|
|
959
|
+
", "
|
|
960
|
+
)} are not supported FlowResource date filter keys. ${suggestedText}, or use $dateBetween with ["YYYY-MM-DD", "YYYY-MM-DD"].`,
|
|
961
|
+
operator,
|
|
962
|
+
resourceType: input.resourceType,
|
|
963
|
+
ruleId: "runjs-resource-filter-date-range-object-invalid",
|
|
964
|
+
suggestedOperator: operator === "$dateBetween" ? "$dateBetween" : operator,
|
|
965
|
+
suggestedValue: relativeExample,
|
|
966
|
+
unsupportedKeys,
|
|
967
|
+
fieldType,
|
|
968
|
+
fieldInterface
|
|
969
|
+
};
|
|
970
|
+
}
|
|
971
|
+
function buildRunJsStrictDateFilterValueError(operator, index, invalidValue, input, error) {
|
|
972
|
+
var _a;
|
|
973
|
+
const details = error instanceof import_errors.FlowSurfaceBadRequestError && _.isPlainObject((_a = error.options) == null ? void 0 : _a.details) ? error.options.details : {};
|
|
974
|
+
const invalidReason = typeof details.invalidReason === "string" && details.invalidReason ? details.invalidReason : "date filter value is invalid";
|
|
975
|
+
const fieldType = String((0, import_service_helpers.getFieldType)(input.field) || "").trim();
|
|
976
|
+
const fieldInterface = String((0, import_service_helpers.getFieldInterface)(input.field) || "").trim();
|
|
977
|
+
return {
|
|
978
|
+
capability: input.capability,
|
|
979
|
+
collectionName: input.collectionName,
|
|
980
|
+
dataSourceKey: input.dataSourceKey,
|
|
981
|
+
fieldPath: input.fieldPath,
|
|
982
|
+
index,
|
|
983
|
+
invalidReason,
|
|
984
|
+
invalidValue: Object.prototype.hasOwnProperty.call(details, "invalidValue") ? details.invalidValue : invalidValue,
|
|
985
|
+
message: `flowSurfaces authoring ${input.capability}(...) uses invalid date filter value for field '${input.fieldPath}' with operator '${operator}': ${invalidReason}`,
|
|
986
|
+
operator,
|
|
987
|
+
repairExample: _.isPlainObject(details.repairExample) ? details.repairExample : void 0,
|
|
988
|
+
repairHint: typeof details.repairHint === "string" ? details.repairHint : void 0,
|
|
989
|
+
resourceType: input.resourceType,
|
|
990
|
+
ruleId: "runjs-resource-filter-date-value-invalid",
|
|
991
|
+
suggestedOperator: operator,
|
|
992
|
+
fieldType,
|
|
993
|
+
fieldInterface
|
|
994
|
+
};
|
|
995
|
+
}
|
|
996
|
+
function resolveRunJsStaticFilterRootNode(node, identifierBindings, staticFilterValueBindings) {
|
|
997
|
+
const objectNode = resolveRunJsStaticFilterObjectNode(node, identifierBindings, staticFilterValueBindings);
|
|
998
|
+
if (objectNode) {
|
|
999
|
+
return {
|
|
1000
|
+
kind: "object",
|
|
1001
|
+
node: objectNode
|
|
1002
|
+
};
|
|
1003
|
+
}
|
|
1004
|
+
const arrayNode = resolveRunJsStaticFilterArrayNode(node, identifierBindings, staticFilterValueBindings);
|
|
1005
|
+
if (arrayNode) {
|
|
1006
|
+
return {
|
|
1007
|
+
kind: "array",
|
|
1008
|
+
node: arrayNode
|
|
1009
|
+
};
|
|
1010
|
+
}
|
|
1011
|
+
return void 0;
|
|
1012
|
+
}
|
|
1013
|
+
function resolveRunJsStaticFilterObjectNode(node, identifierBindings, staticFilterValueBindings, seen = /* @__PURE__ */ new Set()) {
|
|
1014
|
+
const unwrapped = (0, import_bindings.unwrapAstChainExpression)(node);
|
|
1015
|
+
if (!unwrapped) {
|
|
1016
|
+
return void 0;
|
|
1017
|
+
}
|
|
1018
|
+
if (unwrapped.type === "ObjectExpression") {
|
|
1019
|
+
return unwrapped;
|
|
1020
|
+
}
|
|
1021
|
+
if (unwrapped.type !== "Identifier") {
|
|
1022
|
+
return void 0;
|
|
1023
|
+
}
|
|
1024
|
+
const binding = (0, import_static_values.resolveAstAliasBinding)(
|
|
1025
|
+
unwrapped.name,
|
|
1026
|
+
unwrapped.start || 0,
|
|
1027
|
+
staticFilterValueBindings,
|
|
1028
|
+
identifierBindings
|
|
1029
|
+
);
|
|
1030
|
+
if (!binding || seen.has(binding)) {
|
|
1031
|
+
return void 0;
|
|
1032
|
+
}
|
|
1033
|
+
const nextSeen = new Set(seen);
|
|
1034
|
+
nextSeen.add(binding);
|
|
1035
|
+
return resolveRunJsStaticFilterObjectNode(binding.valueNode, identifierBindings, staticFilterValueBindings, nextSeen);
|
|
1036
|
+
}
|
|
1037
|
+
function resolveRunJsStaticFilterArrayNode(node, identifierBindings, staticFilterValueBindings, seen = /* @__PURE__ */ new Set()) {
|
|
1038
|
+
const unwrapped = (0, import_bindings.unwrapAstChainExpression)(node);
|
|
1039
|
+
if (!unwrapped) {
|
|
1040
|
+
return void 0;
|
|
1041
|
+
}
|
|
1042
|
+
if (unwrapped.type === "ArrayExpression") {
|
|
1043
|
+
return unwrapped;
|
|
1044
|
+
}
|
|
1045
|
+
if (unwrapped.type !== "Identifier") {
|
|
1046
|
+
return void 0;
|
|
1047
|
+
}
|
|
1048
|
+
const binding = (0, import_static_values.resolveAstAliasBinding)(
|
|
1049
|
+
unwrapped.name,
|
|
1050
|
+
unwrapped.start || 0,
|
|
1051
|
+
staticFilterValueBindings,
|
|
1052
|
+
identifierBindings
|
|
1053
|
+
);
|
|
1054
|
+
if (!binding || seen.has(binding)) {
|
|
1055
|
+
return void 0;
|
|
1056
|
+
}
|
|
1057
|
+
const nextSeen = new Set(seen);
|
|
1058
|
+
nextSeen.add(binding);
|
|
1059
|
+
return resolveRunJsStaticFilterArrayNode(binding.valueNode, identifierBindings, staticFilterValueBindings, nextSeen);
|
|
1060
|
+
}
|
|
1061
|
+
function resolveRunJsStaticFilterValue(node, source, identifierBindings, staticFilterValueBindings, seen = /* @__PURE__ */ new Set()) {
|
|
1062
|
+
var _a, _b, _c, _d;
|
|
1063
|
+
const unwrapped = (0, import_bindings.unwrapAstChainExpression)(node);
|
|
1064
|
+
if (!unwrapped) {
|
|
1065
|
+
return { status: "unresolved" };
|
|
1066
|
+
}
|
|
1067
|
+
if (unwrapped.type === "Identifier") {
|
|
1068
|
+
const index = unwrapped.start || 0;
|
|
1069
|
+
if (unwrapped.name === "undefined" && !(0, import_static_values.hasAstActiveBinding)("undefined", index, identifierBindings)) {
|
|
1070
|
+
return { status: "resolved", value: void 0 };
|
|
1071
|
+
}
|
|
1072
|
+
const binding = (0, import_static_values.resolveAstAliasBinding)(unwrapped.name, index, staticFilterValueBindings, identifierBindings);
|
|
1073
|
+
if (!binding || seen.has(binding)) {
|
|
1074
|
+
return { status: "unresolved" };
|
|
1075
|
+
}
|
|
1076
|
+
const nextSeen = new Set(seen);
|
|
1077
|
+
nextSeen.add(binding);
|
|
1078
|
+
return resolveRunJsStaticFilterValue(
|
|
1079
|
+
binding.valueNode,
|
|
1080
|
+
source,
|
|
1081
|
+
identifierBindings,
|
|
1082
|
+
staticFilterValueBindings,
|
|
1083
|
+
nextSeen
|
|
1084
|
+
);
|
|
1085
|
+
}
|
|
1086
|
+
if (unwrapped.type === "Literal") {
|
|
1087
|
+
const value = unwrapped.value;
|
|
1088
|
+
if (value === null || ["string", "number", "boolean"].includes(typeof value)) {
|
|
1089
|
+
return { status: "resolved", value };
|
|
1090
|
+
}
|
|
1091
|
+
return { status: "unresolved" };
|
|
1092
|
+
}
|
|
1093
|
+
if (unwrapped.type === "TemplateLiteral" && !((_a = unwrapped.expressions) == null ? void 0 : _a.length)) {
|
|
1094
|
+
return {
|
|
1095
|
+
status: "resolved",
|
|
1096
|
+
value: ((_d = (_c = (_b = unwrapped.quasis) == null ? void 0 : _b[0]) == null ? void 0 : _c.value) == null ? void 0 : _d.cooked) ?? source.slice(unwrapped.start + 1, unwrapped.end - 1)
|
|
1097
|
+
};
|
|
1098
|
+
}
|
|
1099
|
+
if (unwrapped.type === "UnaryExpression") {
|
|
1100
|
+
const argument = resolveRunJsStaticFilterValue(
|
|
1101
|
+
unwrapped.argument,
|
|
1102
|
+
source,
|
|
1103
|
+
identifierBindings,
|
|
1104
|
+
staticFilterValueBindings,
|
|
1105
|
+
seen
|
|
1106
|
+
);
|
|
1107
|
+
if (argument.status !== "resolved") {
|
|
1108
|
+
return argument;
|
|
1109
|
+
}
|
|
1110
|
+
if (unwrapped.operator === "-") {
|
|
1111
|
+
return typeof argument.value === "number" ? { status: "resolved", value: -argument.value } : { status: "unresolved" };
|
|
1112
|
+
}
|
|
1113
|
+
if (unwrapped.operator === "+") {
|
|
1114
|
+
return typeof argument.value === "number" ? { status: "resolved", value: argument.value } : { status: "unresolved" };
|
|
1115
|
+
}
|
|
1116
|
+
if (unwrapped.operator === "!") {
|
|
1117
|
+
return { status: "resolved", value: !argument.value };
|
|
1118
|
+
}
|
|
1119
|
+
if (unwrapped.operator === "void") {
|
|
1120
|
+
return { status: "resolved", value: void 0 };
|
|
1121
|
+
}
|
|
1122
|
+
return { status: "unresolved" };
|
|
1123
|
+
}
|
|
1124
|
+
if (unwrapped.type === "ArrayExpression") {
|
|
1125
|
+
const values = [];
|
|
1126
|
+
for (const element of unwrapped.elements || []) {
|
|
1127
|
+
if (!element) {
|
|
1128
|
+
values.push(void 0);
|
|
1129
|
+
continue;
|
|
1130
|
+
}
|
|
1131
|
+
if (element.type === "SpreadElement") {
|
|
1132
|
+
return { status: "unresolved" };
|
|
1133
|
+
}
|
|
1134
|
+
const item = resolveRunJsStaticFilterValue(element, source, identifierBindings, staticFilterValueBindings, seen);
|
|
1135
|
+
if (item.status !== "resolved") {
|
|
1136
|
+
return item;
|
|
1137
|
+
}
|
|
1138
|
+
values.push(item.value);
|
|
1139
|
+
}
|
|
1140
|
+
return { status: "resolved", value: values };
|
|
1141
|
+
}
|
|
1142
|
+
if (unwrapped.type === "ObjectExpression") {
|
|
1143
|
+
const value = {};
|
|
1144
|
+
for (const property of unwrapped.properties || []) {
|
|
1145
|
+
if (!property || property.type === "SpreadElement") {
|
|
1146
|
+
return { status: "unresolved" };
|
|
1147
|
+
}
|
|
1148
|
+
const key = (0, import_static_values.getAstStaticPropertyName)(property);
|
|
1149
|
+
if (!key) {
|
|
1150
|
+
return { status: "unresolved" };
|
|
1151
|
+
}
|
|
1152
|
+
const propertyValue = resolveRunJsStaticFilterValue(
|
|
1153
|
+
property.value,
|
|
1154
|
+
source,
|
|
1155
|
+
identifierBindings,
|
|
1156
|
+
staticFilterValueBindings,
|
|
1157
|
+
seen
|
|
1158
|
+
);
|
|
1159
|
+
if (propertyValue.status !== "resolved") {
|
|
1160
|
+
return propertyValue;
|
|
1161
|
+
}
|
|
1162
|
+
value[key] = propertyValue.value;
|
|
1163
|
+
}
|
|
1164
|
+
return { status: "resolved", value };
|
|
1165
|
+
}
|
|
1166
|
+
return { status: "unresolved" };
|
|
1167
|
+
}
|
|
1168
|
+
function isRunJsFilterGroupObjectNode(objectExpression, identifierBindings, staticFilterValueBindings) {
|
|
1169
|
+
let hasLogic = false;
|
|
1170
|
+
for (const property of (objectExpression == null ? void 0 : objectExpression.properties) || []) {
|
|
1171
|
+
if (!property || property.type === "SpreadElement") {
|
|
1172
|
+
return false;
|
|
1173
|
+
}
|
|
1174
|
+
const key = (0, import_static_values.getAstStaticPropertyName)(property);
|
|
1175
|
+
if (!key) {
|
|
1176
|
+
return false;
|
|
1177
|
+
}
|
|
1178
|
+
if (key === "logic") {
|
|
1179
|
+
hasLogic = true;
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
return hasLogic && !!resolveRunJsFilterGroupItemsArrayNode(objectExpression, identifierBindings, staticFilterValueBindings);
|
|
1183
|
+
}
|
|
1184
|
+
function buildRunJsResourceFilterShapeError(input) {
|
|
1185
|
+
const invalidValue = resolveRunJsStaticFilterValue(
|
|
1186
|
+
input.filterNode.node,
|
|
1187
|
+
input.source,
|
|
1188
|
+
input.identifierBindings,
|
|
1189
|
+
input.staticFilterValueBindings
|
|
1190
|
+
);
|
|
1191
|
+
const resolvedInvalidValue = invalidValue.status === "resolved" ? invalidValue.value : void 0;
|
|
1192
|
+
const shapeData = getRunJsResourceFilterShapeData(input, resolvedInvalidValue);
|
|
1193
|
+
return {
|
|
1194
|
+
capability: input.capability,
|
|
1195
|
+
collectionName: input.collectionName,
|
|
1196
|
+
dataSourceKey: input.dataSourceKey,
|
|
1197
|
+
index: input.index,
|
|
1198
|
+
invalidShape: input.invalidShape,
|
|
1199
|
+
invalidValue: resolvedInvalidValue,
|
|
1200
|
+
message: `flowSurfaces authoring ${input.capability}(...) received ${input.invalidShape === "filter-group" ? "a FlowSurface FilterGroup" : "an array"}, but FlowResource filters must be backend query filter objects such as { stage: { $eq: '\u65B0\u7EBF\u7D22' } }`,
|
|
1201
|
+
repairExample: buildRunJsResourceFilterShapeRepairExample(shapeData),
|
|
1202
|
+
repairHint: 'FlowResource setFilter/addFilterGroup does not accept FlowSurface FilterGroup items. Convert { field/path, operator, value } items to backend query filter object syntax and prefix operators with "$".',
|
|
1203
|
+
resourceType: input.resourceType,
|
|
1204
|
+
ruleId: "runjs-resource-filter-shape-invalid",
|
|
1205
|
+
suggestedOperator: getSuggestedRunJsResourceFilterShapeOperator(shapeData)
|
|
1206
|
+
};
|
|
1207
|
+
}
|
|
1208
|
+
function buildRunJsResourceFilterShapeRepairExample(source) {
|
|
1209
|
+
const items = source.items.map((item) => buildRunJsResourceFilterConditionFromItem(item)).filter(Boolean);
|
|
1210
|
+
if (items.length === 1) {
|
|
1211
|
+
return items[0];
|
|
1212
|
+
}
|
|
1213
|
+
if (items.length > 1) {
|
|
1214
|
+
return {
|
|
1215
|
+
[source.logic === "$or" ? "$or" : "$and"]: items
|
|
1216
|
+
};
|
|
1217
|
+
}
|
|
1218
|
+
return {
|
|
1219
|
+
stage: {
|
|
1220
|
+
$eq: "\u65B0\u7EBF\u7D22"
|
|
1221
|
+
}
|
|
1222
|
+
};
|
|
1223
|
+
}
|
|
1224
|
+
function getRunJsResourceFilterShapeData(input, resolvedValue) {
|
|
1225
|
+
const astShapeData = getRunJsResourceFilterAstShapeData(input);
|
|
1226
|
+
if (astShapeData.items.length) {
|
|
1227
|
+
return astShapeData;
|
|
1228
|
+
}
|
|
1229
|
+
return getRunJsResourceFilterResolvedShapeData(resolvedValue);
|
|
1230
|
+
}
|
|
1231
|
+
function getRunJsResourceFilterAstShapeData(input) {
|
|
1232
|
+
if (input.filterNode.kind === "array") {
|
|
1233
|
+
return {
|
|
1234
|
+
items: getRunJsResourceFilterShapeItemsFromArrayNode(input.filterNode.node, input)
|
|
1235
|
+
};
|
|
1236
|
+
}
|
|
1237
|
+
const itemsNode = resolveRunJsFilterGroupItemsArrayNode(
|
|
1238
|
+
input.filterNode.node,
|
|
1239
|
+
input.identifierBindings,
|
|
1240
|
+
input.staticFilterValueBindings
|
|
1241
|
+
);
|
|
1242
|
+
if (itemsNode) {
|
|
1243
|
+
return {
|
|
1244
|
+
items: getRunJsResourceFilterShapeItemsFromArrayNode(itemsNode, input),
|
|
1245
|
+
logic: resolveRunJsFilterGroupLogic(input.filterNode.node, input)
|
|
1246
|
+
};
|
|
1247
|
+
}
|
|
1248
|
+
return {
|
|
1249
|
+
items: []
|
|
1250
|
+
};
|
|
1251
|
+
}
|
|
1252
|
+
function getRunJsResourceFilterResolvedShapeData(value) {
|
|
1253
|
+
if (Array.isArray(value)) {
|
|
1254
|
+
return {
|
|
1255
|
+
items: value.map((item) => buildRunJsResourceFilterShapeItemFromValue(item)).filter(Boolean)
|
|
1256
|
+
};
|
|
1257
|
+
}
|
|
1258
|
+
if (_.isPlainObject(value)) {
|
|
1259
|
+
const valueObject = value;
|
|
1260
|
+
if (Array.isArray(valueObject.items)) {
|
|
1261
|
+
return {
|
|
1262
|
+
items: valueObject.items.map((item) => buildRunJsResourceFilterShapeItemFromValue(item)).filter(Boolean),
|
|
1263
|
+
logic: typeof valueObject.logic === "string" ? valueObject.logic : void 0
|
|
1264
|
+
};
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
return {
|
|
1268
|
+
items: []
|
|
1269
|
+
};
|
|
1270
|
+
}
|
|
1271
|
+
function getRunJsResourceFilterShapeItemsFromArrayNode(arrayNode, input) {
|
|
1272
|
+
return ((arrayNode == null ? void 0 : arrayNode.elements) || []).map((element) => buildRunJsResourceFilterShapeItemFromNode(element, input)).filter(Boolean);
|
|
1273
|
+
}
|
|
1274
|
+
function buildRunJsResourceFilterShapeItemFromNode(node, input) {
|
|
1275
|
+
const objectNode = resolveRunJsStaticFilterObjectNode(
|
|
1276
|
+
node,
|
|
1277
|
+
input.identifierBindings,
|
|
1278
|
+
input.staticFilterValueBindings
|
|
1279
|
+
);
|
|
1280
|
+
if (!objectNode) {
|
|
1281
|
+
return null;
|
|
1282
|
+
}
|
|
1283
|
+
const fieldPath = resolveRunJsFilterShapeItemStringProperty(objectNode, "path", input) || resolveRunJsFilterShapeItemStringProperty(objectNode, "field", input);
|
|
1284
|
+
if (!fieldPath) {
|
|
1285
|
+
return null;
|
|
1286
|
+
}
|
|
1287
|
+
const operator = resolveRunJsFilterShapeItemStringProperty(objectNode, "operator", input);
|
|
1288
|
+
const value = resolveRunJsFilterShapeItemValue(objectNode, input);
|
|
1289
|
+
return {
|
|
1290
|
+
fieldPath,
|
|
1291
|
+
operator,
|
|
1292
|
+
...value
|
|
1293
|
+
};
|
|
1294
|
+
}
|
|
1295
|
+
function buildRunJsResourceFilterShapeItemFromValue(value) {
|
|
1296
|
+
if (!_.isPlainObject(value)) {
|
|
1297
|
+
return null;
|
|
1298
|
+
}
|
|
1299
|
+
const input = value;
|
|
1300
|
+
const fieldPath = String(input.path || input.field || "").trim();
|
|
1301
|
+
if (!fieldPath) {
|
|
1302
|
+
return null;
|
|
1303
|
+
}
|
|
1304
|
+
return {
|
|
1305
|
+
fieldPath,
|
|
1306
|
+
hasValue: Object.prototype.hasOwnProperty.call(input, "value"),
|
|
1307
|
+
operator: typeof input.operator === "string" ? input.operator : void 0,
|
|
1308
|
+
value: input.value
|
|
1309
|
+
};
|
|
1310
|
+
}
|
|
1311
|
+
function buildRunJsResourceFilterConditionFromItem(item) {
|
|
1312
|
+
if (!item.fieldPath) {
|
|
1313
|
+
return null;
|
|
1314
|
+
}
|
|
1315
|
+
const operator = normalizeRunJsResourceFilterShapeOperator(item.operator);
|
|
1316
|
+
return {
|
|
1317
|
+
[item.fieldPath]: {
|
|
1318
|
+
[operator]: item.hasValue ? item.value : "<value>"
|
|
1319
|
+
}
|
|
1320
|
+
};
|
|
1321
|
+
}
|
|
1322
|
+
function resolveRunJsFilterShapeItemStringProperty(objectExpression, key, input) {
|
|
1323
|
+
const property = getRunJsFilterShapeObjectProperty(objectExpression, key);
|
|
1324
|
+
if (!property) {
|
|
1325
|
+
return "";
|
|
1326
|
+
}
|
|
1327
|
+
const resolved = resolveRunJsStaticFilterValue(
|
|
1328
|
+
property.value,
|
|
1329
|
+
input.source,
|
|
1330
|
+
input.identifierBindings,
|
|
1331
|
+
input.staticFilterValueBindings
|
|
1332
|
+
);
|
|
1333
|
+
return resolved.status === "resolved" && typeof resolved.value === "string" ? resolved.value.trim() : "";
|
|
1334
|
+
}
|
|
1335
|
+
function resolveRunJsFilterShapeItemValue(objectExpression, input) {
|
|
1336
|
+
const property = getRunJsFilterShapeObjectProperty(objectExpression, "value");
|
|
1337
|
+
if (!property) {
|
|
1338
|
+
return {
|
|
1339
|
+
hasValue: false
|
|
1340
|
+
};
|
|
1341
|
+
}
|
|
1342
|
+
const resolved = resolveRunJsStaticFilterValue(
|
|
1343
|
+
property.value,
|
|
1344
|
+
input.source,
|
|
1345
|
+
input.identifierBindings,
|
|
1346
|
+
input.staticFilterValueBindings
|
|
1347
|
+
);
|
|
1348
|
+
return {
|
|
1349
|
+
hasValue: true,
|
|
1350
|
+
value: resolved.status === "resolved" ? resolved.value : "<value>"
|
|
1351
|
+
};
|
|
1352
|
+
}
|
|
1353
|
+
function resolveRunJsFilterGroupItemsArrayNode(objectExpression, identifierBindings, staticFilterValueBindings) {
|
|
1354
|
+
const property = getRunJsFilterShapeObjectProperty(objectExpression, "items");
|
|
1355
|
+
return property ? resolveRunJsStaticFilterArrayNode(property.value, identifierBindings, staticFilterValueBindings) : void 0;
|
|
1356
|
+
}
|
|
1357
|
+
function resolveRunJsFilterGroupLogic(objectExpression, input) {
|
|
1358
|
+
const property = getRunJsFilterShapeObjectProperty(objectExpression, "logic");
|
|
1359
|
+
if (!property) {
|
|
1360
|
+
return void 0;
|
|
1361
|
+
}
|
|
1362
|
+
const resolved = resolveRunJsStaticFilterValue(
|
|
1363
|
+
property.value,
|
|
1364
|
+
input.source,
|
|
1365
|
+
input.identifierBindings,
|
|
1366
|
+
input.staticFilterValueBindings
|
|
1367
|
+
);
|
|
1368
|
+
return resolved.status === "resolved" && typeof resolved.value === "string" ? resolved.value : void 0;
|
|
1369
|
+
}
|
|
1370
|
+
function getRunJsFilterShapeObjectProperty(objectExpression, name) {
|
|
1371
|
+
return ((objectExpression == null ? void 0 : objectExpression.properties) || []).find((property) => {
|
|
1372
|
+
if (!property || property.type === "SpreadElement") {
|
|
1373
|
+
return false;
|
|
1374
|
+
}
|
|
1375
|
+
return (0, import_static_values.getAstStaticPropertyName)(property) === name;
|
|
1376
|
+
});
|
|
1377
|
+
}
|
|
1378
|
+
function normalizeRunJsResourceFilterShapeOperator(operator) {
|
|
1379
|
+
const normalized = String(operator || "").trim();
|
|
1380
|
+
if (!normalized) {
|
|
1381
|
+
return "$eq";
|
|
1382
|
+
}
|
|
1383
|
+
return getSuggestedRunJsFilterOperator(normalized) || normalized;
|
|
1384
|
+
}
|
|
1385
|
+
function getSuggestedRunJsResourceFilterShapeOperator(input) {
|
|
1386
|
+
var _a;
|
|
1387
|
+
const operator = (_a = input.items.find((item) => typeof item.operator === "string")) == null ? void 0 : _a.operator;
|
|
1388
|
+
if (!operator) {
|
|
1389
|
+
return void 0;
|
|
1390
|
+
}
|
|
1391
|
+
return getSuggestedRunJsFilterOperator(operator) || void 0;
|
|
1392
|
+
}
|
|
1393
|
+
function isRunJsDateFilterOperator(operator) {
|
|
1394
|
+
return import_constants.RUNJS_DATE_FILTER_OPERATORS.has(String(operator || "").trim());
|
|
1395
|
+
}
|
|
1396
|
+
function collectRunJsUnsupportedDateRangeValueKeys(objectExpression) {
|
|
1397
|
+
const keys = [];
|
|
1398
|
+
for (const property of objectExpression.properties || []) {
|
|
1399
|
+
if (!property || property.type === "SpreadElement") {
|
|
1400
|
+
continue;
|
|
1401
|
+
}
|
|
1402
|
+
const key = (0, import_static_values.getAstStaticPropertyName)(property);
|
|
1403
|
+
if (import_constants.RUNJS_UNSUPPORTED_DATE_RANGE_VALUE_KEYS.has(key)) {
|
|
1404
|
+
keys.push(key);
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1407
|
+
return keys;
|
|
1408
|
+
}
|
|
1409
|
+
function buildSuggestedRunJsDateRangeValue(objectExpression, source) {
|
|
1410
|
+
const values = {};
|
|
1411
|
+
for (const property of objectExpression.properties || []) {
|
|
1412
|
+
if (!property || property.type === "SpreadElement") {
|
|
1413
|
+
continue;
|
|
1414
|
+
}
|
|
1415
|
+
const key = (0, import_static_values.getAstStaticPropertyName)(property);
|
|
1416
|
+
if (!import_constants.RUNJS_UNSUPPORTED_DATE_RANGE_VALUE_KEYS.has(key)) {
|
|
1417
|
+
continue;
|
|
1418
|
+
}
|
|
1419
|
+
const value = (0, import_static_values.resolveAstStaticStringValue)(property.value, source);
|
|
1420
|
+
if (typeof value === "string") {
|
|
1421
|
+
values[key] = value.trim();
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
const from = values.$dateFrom;
|
|
1425
|
+
const to = values.$dateTo;
|
|
1426
|
+
const fromOffset = parseRunJsRelativeDateOffset(from);
|
|
1427
|
+
const toOffset = parseRunJsRelativeDateOffset(to);
|
|
1428
|
+
if (to === "now" && (fromOffset == null ? void 0 : fromOffset.direction) === "past") {
|
|
1429
|
+
return {
|
|
1430
|
+
type: "past",
|
|
1431
|
+
number: fromOffset.number,
|
|
1432
|
+
unit: fromOffset.unit
|
|
1433
|
+
};
|
|
1434
|
+
}
|
|
1435
|
+
if (from === "now" && (toOffset == null ? void 0 : toOffset.direction) === "next") {
|
|
1436
|
+
return {
|
|
1437
|
+
type: "next",
|
|
1438
|
+
number: toOffset.number,
|
|
1439
|
+
unit: toOffset.unit
|
|
1440
|
+
};
|
|
1441
|
+
}
|
|
1442
|
+
return void 0;
|
|
1443
|
+
}
|
|
1444
|
+
function parseRunJsRelativeDateOffset(value) {
|
|
1445
|
+
const match = String(value || "").trim().match(/^([+-])\s*(\d+)\s*(d|day|days|w|week|weeks|m|mo|month|months|q|quarter|quarters|y|year|years)$/i);
|
|
1446
|
+
if (!match) {
|
|
1447
|
+
return null;
|
|
1448
|
+
}
|
|
1449
|
+
const unit = normalizeRunJsRelativeDateUnit(match[3]);
|
|
1450
|
+
if (!unit) {
|
|
1451
|
+
return null;
|
|
1452
|
+
}
|
|
1453
|
+
return {
|
|
1454
|
+
direction: match[1] === "-" ? "past" : "next",
|
|
1455
|
+
number: Number(match[2]),
|
|
1456
|
+
unit
|
|
1457
|
+
};
|
|
1458
|
+
}
|
|
1459
|
+
function normalizeRunJsRelativeDateUnit(value) {
|
|
1460
|
+
const normalized = String(value || "").toLowerCase();
|
|
1461
|
+
if (normalized === "d" || normalized === "day" || normalized === "days") {
|
|
1462
|
+
return "day";
|
|
1463
|
+
}
|
|
1464
|
+
if (normalized === "w" || normalized === "week" || normalized === "weeks") {
|
|
1465
|
+
return "week";
|
|
1466
|
+
}
|
|
1467
|
+
if (normalized === "m" || normalized === "mo" || normalized === "month" || normalized === "months") {
|
|
1468
|
+
return "month";
|
|
1469
|
+
}
|
|
1470
|
+
if (normalized === "q" || normalized === "quarter" || normalized === "quarters") {
|
|
1471
|
+
return "quarter";
|
|
1472
|
+
}
|
|
1473
|
+
if (normalized === "y" || normalized === "year" || normalized === "years") {
|
|
1474
|
+
return "year";
|
|
1475
|
+
}
|
|
1476
|
+
return "";
|
|
1477
|
+
}
|
|
1478
|
+
function buildRunJsResourceFilterFieldError(input) {
|
|
1479
|
+
const collectionName = (0, import_service_helpers.getCollectionName)(input.collection) || input.collectionName;
|
|
1480
|
+
return {
|
|
1481
|
+
availableFields: (0, import_service_helpers.getCollectionFields)(input.collection).map((field) => String((0, import_service_helpers.getFieldName)(field) || "").trim()).filter(Boolean),
|
|
1482
|
+
capability: input.capability,
|
|
1483
|
+
collectionName,
|
|
1484
|
+
dataSourceKey: input.dataSourceKey,
|
|
1485
|
+
fieldPath: input.fieldPath,
|
|
1486
|
+
index: input.index,
|
|
1487
|
+
message: `flowSurfaces authoring ${input.capability}(...) references unknown filter field '${input.fieldPath}' on collection '${collectionName}'`,
|
|
1488
|
+
resourceType: input.resourceType,
|
|
1489
|
+
ruleId: "runjs-resource-filter-field-unknown"
|
|
1490
|
+
};
|
|
1491
|
+
}
|
|
1492
|
+
function resolveRunJsResourceFilterFieldPath(collection, dataSourceKey, fieldPath, context) {
|
|
1493
|
+
if (typeof (collection == null ? void 0 : collection.getFieldByPath) === "function") {
|
|
1494
|
+
const direct2 = collection.getFieldByPath(fieldPath);
|
|
1495
|
+
if (direct2) {
|
|
1496
|
+
return { collection, field: direct2 };
|
|
1497
|
+
}
|
|
1498
|
+
}
|
|
1499
|
+
const direct = (0, import_service_helpers.resolveFieldFromCollection)(collection, fieldPath);
|
|
1500
|
+
if (direct) {
|
|
1501
|
+
return { collection, field: direct };
|
|
1502
|
+
}
|
|
1503
|
+
let currentCollection = collection;
|
|
1504
|
+
let currentDataSourceKey = dataSourceKey || (collection == null ? void 0 : collection.dataSourceKey) || "main";
|
|
1505
|
+
const parts = String(fieldPath || "").split(".").filter(Boolean);
|
|
1506
|
+
for (let index = 0; index < parts.length; index += 1) {
|
|
1507
|
+
const part = parts[index];
|
|
1508
|
+
const field = getRunJsCollectionField(currentCollection, part);
|
|
1509
|
+
if (!field) {
|
|
1510
|
+
return { collection: currentCollection, field: null };
|
|
1511
|
+
}
|
|
1512
|
+
if (index === parts.length - 1) {
|
|
1513
|
+
return { collection: currentCollection, field };
|
|
1514
|
+
}
|
|
1515
|
+
if (!(0, import_service_helpers.isAssociationField)(field)) {
|
|
1516
|
+
return { collection: currentCollection, field: null };
|
|
1517
|
+
}
|
|
1518
|
+
const targetCollection = (0, import_service_helpers.resolveFieldTargetCollection)(
|
|
1519
|
+
field,
|
|
1520
|
+
(currentCollection == null ? void 0 : currentCollection.dataSourceKey) || currentDataSourceKey,
|
|
1521
|
+
(nextDataSourceKey, collectionName) => {
|
|
1522
|
+
var _a;
|
|
1523
|
+
return (_a = context.getCollection) == null ? void 0 : _a.call(context, nextDataSourceKey, collectionName);
|
|
1524
|
+
}
|
|
1525
|
+
);
|
|
1526
|
+
if (!targetCollection) {
|
|
1527
|
+
return { collection: currentCollection, field: null };
|
|
1528
|
+
}
|
|
1529
|
+
currentCollection = targetCollection;
|
|
1530
|
+
currentDataSourceKey = (targetCollection == null ? void 0 : targetCollection.dataSourceKey) || currentDataSourceKey;
|
|
1531
|
+
}
|
|
1532
|
+
return { collection: currentCollection, field: null };
|
|
1533
|
+
}
|
|
1534
|
+
function getRunJsCollectionField(collection, fieldName) {
|
|
1535
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
1536
|
+
const normalized = String(fieldName || "").trim();
|
|
1537
|
+
if (!normalized) {
|
|
1538
|
+
return null;
|
|
1539
|
+
}
|
|
1540
|
+
const field = ((_a = collection == null ? void 0 : collection.getField) == null ? void 0 : _a.call(collection, normalized)) || ((_c = (_b = collection == null ? void 0 : collection.fields) == null ? void 0 : _b.get) == null ? void 0 : _c.call(_b, normalized));
|
|
1541
|
+
if (field) {
|
|
1542
|
+
return field;
|
|
1543
|
+
}
|
|
1544
|
+
const modelAttributes = (typeof ((_d = collection == null ? void 0 : collection.model) == null ? void 0 : _d.getAttributes) === "function" ? collection.model.getAttributes() : null) || ((_e = collection == null ? void 0 : collection.model) == null ? void 0 : _e.rawAttributes) || ((_f = collection == null ? void 0 : collection.model) == null ? void 0 : _f.attributes) || {};
|
|
1545
|
+
const modelAttribute = modelAttributes == null ? void 0 : modelAttributes[normalized];
|
|
1546
|
+
if (modelAttribute) {
|
|
1547
|
+
return {
|
|
1548
|
+
name: normalized,
|
|
1549
|
+
type: ((_g = modelAttribute.type) == null ? void 0 : _g.key) || modelAttribute.type,
|
|
1550
|
+
interface: modelAttribute.interface
|
|
1551
|
+
};
|
|
1552
|
+
}
|
|
1553
|
+
if (normalized === "id") {
|
|
1554
|
+
return {
|
|
1555
|
+
name: "id",
|
|
1556
|
+
type: "bigInt",
|
|
1557
|
+
interface: "id"
|
|
1558
|
+
};
|
|
1559
|
+
}
|
|
1560
|
+
return null;
|
|
1561
|
+
}
|
|
1562
|
+
function isRunJsJsonLikeField(field) {
|
|
1563
|
+
const type = String((0, import_service_helpers.getFieldType)(field) || "").trim().toLowerCase();
|
|
1564
|
+
return type === "json" || type === "jsonb" || type === "array";
|
|
1565
|
+
}
|
|
1566
|
+
function isRunJsSupportedFilterOperator(operator) {
|
|
1567
|
+
return import_constants.RUNJS_SUPPORTED_FILTER_OPERATORS.has(String(operator || "").trim());
|
|
1568
|
+
}
|
|
1569
|
+
function getSuggestedRunJsFilterOperator(operator) {
|
|
1570
|
+
const normalized = String(operator || "").trim();
|
|
1571
|
+
if (normalized === "$dataOn" || normalized === "dataOn") {
|
|
1572
|
+
return "$dateOn";
|
|
1573
|
+
}
|
|
1574
|
+
if (!normalized || normalized.startsWith("$")) {
|
|
1575
|
+
return "";
|
|
1576
|
+
}
|
|
1577
|
+
const suggested = `$${normalized}`;
|
|
1578
|
+
return isRunJsSupportedFilterOperator(suggested) ? suggested : "";
|
|
1579
|
+
}
|
|
1580
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1581
|
+
0 && (module.exports = {
|
|
1582
|
+
collectAstInvalidResourceFilterCalls
|
|
1583
|
+
});
|