@nocobase/plugin-flow-engine 2.1.0-beta.43 → 2.1.0-beta.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/dist/externalVersion.js +9 -9
  2. package/dist/node_modules/@ant-design/icons-svg/package.json +1 -1
  3. package/dist/node_modules/acorn/package.json +1 -1
  4. package/dist/node_modules/acorn-jsx/package.json +1 -1
  5. package/dist/node_modules/acorn-walk/package.json +1 -1
  6. package/dist/node_modules/ses/package.json +1 -1
  7. package/dist/node_modules/zod/package.json +1 -1
  8. package/dist/server/flow-surfaces/authoring-validation.js +160 -21
  9. package/dist/server/flow-surfaces/catalog.js +9 -5
  10. package/dist/server/flow-surfaces/chart-config.js +29 -6
  11. package/dist/server/flow-surfaces/contract-guard.js +39 -5
  12. package/dist/server/flow-surfaces/default-block-actions.js +2 -0
  13. package/dist/server/flow-surfaces/errors.d.ts +15 -0
  14. package/dist/server/flow-surfaces/errors.js +49 -3
  15. package/dist/server/flow-surfaces/filter-group.d.ts +7 -1
  16. package/dist/server/flow-surfaces/filter-group.js +175 -71
  17. package/dist/server/flow-surfaces/public-data-surface-default-filter.js +2 -1
  18. package/dist/server/flow-surfaces/runjs-authoring/ast/bindings.d.ts +66 -0
  19. package/dist/server/flow-surfaces/runjs-authoring/ast/bindings.js +661 -0
  20. package/dist/server/flow-surfaces/runjs-authoring/ast/execution.d.ts +20 -0
  21. package/dist/server/flow-surfaces/runjs-authoring/ast/execution.js +275 -0
  22. package/dist/server/flow-surfaces/runjs-authoring/ast/parser.d.ts +16 -0
  23. package/dist/server/flow-surfaces/runjs-authoring/ast/parser.js +130 -0
  24. package/dist/server/flow-surfaces/runjs-authoring/ast/react-values.d.ts +20 -0
  25. package/dist/server/flow-surfaces/runjs-authoring/ast/react-values.js +401 -0
  26. package/dist/server/flow-surfaces/runjs-authoring/ast/request-config.d.ts +21 -0
  27. package/dist/server/flow-surfaces/runjs-authoring/ast/request-config.js +199 -0
  28. package/dist/server/flow-surfaces/runjs-authoring/ast/source.d.ts +70 -0
  29. package/dist/server/flow-surfaces/runjs-authoring/ast/source.js +895 -0
  30. package/dist/server/flow-surfaces/runjs-authoring/ast/static-bindings.d.ts +23 -0
  31. package/dist/server/flow-surfaces/runjs-authoring/ast/static-bindings.js +618 -0
  32. package/dist/server/flow-surfaces/runjs-authoring/ast/static-values.d.ts +196 -0
  33. package/dist/server/flow-surfaces/runjs-authoring/ast/static-values.js +1777 -0
  34. package/dist/server/flow-surfaces/runjs-authoring/ast/walk.d.ts +10 -0
  35. package/dist/server/flow-surfaces/runjs-authoring/ast/walk.js +55 -0
  36. package/dist/server/flow-surfaces/runjs-authoring/collectors.d.ts +12 -0
  37. package/dist/server/flow-surfaces/runjs-authoring/collectors.js +589 -0
  38. package/dist/server/flow-surfaces/runjs-authoring/index.d.ts +2 -25
  39. package/dist/server/flow-surfaces/runjs-authoring/index.js +5 -11138
  40. package/dist/server/flow-surfaces/runjs-authoring/inspect.d.ts +13 -0
  41. package/dist/server/flow-surfaces/runjs-authoring/inspect.js +149 -0
  42. package/dist/server/flow-surfaces/runjs-authoring/internal-types.d.ts +333 -0
  43. package/dist/server/flow-surfaces/runjs-authoring/internal-types.js +36 -0
  44. package/dist/server/flow-surfaces/runjs-authoring/rules.js +2 -0
  45. package/dist/server/flow-surfaces/runjs-authoring/runtime/constants.d.ts +67 -0
  46. package/dist/server/flow-surfaces/runjs-authoring/runtime/constants.js +757 -0
  47. package/dist/server/flow-surfaces/runjs-authoring/runtime/errors.d.ts +22 -0
  48. package/dist/server/flow-surfaces/runjs-authoring/runtime/errors.js +91 -0
  49. package/dist/server/flow-surfaces/runjs-authoring/runtime/source-budget.d.ts +16 -0
  50. package/dist/server/flow-surfaces/runjs-authoring/runtime/source-budget.js +115 -0
  51. package/dist/server/flow-surfaces/runjs-authoring/runtime/surface.d.ts +19 -0
  52. package/dist/server/flow-surfaces/runjs-authoring/runtime/surface.js +140 -0
  53. package/dist/server/flow-surfaces/runjs-authoring/runtime/types.d.ts +91 -0
  54. package/dist/server/flow-surfaces/runjs-authoring/runtime/types.js +24 -0
  55. package/dist/server/flow-surfaces/runjs-authoring/scan/ctx-api.d.ts +138 -0
  56. package/dist/server/flow-surfaces/runjs-authoring/scan/ctx-api.js +1779 -0
  57. package/dist/server/flow-surfaces/runjs-authoring/scan/filter.d.ts +10 -0
  58. package/dist/server/flow-surfaces/runjs-authoring/scan/filter.js +1583 -0
  59. package/dist/server/flow-surfaces/runjs-authoring/scan/index.d.ts +195 -0
  60. package/dist/server/flow-surfaces/runjs-authoring/scan/index.js +463 -0
  61. package/dist/server/flow-surfaces/runjs-authoring/scan/react-render.d.ts +48 -0
  62. package/dist/server/flow-surfaces/runjs-authoring/scan/react-render.js +379 -0
  63. package/dist/server/flow-surfaces/runjs-authoring/scan/react.d.ts +26 -0
  64. package/dist/server/flow-surfaces/runjs-authoring/scan/react.js +1441 -0
  65. package/dist/server/flow-surfaces/runjs-authoring/scan/resource.d.ts +23 -0
  66. package/dist/server/flow-surfaces/runjs-authoring/scan/resource.js +1427 -0
  67. package/dist/server/flow-surfaces/runjs-authoring/scan/source-patterns.d.ts +91 -0
  68. package/dist/server/flow-surfaces/runjs-authoring/scan/source-patterns.js +889 -0
  69. package/dist/server/flow-surfaces/runjs-authoring/types.d.ts +1 -1
  70. package/dist/server/flow-surfaces/runjs-authoring/unknown-global-stop/index.d.ts +10 -0
  71. package/dist/server/flow-surfaces/runjs-authoring/unknown-global-stop/index.js +40 -0
  72. package/dist/server/flow-surfaces/runjs-authoring/validators/index.d.ts +12 -0
  73. package/dist/server/flow-surfaces/runjs-authoring/validators/index.js +887 -0
  74. package/dist/server/flow-surfaces/service-helpers.d.ts +29 -0
  75. package/dist/server/flow-surfaces/service-helpers.js +105 -0
  76. package/dist/server/flow-surfaces/service-utils.d.ts +15 -3
  77. package/dist/server/flow-surfaces/service-utils.js +5 -4
  78. package/dist/server/flow-surfaces/service.d.ts +4 -0
  79. package/dist/server/flow-surfaces/service.js +360 -30
  80. package/dist/server/flow-surfaces/types.d.ts +3 -0
  81. package/dist/server/repository.d.ts +12 -1
  82. package/dist/server/repository.js +195 -23
  83. package/dist/swagger/flow-surfaces.d.ts +175 -0
  84. package/dist/swagger/flow-surfaces.js +130 -51
  85. package/dist/swagger/index.d.ts +175 -0
  86. 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
+ });