@nocobase/plugin-flow-engine 2.1.0-beta.43 → 2.1.0-beta.45
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/authoring-validation.js +160 -21
- package/dist/server/flow-surfaces/catalog.js +9 -5
- package/dist/server/flow-surfaces/chart-config.js +29 -6
- package/dist/server/flow-surfaces/contract-guard.js +39 -5
- 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/filter-group.d.ts +7 -1
- package/dist/server/flow-surfaces/filter-group.js +175 -71
- package/dist/server/flow-surfaces/public-data-surface-default-filter.js +2 -1
- package/dist/server/flow-surfaces/runjs-authoring/ast/bindings.d.ts +66 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/bindings.js +661 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/execution.d.ts +20 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/execution.js +275 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/parser.d.ts +16 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/parser.js +130 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/react-values.d.ts +20 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/react-values.js +401 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/request-config.d.ts +21 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/request-config.js +199 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/source.d.ts +70 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/source.js +895 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/static-bindings.d.ts +23 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/static-bindings.js +618 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/static-values.d.ts +196 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/static-values.js +1777 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/walk.d.ts +10 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/walk.js +55 -0
- package/dist/server/flow-surfaces/runjs-authoring/collectors.d.ts +12 -0
- package/dist/server/flow-surfaces/runjs-authoring/collectors.js +589 -0
- package/dist/server/flow-surfaces/runjs-authoring/index.d.ts +2 -25
- package/dist/server/flow-surfaces/runjs-authoring/index.js +5 -11138
- package/dist/server/flow-surfaces/runjs-authoring/inspect.d.ts +13 -0
- package/dist/server/flow-surfaces/runjs-authoring/inspect.js +149 -0
- package/dist/server/flow-surfaces/runjs-authoring/internal-types.d.ts +333 -0
- package/dist/server/flow-surfaces/runjs-authoring/internal-types.js +36 -0
- package/dist/server/flow-surfaces/runjs-authoring/rules.js +2 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/constants.d.ts +67 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/constants.js +757 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/errors.d.ts +22 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/errors.js +91 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/source-budget.d.ts +16 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/source-budget.js +115 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/surface.d.ts +19 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/surface.js +140 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/types.d.ts +91 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/types.js +24 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/ctx-api.d.ts +138 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/ctx-api.js +1779 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/filter.d.ts +10 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/filter.js +1583 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/index.d.ts +195 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/index.js +463 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/react-render.d.ts +48 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/react-render.js +379 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/react.d.ts +26 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/react.js +1441 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/resource.d.ts +23 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/resource.js +1427 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/source-patterns.d.ts +91 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/source-patterns.js +889 -0
- package/dist/server/flow-surfaces/runjs-authoring/types.d.ts +1 -1
- package/dist/server/flow-surfaces/runjs-authoring/unknown-global-stop/index.d.ts +10 -0
- package/dist/server/flow-surfaces/runjs-authoring/unknown-global-stop/index.js +40 -0
- package/dist/server/flow-surfaces/runjs-authoring/validators/index.d.ts +12 -0
- package/dist/server/flow-surfaces/runjs-authoring/validators/index.js +887 -0
- package/dist/server/flow-surfaces/service-helpers.d.ts +29 -0
- package/dist/server/flow-surfaces/service-helpers.js +105 -0
- package/dist/server/flow-surfaces/service-utils.d.ts +15 -3
- package/dist/server/flow-surfaces/service-utils.js +5 -4
- package/dist/server/flow-surfaces/service.d.ts +4 -0
- package/dist/server/flow-surfaces/service.js +360 -30
- package/dist/server/flow-surfaces/types.d.ts +3 -0
- package/dist/server/repository.d.ts +15 -1
- package/dist/server/repository.js +262 -23
- package/dist/server/template/contexts.d.ts +2 -0
- package/dist/server/template/contexts.js +34 -0
- package/dist/server/template/resolver.js +233 -22
- package/dist/swagger/flow-surfaces.d.ts +175 -0
- package/dist/swagger/flow-surfaces.js +130 -51
- package/dist/swagger/index.d.ts +175 -0
- package/package.json +2 -2
|
@@ -0,0 +1,889 @@
|
|
|
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 __defProp = Object.defineProperty;
|
|
11
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
+
var __export = (target, all) => {
|
|
15
|
+
for (var name in all)
|
|
16
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
17
|
+
};
|
|
18
|
+
var __copyProps = (to, from, except, desc) => {
|
|
19
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
20
|
+
for (let key of __getOwnPropNames(from))
|
|
21
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
22
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
23
|
+
}
|
|
24
|
+
return to;
|
|
25
|
+
};
|
|
26
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
|
+
var source_patterns_exports = {};
|
|
28
|
+
__export(source_patterns_exports, {
|
|
29
|
+
collectCtxAliases: () => collectCtxAliases,
|
|
30
|
+
collectCtxLibMemberCaseMismatches: () => collectCtxLibMemberCaseMismatches,
|
|
31
|
+
collectCtxMemberAccesses: () => collectCtxMemberAccesses,
|
|
32
|
+
collectCtxRenderComponentSignatureCalls: () => collectCtxRenderComponentSignatureCalls,
|
|
33
|
+
collectDirectDomAliases: () => collectDirectDomAliases,
|
|
34
|
+
collectDirectDomWrites: () => collectDirectDomWrites,
|
|
35
|
+
collectFlowResourceAliases: () => collectFlowResourceAliases,
|
|
36
|
+
collectForbiddenBareGlobals: () => collectForbiddenBareGlobals,
|
|
37
|
+
collectInvalidApiResourceCalls: () => collectInvalidApiResourceCalls,
|
|
38
|
+
collectInvalidFlowResourceListCalls: () => collectInvalidFlowResourceListCalls,
|
|
39
|
+
collectInvalidResourceTypeCalls: () => collectInvalidResourceTypeCalls,
|
|
40
|
+
collectReactComponentAliases: () => collectReactComponentAliases,
|
|
41
|
+
collectReactComponentFunctionCalls: () => collectReactComponentFunctionCalls,
|
|
42
|
+
collectReactComponentPropReferences: () => collectReactComponentPropReferences,
|
|
43
|
+
collectReactHookCalls: () => collectReactHookCalls,
|
|
44
|
+
collectResourceCallsInReactHooks: () => collectResourceCallsInReactHooks,
|
|
45
|
+
collectUnboundReactCreateElementCalls: () => collectUnboundReactCreateElementCalls,
|
|
46
|
+
collectWindowDocumentNavigatorAliases: () => collectWindowDocumentNavigatorAliases,
|
|
47
|
+
collectWindowDocumentNavigatorUses: () => collectWindowDocumentNavigatorUses,
|
|
48
|
+
getResourceLikeCtxRunjsEntrypoint: () => getResourceLikeCtxRunjsEntrypoint,
|
|
49
|
+
isResourceLikeCtxRequest: () => isResourceLikeCtxRequest,
|
|
50
|
+
isTopLevelFunctionWrapper: () => isTopLevelFunctionWrapper
|
|
51
|
+
});
|
|
52
|
+
module.exports = __toCommonJS(source_patterns_exports);
|
|
53
|
+
var import_constants = require("../runtime/constants");
|
|
54
|
+
var import_bindings = require("../ast/bindings");
|
|
55
|
+
var import_source = require("../ast/source");
|
|
56
|
+
function collectForbiddenBareGlobals(masked, bindings) {
|
|
57
|
+
const entries = [];
|
|
58
|
+
for (const name of import_constants.FORBIDDEN_BARE_GLOBALS) {
|
|
59
|
+
const pattern = new RegExp(`(?<![.$\\w])${(0, import_source.escapeRegExp)(name)}\\b`, "g");
|
|
60
|
+
for (const match of masked.matchAll(pattern)) {
|
|
61
|
+
if (!(0, import_bindings.isNameBoundAtIndex)(bindings, name, match.index || 0) && !isObjectPropertyKey(masked, match.index || 0, name)) {
|
|
62
|
+
entries.push({ name, index: match.index || 0 });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return entries.sort((left, right) => left.index - right.index);
|
|
67
|
+
}
|
|
68
|
+
function collectInvalidApiResourceCalls(source, masked, bindings) {
|
|
69
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
70
|
+
const resourceMethods = /* @__PURE__ */ new Set(["list", "get", "create", "update", "destroy"]);
|
|
71
|
+
const entries = [
|
|
72
|
+
...masked.matchAll(
|
|
73
|
+
/\bctx\s*(?:\?\.|\.)\s*api\s*(?:\?\.|\.)\s*resource\s*(?:\?\.|\.)\s*(list|get|create|update|destroy)\s*(?:\?\.)?\(/g
|
|
74
|
+
)
|
|
75
|
+
].filter((match) => !(0, import_bindings.isNameBoundAtIndex)(bindings, "ctx", match.index || 0)).map((match) => ({
|
|
76
|
+
index: match.index || 0,
|
|
77
|
+
match: match[0].replace(/\s*(?:\?\.)?\($/, ""),
|
|
78
|
+
method: match[1]
|
|
79
|
+
}));
|
|
80
|
+
for (const match of masked.matchAll(/\bctx\s*(?:\?\.|\.)\s*api\s*(?:\?\.|\.)\s*resource\s*(?:\?\.)?\(/g)) {
|
|
81
|
+
const index = match.index || 0;
|
|
82
|
+
if ((0, import_bindings.isNameBoundAtIndex)(bindings, "ctx", index)) {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const openParen = masked.indexOf("(", index);
|
|
86
|
+
const closeParen = openParen >= 0 ? (0, import_source.findMatchingDelimiter)(masked, openParen) : -1;
|
|
87
|
+
const args = (0, import_source.getCallArgumentSources)(source, masked, index);
|
|
88
|
+
if (args.length >= 2) {
|
|
89
|
+
const method2 = (_b = (0, import_source.readCompleteStringLiteral)(((_a = args[0]) == null ? void 0 : _a.source) || "")) == null ? void 0 : _b.value;
|
|
90
|
+
if (method2 && resourceMethods.has(method2)) {
|
|
91
|
+
entries.push({
|
|
92
|
+
index,
|
|
93
|
+
match: `ctx.api.resource('${method2}')`,
|
|
94
|
+
method: method2
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
const resourceName2 = (_d = (0, import_source.readCompleteStringLiteral)(((_c = args[0]) == null ? void 0 : _c.source) || "")) == null ? void 0 : _d.value;
|
|
98
|
+
const action = (_f = (0, import_source.readCompleteStringLiteral)(((_e = args[1]) == null ? void 0 : _e.source) || "")) == null ? void 0 : _f.value;
|
|
99
|
+
if (action && resourceMethods.has(action)) {
|
|
100
|
+
entries.push({
|
|
101
|
+
index,
|
|
102
|
+
match: resourceName2 ? `ctx.api.resource('${resourceName2}', '${action}')` : `ctx.api.resource(..., '${action}')`,
|
|
103
|
+
method: action
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (closeParen < 0) {
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
const chainedMethod = masked.slice(closeParen + 1, closeParen + 96).match(/^\s*(?:\?\.|\.)\s*(list|get|create|update|destroy)\s*(?:\?\.)?\(/);
|
|
111
|
+
if (!chainedMethod) {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
const method = chainedMethod[1];
|
|
115
|
+
const resourceName = (_h = (0, import_source.readCompleteStringLiteral)(((_g = args[0]) == null ? void 0 : _g.source) || "")) == null ? void 0 : _h.value;
|
|
116
|
+
entries.push({
|
|
117
|
+
index,
|
|
118
|
+
match: resourceName ? `ctx.api.resource('${resourceName}').${method}` : `ctx.api.resource(...).${method}`,
|
|
119
|
+
method
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
return (0, import_bindings.dedupeIndexedEntries)(entries).sort((left, right) => left.index - right.index);
|
|
123
|
+
}
|
|
124
|
+
function collectInvalidResourceTypeCalls(source, masked, stringBindings, bindings) {
|
|
125
|
+
const entries = [];
|
|
126
|
+
for (const match of masked.matchAll(/\bctx\s*(?:\?\.|\.)\s*(makeResource|initResource)\s*(?:\?\.)?\(/g)) {
|
|
127
|
+
const index = match.index || 0;
|
|
128
|
+
if ((0, import_bindings.isNameBoundAtIndex)(bindings, "ctx", index)) {
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
const method = match[1];
|
|
132
|
+
const capability = `ctx.${method}`;
|
|
133
|
+
const firstArg = (0, import_source.getCallArgumentSources)(source, masked, index)[0];
|
|
134
|
+
if (!firstArg) {
|
|
135
|
+
entries.push({
|
|
136
|
+
capability,
|
|
137
|
+
expression: "",
|
|
138
|
+
index,
|
|
139
|
+
ruleId: "runjs-make-resource-type-unresolved",
|
|
140
|
+
message: `flowSurfaces authoring cannot validate ${capability}(...) without a resource type`
|
|
141
|
+
});
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
const resolved = resolveResourceTypeExpression(firstArg, stringBindings);
|
|
145
|
+
if (resolved.status === "unresolved") {
|
|
146
|
+
entries.push({
|
|
147
|
+
capability,
|
|
148
|
+
expression: resolved.expression,
|
|
149
|
+
index,
|
|
150
|
+
ruleId: "runjs-make-resource-type-unresolved",
|
|
151
|
+
message: `flowSurfaces authoring cannot validate dynamic ${capability}(...) resource type '${resolved.expression}'`
|
|
152
|
+
});
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
const allowedResourceTypes = method === "initResource" ? import_constants.INIT_RESOURCE_CLASS_NAMES : import_constants.FLOW_RESOURCE_CLASS_NAMES;
|
|
156
|
+
if (!allowedResourceTypes.has(resolved.value)) {
|
|
157
|
+
entries.push({
|
|
158
|
+
capability,
|
|
159
|
+
index,
|
|
160
|
+
resourceType: resolved.value,
|
|
161
|
+
ruleId: "runjs-make-resource-type-invalid",
|
|
162
|
+
message: `flowSurfaces authoring ${capability}(...) expects a FlowResource class name, not collection '${resolved.value}'`
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return entries;
|
|
167
|
+
}
|
|
168
|
+
function collectResourceCallsInReactHooks(source, masked, reactHookCalls, bindings) {
|
|
169
|
+
const hookArgumentRanges = reactHookCalls.map((hook) => {
|
|
170
|
+
const firstArg = (0, import_source.getCallArgumentSources)(source, masked, hook.index)[0];
|
|
171
|
+
return firstArg ? { hook: hook.hook, range: firstArg } : null;
|
|
172
|
+
}).filter(Boolean);
|
|
173
|
+
if (!hookArgumentRanges.length) {
|
|
174
|
+
return [];
|
|
175
|
+
}
|
|
176
|
+
const entries = [];
|
|
177
|
+
const pattern = /\bctx\s*(?:\?\.|\.)\s*(?:(makeResource|initResource)\s*(?:\?\.)?\(|resource\b)/g;
|
|
178
|
+
for (const match of masked.matchAll(pattern)) {
|
|
179
|
+
const index = match.index || 0;
|
|
180
|
+
if ((0, import_bindings.isNameBoundAtIndex)(bindings, "ctx", index)) {
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
const hook = hookArgumentRanges.find((entry) => index >= entry.range.start && index < entry.range.end);
|
|
184
|
+
if (!hook) {
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
entries.push({
|
|
188
|
+
capability: match[1] ? `ctx.${match[1]}` : "ctx.resource",
|
|
189
|
+
hook: hook.hook,
|
|
190
|
+
index
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
return (0, import_bindings.dedupeIndexedEntries)(entries).sort((left, right) => left.index - right.index);
|
|
194
|
+
}
|
|
195
|
+
function resolveResourceTypeExpression(arg, stringBindings) {
|
|
196
|
+
const expression = arg.source.trim();
|
|
197
|
+
const leadingLength = arg.source.length - arg.source.trimStart().length;
|
|
198
|
+
const expressionIndex = arg.start + leadingLength;
|
|
199
|
+
const literal = (0, import_source.readCompleteStringLiteral)(arg.source);
|
|
200
|
+
if (literal) {
|
|
201
|
+
return { status: "resolved", value: literal.value };
|
|
202
|
+
}
|
|
203
|
+
if (/^[A-Za-z_$][\w$]*$/.test(expression)) {
|
|
204
|
+
const binding = stringBindings.find(
|
|
205
|
+
(entry) => entry.name === expression && expressionIndex >= entry.start && expressionIndex < entry.end
|
|
206
|
+
);
|
|
207
|
+
if (binding) {
|
|
208
|
+
return { status: "resolved", value: binding.value };
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return {
|
|
212
|
+
status: "unresolved",
|
|
213
|
+
expression
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
function collectFlowResourceAliases(masked, bindings) {
|
|
217
|
+
const aliases = [];
|
|
218
|
+
const addAlias = (name, capability, declarationIndex) => {
|
|
219
|
+
const binding = (0, import_bindings.findSourceBindingByDeclaration)(bindings, name, declarationIndex);
|
|
220
|
+
aliases.push({
|
|
221
|
+
name,
|
|
222
|
+
capability,
|
|
223
|
+
declarationStart: declarationIndex,
|
|
224
|
+
start: declarationIndex,
|
|
225
|
+
end: (binding == null ? void 0 : binding.end) ?? masked.length
|
|
226
|
+
});
|
|
227
|
+
};
|
|
228
|
+
for (const match of masked.matchAll(
|
|
229
|
+
/\b(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*ctx\s*(?:\?\.|\.)\s*(makeResource|initResource)\s*(?:\?\.)?\(/g
|
|
230
|
+
)) {
|
|
231
|
+
if ((0, import_bindings.isNameBoundAtIndex)(bindings, "ctx", (match.index || 0) + match[0].lastIndexOf("ctx"))) {
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
addAlias(match[1], `ctx.${match[2]}`, match.index || 0);
|
|
235
|
+
}
|
|
236
|
+
for (const match of masked.matchAll(
|
|
237
|
+
/\b(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*ctx\s*(?:\?\.|\.)\s*resource\b/g
|
|
238
|
+
)) {
|
|
239
|
+
if ((0, import_bindings.isNameBoundAtIndex)(bindings, "ctx", (match.index || 0) + match[0].lastIndexOf("ctx"))) {
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
addAlias(match[1], "ctx.resource", match.index || 0);
|
|
243
|
+
}
|
|
244
|
+
return aliases;
|
|
245
|
+
}
|
|
246
|
+
function collectInvalidFlowResourceListCalls(masked, aliases, bindings) {
|
|
247
|
+
const entries = [];
|
|
248
|
+
for (const match of masked.matchAll(/\bctx\s*(?:\?\.|\.)\s*resource\s*(?:\?\.|\.)\s*list\s*(?:\?\.)?\(/g)) {
|
|
249
|
+
if ((0, import_bindings.isNameBoundAtIndex)(bindings, "ctx", match.index || 0)) {
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
entries.push({
|
|
253
|
+
index: match.index || 0,
|
|
254
|
+
capability: "ctx.resource.list"
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
for (const match of masked.matchAll(
|
|
258
|
+
/\bctx\s*(?:\?\.|\.)\s*(makeResource|initResource)\s*(?:\?\.)?\([^)]*\)\s*(?:\?\.|\.)\s*list\s*(?:\?\.)?\(/g
|
|
259
|
+
)) {
|
|
260
|
+
if ((0, import_bindings.isNameBoundAtIndex)(bindings, "ctx", match.index || 0)) {
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
entries.push({
|
|
264
|
+
index: match.index || 0,
|
|
265
|
+
capability: `ctx.${match[1]}(...).list`
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
aliases.forEach((alias) => {
|
|
269
|
+
const pattern = new RegExp(
|
|
270
|
+
`(?<![.$\\w])${(0, import_source.escapeRegExp)(alias.name)}\\s*(?:\\?\\.|\\.)\\s*list\\s*(?:\\?\\.)?\\(`,
|
|
271
|
+
"g"
|
|
272
|
+
);
|
|
273
|
+
for (const match of masked.matchAll(pattern)) {
|
|
274
|
+
const index = match.index || 0;
|
|
275
|
+
if (index <= alias.start || index >= alias.end) {
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
if ((0, import_bindings.isSourceAliasShadowedAtIndex)(alias, bindings, index)) {
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
entries.push({
|
|
282
|
+
index,
|
|
283
|
+
capability: `${alias.name}.list`
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
return (0, import_bindings.dedupeIndexedEntries)(entries).sort((left, right) => left.index - right.index);
|
|
288
|
+
}
|
|
289
|
+
function collectCtxLibMemberCaseMismatches(source, masked, bindings) {
|
|
290
|
+
const entries = [];
|
|
291
|
+
const addEntry = (index, member, accessKind, capability) => {
|
|
292
|
+
const expectedMember = import_constants.CTX_LIB_MEMBER_BY_LOWERCASE.get(member.toLowerCase());
|
|
293
|
+
if (!expectedMember || expectedMember === member) {
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
entries.push({
|
|
297
|
+
accessKind,
|
|
298
|
+
capability: capability || `ctx.libs.${member}`,
|
|
299
|
+
expectedCapability: `ctx.libs.${expectedMember}`,
|
|
300
|
+
expectedMember,
|
|
301
|
+
index,
|
|
302
|
+
member
|
|
303
|
+
});
|
|
304
|
+
};
|
|
305
|
+
for (const match of masked.matchAll(/\bctx\s*(?:\?\.|\.)\s*libs\s*(?:\?\.|\.)\s*([A-Za-z_$][\w$]*)/g)) {
|
|
306
|
+
const index = match.index || 0;
|
|
307
|
+
if ((0, import_bindings.isNameBoundAtIndex)(bindings, "ctx", index)) {
|
|
308
|
+
continue;
|
|
309
|
+
}
|
|
310
|
+
const member = match[1];
|
|
311
|
+
addEntry(index + match[0].lastIndexOf(member), member, "member");
|
|
312
|
+
}
|
|
313
|
+
for (const match of source.matchAll(
|
|
314
|
+
/\bctx\s*(?:\?\.|\.)\s*libs\s*(?:\?\.)?\s*\[\s*(['"])([A-Za-z_$][\w$]*)\1\s*\]/g
|
|
315
|
+
)) {
|
|
316
|
+
const index = match.index || 0;
|
|
317
|
+
if (masked.slice(index, index + 3) !== "ctx" || (0, import_bindings.isNameBoundAtIndex)(bindings, "ctx", index)) {
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
const quote = match[1];
|
|
321
|
+
const member = match[2];
|
|
322
|
+
addEntry(index + match[0].indexOf(member), member, "bracket", `ctx.libs[${quote}${member}${quote}]`);
|
|
323
|
+
}
|
|
324
|
+
for (const match of masked.matchAll(/\b(?:const|let|var)\s*\{([^}]*)\}\s*=\s*ctx\s*(?:\?\.|\.)\s*libs\b/g)) {
|
|
325
|
+
const declarationIndex = match.index || 0;
|
|
326
|
+
const ctxIndex = declarationIndex + match[0].lastIndexOf("ctx");
|
|
327
|
+
if ((0, import_bindings.isNameBoundAtIndex)(bindings, "ctx", ctxIndex)) {
|
|
328
|
+
continue;
|
|
329
|
+
}
|
|
330
|
+
const bindingPattern = match[1];
|
|
331
|
+
const patternStart = declarationIndex + match[0].indexOf(bindingPattern);
|
|
332
|
+
(0, import_source.splitTopLevelWithRanges)(bindingPattern, ",").forEach((property) => {
|
|
333
|
+
const prop = readObjectBindingPropertyName(property.source);
|
|
334
|
+
if (!prop) {
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
addEntry(patternStart + property.start + prop.offset, prop.name, "destructure", `ctx.libs.${prop.name}`);
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
return (0, import_bindings.dedupeIndexedEntries)(entries).sort((left, right) => left.index - right.index);
|
|
341
|
+
}
|
|
342
|
+
function readObjectBindingPropertyName(element) {
|
|
343
|
+
const trimmed = element.trim();
|
|
344
|
+
if (!trimmed || trimmed.startsWith("...") || trimmed.startsWith("{") || trimmed.startsWith("[")) {
|
|
345
|
+
return void 0;
|
|
346
|
+
}
|
|
347
|
+
const normalized = (0, import_source.trimBindingElement)(trimmed);
|
|
348
|
+
const colon = (0, import_source.findTopLevelChar)(normalized, ":");
|
|
349
|
+
const rawProperty = (colon >= 0 ? normalized.slice(0, colon) : normalized).trim();
|
|
350
|
+
const name = normalizeObjectPropertyName(rawProperty);
|
|
351
|
+
if (!/^[A-Za-z_$][\w$]*$/.test(name)) {
|
|
352
|
+
return void 0;
|
|
353
|
+
}
|
|
354
|
+
const offset = Math.max(0, element.indexOf(name));
|
|
355
|
+
return { name, offset };
|
|
356
|
+
}
|
|
357
|
+
function collectReactHookCalls(masked, bindings) {
|
|
358
|
+
const entries = [];
|
|
359
|
+
const memberPattern = new RegExp(
|
|
360
|
+
`\\b(?:(?:ctx\\s*(?:\\?\\.|\\.)\\s*(?:libs\\s*(?:\\?\\.|\\.)\\s*)?React)|React)\\s*(?:\\?\\.|\\.)\\s*(${import_constants.REACT_HOOK_PATTERN})\\s*(?:\\?\\.)?\\(`,
|
|
361
|
+
"g"
|
|
362
|
+
);
|
|
363
|
+
for (const match of masked.matchAll(memberPattern)) {
|
|
364
|
+
const index = match.index || 0;
|
|
365
|
+
if (masked.slice(index, index + 3) === "ctx" && (0, import_bindings.isNameBoundAtIndex)(bindings, "ctx", index)) {
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
368
|
+
entries.push({
|
|
369
|
+
hook: match[1],
|
|
370
|
+
index,
|
|
371
|
+
match: match[0].replace(/\s*(?:\?\.)?\($/, "")
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
const barePattern = new RegExp(`(?<![.$\\w])(${import_constants.REACT_HOOK_PATTERN})\\s*(?:\\?\\.)?\\(`, "g");
|
|
375
|
+
for (const match of masked.matchAll(barePattern)) {
|
|
376
|
+
const index = match.index || 0;
|
|
377
|
+
const hook = match[1];
|
|
378
|
+
if ((0, import_source.getPreviousSignificantToken)(masked, index) === "function" || isObjectPropertyKey(masked, index, hook)) {
|
|
379
|
+
continue;
|
|
380
|
+
}
|
|
381
|
+
entries.push({
|
|
382
|
+
hook,
|
|
383
|
+
index,
|
|
384
|
+
match: match[0].replace(/\s*(?:\?\.)?\($/, "")
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
return (0, import_bindings.dedupeIndexedEntries)(entries).sort((left, right) => left.index - right.index);
|
|
388
|
+
}
|
|
389
|
+
function collectUnboundReactCreateElementCalls(masked, bindings) {
|
|
390
|
+
const entries = [];
|
|
391
|
+
for (const match of masked.matchAll(/(?<![.$\w])React\s*(?:\?\.|\.)\s*createElement\s*(?:\?\.)?\(/g)) {
|
|
392
|
+
const index = match.index || 0;
|
|
393
|
+
if (!(0, import_bindings.isNameBoundAtIndex)(bindings, "React", index)) {
|
|
394
|
+
entries.push({ index });
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
return entries;
|
|
398
|
+
}
|
|
399
|
+
function collectReactComponentAliases(masked, bindings) {
|
|
400
|
+
const aliases = [];
|
|
401
|
+
const addAlias = (name, capability, declarationIndex) => {
|
|
402
|
+
if (!/^[A-Z][\w$]*$/.test(name)) {
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
const binding = (0, import_bindings.findSourceBindingByDeclaration)(bindings, name, declarationIndex);
|
|
406
|
+
aliases.push({
|
|
407
|
+
name,
|
|
408
|
+
capability,
|
|
409
|
+
declarationStart: declarationIndex,
|
|
410
|
+
start: declarationIndex,
|
|
411
|
+
end: (binding == null ? void 0 : binding.end) ?? masked.length
|
|
412
|
+
});
|
|
413
|
+
};
|
|
414
|
+
for (const match of masked.matchAll(
|
|
415
|
+
/\b(?:const|let|var)\s*\{([^}]*)\}\s*=\s*ctx\s*(?:\?\.|\.)\s*(?:(libs)\s*(?:\?\.|\.)\s*)?(antdIcons|antd)\b/g
|
|
416
|
+
)) {
|
|
417
|
+
const declarationIndex = match.index || 0;
|
|
418
|
+
const ctxIndex = declarationIndex + match[0].lastIndexOf("ctx");
|
|
419
|
+
if ((0, import_bindings.isNameBoundAtIndex)(bindings, "ctx", ctxIndex)) {
|
|
420
|
+
continue;
|
|
421
|
+
}
|
|
422
|
+
const namespace = `ctx.${match[2] ? "libs." : ""}${match[3]}`;
|
|
423
|
+
collectObjectBindingAliases(match[1]).forEach(
|
|
424
|
+
(alias) => addAlias(alias, `${namespace}.${alias}`, declarationIndex)
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
for (const match of masked.matchAll(
|
|
428
|
+
/\b(?:const|let|var)\s+([A-Z][\w$]*)\s*=\s*ctx\s*(?:\?\.|\.)\s*(?:(libs)\s*(?:\?\.|\.)\s*)?(antdIcons|antd)\s*(?:\?\.|\.)\s*([A-Z][\w$]*)\b/g
|
|
429
|
+
)) {
|
|
430
|
+
const ctxIndex = (match.index || 0) + match[0].lastIndexOf("ctx");
|
|
431
|
+
if ((0, import_bindings.isNameBoundAtIndex)(bindings, "ctx", ctxIndex)) {
|
|
432
|
+
continue;
|
|
433
|
+
}
|
|
434
|
+
const namespace = `ctx.${match[2] ? "libs." : ""}${match[3]}`;
|
|
435
|
+
addAlias(match[1], `${namespace}.${match[4]}`, match.index || 0);
|
|
436
|
+
}
|
|
437
|
+
return aliases;
|
|
438
|
+
}
|
|
439
|
+
function collectReactComponentFunctionCalls(masked, aliases, bindings) {
|
|
440
|
+
const entries = [];
|
|
441
|
+
for (const match of masked.matchAll(
|
|
442
|
+
/\bctx\s*(?:\?\.|\.)\s*(?:(libs)\s*(?:\?\.|\.)\s*)?(antdIcons|antd)\s*(?:\?\.|\.)\s*([A-Z][\w$]*)\s*(?:\?\.)?\(/g
|
|
443
|
+
)) {
|
|
444
|
+
if ((0, import_bindings.isNameBoundAtIndex)(bindings, "ctx", match.index || 0)) {
|
|
445
|
+
continue;
|
|
446
|
+
}
|
|
447
|
+
const namespace = `ctx.${match[1] ? "libs." : ""}${match[2]}`;
|
|
448
|
+
entries.push({
|
|
449
|
+
index: match.index || 0,
|
|
450
|
+
component: match[3],
|
|
451
|
+
capability: `${namespace}.${match[3]}`
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
aliases.forEach((alias) => {
|
|
455
|
+
const pattern = new RegExp(`(?<![.$\\w])${(0, import_source.escapeRegExp)(alias.name)}\\s*(?:\\?\\.)?\\(`, "g");
|
|
456
|
+
for (const match of masked.matchAll(pattern)) {
|
|
457
|
+
const index = match.index || 0;
|
|
458
|
+
if (index <= alias.start || index >= alias.end) {
|
|
459
|
+
continue;
|
|
460
|
+
}
|
|
461
|
+
if ((0, import_bindings.isSourceAliasShadowedAtIndex)(alias, bindings, index)) {
|
|
462
|
+
continue;
|
|
463
|
+
}
|
|
464
|
+
const previous = (0, import_source.getPreviousSignificantToken)(masked, index);
|
|
465
|
+
if (previous === "function" || isObjectPropertyKey(masked, index, alias.name)) {
|
|
466
|
+
continue;
|
|
467
|
+
}
|
|
468
|
+
entries.push({
|
|
469
|
+
index,
|
|
470
|
+
component: alias.name,
|
|
471
|
+
capability: alias.capability
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
});
|
|
475
|
+
return (0, import_bindings.dedupeIndexedEntries)(entries).sort((left, right) => left.index - right.index);
|
|
476
|
+
}
|
|
477
|
+
function collectCtxRenderComponentSignatureCalls(source, masked, aliases, bindings) {
|
|
478
|
+
const entries = [];
|
|
479
|
+
for (const match of masked.matchAll(/\bctx\s*(?:\?\.|\.)\s*render\s*(?:\?\.)?\(/g)) {
|
|
480
|
+
const index = match.index || 0;
|
|
481
|
+
if ((0, import_bindings.isNameBoundAtIndex)(bindings, "ctx", index)) {
|
|
482
|
+
continue;
|
|
483
|
+
}
|
|
484
|
+
const firstArg = (0, import_source.getCallArgumentSources)(source, masked, index)[0];
|
|
485
|
+
if (!firstArg) {
|
|
486
|
+
continue;
|
|
487
|
+
}
|
|
488
|
+
const reference = readReactComponentReference(firstArg.source, aliases, firstArg.start, bindings);
|
|
489
|
+
if (reference) {
|
|
490
|
+
entries.push({
|
|
491
|
+
index: firstArg.start,
|
|
492
|
+
...reference
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
return (0, import_bindings.dedupeIndexedEntries)(entries).sort((left, right) => left.index - right.index);
|
|
497
|
+
}
|
|
498
|
+
function collectReactComponentPropReferences(source, masked, aliases, bindings) {
|
|
499
|
+
var _a, _b;
|
|
500
|
+
const entries = [];
|
|
501
|
+
const inspectPropsArg = (arg) => {
|
|
502
|
+
if (!arg) {
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
collectReactComponentPropReferencesFromObject(arg, aliases, bindings).forEach((entry) => entries.push(entry));
|
|
506
|
+
};
|
|
507
|
+
for (const match of masked.matchAll(
|
|
508
|
+
/\b(?:(?:ctx\s*(?:\?\.|\.)\s*(?:libs\s*(?:\?\.|\.)\s*)?React)|React)\s*(?:\?\.|\.)\s*createElement\s*(?:\?\.)?\(/g
|
|
509
|
+
)) {
|
|
510
|
+
if (masked.slice(match.index || 0, (match.index || 0) + 3) === "ctx" && (0, import_bindings.isNameBoundAtIndex)(bindings, "ctx", match.index || 0)) {
|
|
511
|
+
continue;
|
|
512
|
+
}
|
|
513
|
+
inspectPropsArg((0, import_source.getCallArgumentSources)(source, masked, match.index || 0)[1]);
|
|
514
|
+
}
|
|
515
|
+
for (const match of masked.matchAll(/\bctx\s*(?:\?\.|\.)\s*render\s*(?:\?\.)?\(/g)) {
|
|
516
|
+
if ((0, import_bindings.isNameBoundAtIndex)(bindings, "ctx", match.index || 0)) {
|
|
517
|
+
continue;
|
|
518
|
+
}
|
|
519
|
+
const args = (0, import_source.getCallArgumentSources)(source, masked, match.index || 0);
|
|
520
|
+
if (!readReactComponentReference(((_a = args[0]) == null ? void 0 : _a.source) || "", aliases, ((_b = args[0]) == null ? void 0 : _b.start) || 0, bindings)) {
|
|
521
|
+
continue;
|
|
522
|
+
}
|
|
523
|
+
inspectPropsArg(args[1]);
|
|
524
|
+
}
|
|
525
|
+
return (0, import_bindings.dedupeIndexedEntries)(entries).sort((left, right) => left.index - right.index);
|
|
526
|
+
}
|
|
527
|
+
function collectReactComponentPropReferencesFromObject(arg, aliases, bindings) {
|
|
528
|
+
const entries = [];
|
|
529
|
+
const localMasked = (0, import_source.maskJavaScriptSource)(arg.source);
|
|
530
|
+
const openOffset = arg.source.search(/\S/);
|
|
531
|
+
if (openOffset < 0 || arg.source[openOffset] !== "{") {
|
|
532
|
+
return entries;
|
|
533
|
+
}
|
|
534
|
+
const closeOffset = (0, import_source.findMatchingDelimiter)(localMasked, openOffset);
|
|
535
|
+
if (closeOffset <= openOffset) {
|
|
536
|
+
return entries;
|
|
537
|
+
}
|
|
538
|
+
const body = arg.source.slice(openOffset + 1, closeOffset);
|
|
539
|
+
const bodyStart = arg.start + openOffset + 1;
|
|
540
|
+
(0, import_source.splitTopLevelWithRanges)(body, ",").forEach((property) => {
|
|
541
|
+
const colon = (0, import_source.findTopLevelChar)(property.source, ":");
|
|
542
|
+
if (colon < 0) {
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
const propName = normalizeObjectPropertyName(property.source.slice(0, colon));
|
|
546
|
+
if (!import_constants.REACT_NODE_COMPONENT_PROP_NAMES.has(propName)) {
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
const rawValue = property.source.slice(colon + 1);
|
|
550
|
+
const leading = rawValue.length - rawValue.trimStart().length;
|
|
551
|
+
const valueStart = bodyStart + property.start + colon + 1 + leading;
|
|
552
|
+
const reference = readReactComponentReference(rawValue, aliases, valueStart, bindings);
|
|
553
|
+
if (!reference) {
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
entries.push({
|
|
557
|
+
index: valueStart,
|
|
558
|
+
prop: propName,
|
|
559
|
+
...reference
|
|
560
|
+
});
|
|
561
|
+
});
|
|
562
|
+
return entries;
|
|
563
|
+
}
|
|
564
|
+
function readReactComponentReference(expression, aliases, expressionIndex, bindings) {
|
|
565
|
+
const normalized = (0, import_source.maskJavaScriptComments)(expression).trim();
|
|
566
|
+
const ctxMatch = normalized.match(
|
|
567
|
+
/^ctx\s*(?:\?\.|\.)\s*(?:(libs)\s*(?:\?\.|\.)\s*)?(antdIcons|antd)\s*(?:\?\.|\.)\s*([A-Z][\w$]*)$/
|
|
568
|
+
);
|
|
569
|
+
if (ctxMatch) {
|
|
570
|
+
if ((0, import_bindings.isNameBoundAtIndex)(bindings, "ctx", expressionIndex)) {
|
|
571
|
+
return void 0;
|
|
572
|
+
}
|
|
573
|
+
const namespace = `ctx.${ctxMatch[1] ? "libs." : ""}${ctxMatch[2]}`;
|
|
574
|
+
return {
|
|
575
|
+
component: ctxMatch[3],
|
|
576
|
+
capability: `${namespace}.${ctxMatch[3]}`
|
|
577
|
+
};
|
|
578
|
+
}
|
|
579
|
+
const aliasMatch = normalized.match(/^([A-Z][\w$]*)$/);
|
|
580
|
+
if (!aliasMatch) {
|
|
581
|
+
return void 0;
|
|
582
|
+
}
|
|
583
|
+
const alias = aliases.find(
|
|
584
|
+
(entry) => entry.name === aliasMatch[1] && expressionIndex >= entry.start && expressionIndex < entry.end && !(0, import_bindings.isSourceAliasShadowedAtIndex)(entry, bindings, expressionIndex)
|
|
585
|
+
);
|
|
586
|
+
return alias ? {
|
|
587
|
+
component: alias.name,
|
|
588
|
+
capability: alias.capability
|
|
589
|
+
} : void 0;
|
|
590
|
+
}
|
|
591
|
+
function normalizeObjectPropertyName(value) {
|
|
592
|
+
return value.trim().replace(/^['"]([A-Za-z_$][\w$]*)['"]$/, "$1");
|
|
593
|
+
}
|
|
594
|
+
function isObjectPropertyKey(masked, index, name) {
|
|
595
|
+
let cursor = index + name.length;
|
|
596
|
+
while (cursor < masked.length && /\s/.test(masked[cursor])) {
|
|
597
|
+
cursor += 1;
|
|
598
|
+
}
|
|
599
|
+
if (masked[cursor] === ":") {
|
|
600
|
+
return true;
|
|
601
|
+
}
|
|
602
|
+
if (masked[cursor] !== "(") {
|
|
603
|
+
return false;
|
|
604
|
+
}
|
|
605
|
+
const previous = (0, import_source.getPreviousSignificantToken)(masked, index);
|
|
606
|
+
return previous === "{" || previous === ",";
|
|
607
|
+
}
|
|
608
|
+
function collectDirectDomWrites(source, masked, bindings) {
|
|
609
|
+
const entries = [];
|
|
610
|
+
const commentMasked = (0, import_source.maskJavaScriptComments)(source);
|
|
611
|
+
const pattern = /\b(ctx)\s*(?:\?\.|\.)\s*element\s*(?:\?\.|\.)\s*(innerHTML|insertAdjacentHTML)\b|\b(document)\s*(?:\?\.|\.)\s*(createElement)\b|\b(element)\s*(?:\?\.|\.)\s*(innerHTML|insertAdjacentHTML)\b|(?<![.$\w])(insertAdjacentHTML)\s*(?:\?\.)?\(/g;
|
|
612
|
+
for (const match of masked.matchAll(pattern)) {
|
|
613
|
+
const index = match.index || 0;
|
|
614
|
+
const boundRoot = match[3] || match[5];
|
|
615
|
+
const bareFunction = match[7];
|
|
616
|
+
if (match[1] === "ctx" && (0, import_bindings.isNameBoundAtIndex)(bindings, "ctx", index) || boundRoot && (0, import_bindings.isNameBoundAtIndex)(bindings, boundRoot, index) || bareFunction && (0, import_bindings.isNameBoundAtIndex)(bindings, bareFunction, index)) {
|
|
617
|
+
continue;
|
|
618
|
+
}
|
|
619
|
+
entries.push({ index, match: match[0].replace(/\s*(?:\?\.)?\($/, "") });
|
|
620
|
+
}
|
|
621
|
+
for (const match of commentMasked.matchAll(
|
|
622
|
+
/\b(ctx)\s*(?:\?\.|\.)\s*element\s*(?:\?\.\s*)?\[\s*(?:(['"])([A-Za-z_$][\w$]*)\2|([^\]]+))\s*\]/g
|
|
623
|
+
)) {
|
|
624
|
+
const index = match.index || 0;
|
|
625
|
+
const member = match[3] || "";
|
|
626
|
+
const dynamicMember = Boolean(match[4]);
|
|
627
|
+
if (isCodeTokenAt(masked, index, "ctx") && !(0, import_bindings.isNameBoundAtIndex)(bindings, "ctx", index) && (dynamicMember || isDirectDomMember(member))) {
|
|
628
|
+
entries.push({ index, match: match[0] });
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
for (const match of commentMasked.matchAll(
|
|
632
|
+
/\b(document)\s*(?:\?\.\s*)?\[\s*(?:(['"])([A-Za-z_$][\w$]*)\2|([^\]]+))\s*\]/g
|
|
633
|
+
)) {
|
|
634
|
+
const index = match.index || 0;
|
|
635
|
+
const member = match[3] || "";
|
|
636
|
+
const dynamicMember = Boolean(match[4]);
|
|
637
|
+
if (isCodeTokenAt(masked, index, match[1]) && !(0, import_bindings.isNameBoundAtIndex)(bindings, match[1], index) && (dynamicMember || member === "createElement")) {
|
|
638
|
+
entries.push({ index, match: match[0] });
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
for (const match of commentMasked.matchAll(
|
|
642
|
+
/\b(element)\s*(?:\?\.\s*)?\[\s*(?:(['"])([A-Za-z_$][\w$]*)\2|([^\]]+))\s*\]/g
|
|
643
|
+
)) {
|
|
644
|
+
const index = match.index || 0;
|
|
645
|
+
const member = match[3] || "";
|
|
646
|
+
const dynamicMember = Boolean(match[4]);
|
|
647
|
+
if (isCodeTokenAt(masked, index, match[1]) && !(0, import_bindings.isNameBoundAtIndex)(bindings, match[1], index) && (dynamicMember || isDirectDomMember(member))) {
|
|
648
|
+
entries.push({ index, match: match[0] });
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
return entries;
|
|
652
|
+
}
|
|
653
|
+
function collectWindowDocumentNavigatorUses(source, masked, bindings) {
|
|
654
|
+
const commentMasked = (0, import_source.maskJavaScriptComments)(source);
|
|
655
|
+
const entries = [...masked.matchAll(/\b(window|document|navigator)\s*(?:\?\.|\.)\s*([A-Za-z_$][\w$]*)/g)].filter((match) => !(0, import_bindings.isNameBoundAtIndex)(bindings, match[1], match.index || 0)).map((match) => ({
|
|
656
|
+
root: match[1],
|
|
657
|
+
member: match[2],
|
|
658
|
+
index: match.index || 0
|
|
659
|
+
}));
|
|
660
|
+
for (const match of commentMasked.matchAll(
|
|
661
|
+
/\b(window|document|navigator)\s*(?:\?\.\s*)?\[\s*(?:(['"])([A-Za-z_$][\w$]*)\2|([^\]]+))\s*\]/g
|
|
662
|
+
)) {
|
|
663
|
+
const index = match.index || 0;
|
|
664
|
+
const root = match[1];
|
|
665
|
+
if (!isCodeTokenAt(masked, index, root) || (0, import_bindings.isNameBoundAtIndex)(bindings, root, index)) {
|
|
666
|
+
continue;
|
|
667
|
+
}
|
|
668
|
+
entries.push({
|
|
669
|
+
root,
|
|
670
|
+
member: match[3] || "[dynamic]",
|
|
671
|
+
index
|
|
672
|
+
});
|
|
673
|
+
}
|
|
674
|
+
return entries.sort((left, right) => left.index - right.index);
|
|
675
|
+
}
|
|
676
|
+
function collectWindowDocumentNavigatorAliases(masked, bindings) {
|
|
677
|
+
const entries = [];
|
|
678
|
+
collectAliasMatches(
|
|
679
|
+
masked,
|
|
680
|
+
[
|
|
681
|
+
/\b(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*(window|document|navigator)\b/g,
|
|
682
|
+
/(?<![.$\w])([A-Za-z_$][\w$]*)\s*=\s*(window|document|navigator)\b/g
|
|
683
|
+
],
|
|
684
|
+
(match) => {
|
|
685
|
+
const alias = match[1];
|
|
686
|
+
const root = match[2];
|
|
687
|
+
const rootIndex = (match.index || 0) + match[0].lastIndexOf(root);
|
|
688
|
+
if (alias === root || (0, import_bindings.isNameBoundAtIndex)(bindings, root, rootIndex)) {
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
691
|
+
entries.push({ alias, root, index: rootIndex });
|
|
692
|
+
}
|
|
693
|
+
);
|
|
694
|
+
for (const match of masked.matchAll(
|
|
695
|
+
/\b(?:const|let|var)\s*\{([^}]*)\}\s*=\s*(window|document|navigator)\b(?!\s*(?:\.|\?\.))/g
|
|
696
|
+
)) {
|
|
697
|
+
const root = match[2];
|
|
698
|
+
const rootIndex = (match.index || 0) + match[0].lastIndexOf(root);
|
|
699
|
+
if ((0, import_bindings.isNameBoundAtIndex)(bindings, root, rootIndex)) {
|
|
700
|
+
continue;
|
|
701
|
+
}
|
|
702
|
+
collectObjectBindingAliases(match[1]).forEach((alias) => {
|
|
703
|
+
entries.push({ alias, root, index: rootIndex });
|
|
704
|
+
});
|
|
705
|
+
}
|
|
706
|
+
return dedupeAliasEntries(entries);
|
|
707
|
+
}
|
|
708
|
+
function collectDirectDomAliases(masked, bindings) {
|
|
709
|
+
const entries = [];
|
|
710
|
+
collectAliasMatches(
|
|
711
|
+
masked,
|
|
712
|
+
[
|
|
713
|
+
/\b(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*ctx\s*(?:\?\.|\.)\s*element\b/g,
|
|
714
|
+
/(?<![.$\w])([A-Za-z_$][\w$]*)\s*=\s*ctx\s*(?:\?\.|\.)\s*element\b/g
|
|
715
|
+
],
|
|
716
|
+
(match) => {
|
|
717
|
+
const alias = match[1];
|
|
718
|
+
const ctxIndex = (match.index || 0) + match[0].lastIndexOf("ctx");
|
|
719
|
+
if ((0, import_bindings.isNameBoundAtIndex)(bindings, "ctx", ctxIndex)) {
|
|
720
|
+
return;
|
|
721
|
+
}
|
|
722
|
+
entries.push({ alias, index: ctxIndex });
|
|
723
|
+
}
|
|
724
|
+
);
|
|
725
|
+
for (const match of masked.matchAll(/\b(?:const|let|var)\s*\{([^}]*)\}\s*=\s*ctx\b(?!\s*(?:\.|\?\.))/g)) {
|
|
726
|
+
const ctxIndex = (match.index || 0) + match[0].lastIndexOf("ctx");
|
|
727
|
+
if ((0, import_bindings.isNameBoundAtIndex)(bindings, "ctx", ctxIndex)) {
|
|
728
|
+
continue;
|
|
729
|
+
}
|
|
730
|
+
collectObjectBindingAliases(match[1]).filter((alias) => alias === "element").forEach((alias) => {
|
|
731
|
+
entries.push({ alias, index: ctxIndex });
|
|
732
|
+
});
|
|
733
|
+
}
|
|
734
|
+
return dedupeAliasEntries(entries);
|
|
735
|
+
}
|
|
736
|
+
function collectCtxAliases(masked, bindings) {
|
|
737
|
+
const entries = [];
|
|
738
|
+
collectAliasMatches(
|
|
739
|
+
masked,
|
|
740
|
+
[
|
|
741
|
+
/\b(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*ctx\b(?!\s*(?:\.|\?\.))/g,
|
|
742
|
+
/(?<![.$\w])([A-Za-z_$][\w$]*)\s*=\s*ctx\b(?!\s*(?:\.|\?\.))/g
|
|
743
|
+
],
|
|
744
|
+
(match) => {
|
|
745
|
+
const alias = match[1];
|
|
746
|
+
const ctxIndex = (match.index || 0) + match[0].lastIndexOf("ctx");
|
|
747
|
+
if (alias === "ctx" || (0, import_bindings.isNameBoundAtIndex)(bindings, "ctx", ctxIndex)) {
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
750
|
+
entries.push({ alias, index: ctxIndex });
|
|
751
|
+
}
|
|
752
|
+
);
|
|
753
|
+
for (const match of masked.matchAll(/\b(?:const|let|var)\s*\{([^}]*)\}\s*=\s*ctx\b(?!\s*(?:\.|\?\.))/g)) {
|
|
754
|
+
const ctxIndex = (match.index || 0) + match[0].lastIndexOf("ctx");
|
|
755
|
+
if ((0, import_bindings.isNameBoundAtIndex)(bindings, "ctx", ctxIndex)) {
|
|
756
|
+
continue;
|
|
757
|
+
}
|
|
758
|
+
collectObjectBindingAliases(match[1]).forEach((alias) => {
|
|
759
|
+
entries.push({ alias, index: ctxIndex });
|
|
760
|
+
});
|
|
761
|
+
}
|
|
762
|
+
return dedupeAliasEntries(entries);
|
|
763
|
+
}
|
|
764
|
+
function collectAliasMatches(masked, patterns, onMatch) {
|
|
765
|
+
patterns.forEach((pattern) => {
|
|
766
|
+
for (const match of masked.matchAll(pattern)) {
|
|
767
|
+
onMatch(match);
|
|
768
|
+
}
|
|
769
|
+
});
|
|
770
|
+
}
|
|
771
|
+
function dedupeAliasEntries(entries) {
|
|
772
|
+
const seen = /* @__PURE__ */ new Set();
|
|
773
|
+
return entries.filter((entry) => {
|
|
774
|
+
const key = `${entry.alias}:${entry.index}`;
|
|
775
|
+
if (seen.has(key)) {
|
|
776
|
+
return false;
|
|
777
|
+
}
|
|
778
|
+
seen.add(key);
|
|
779
|
+
return true;
|
|
780
|
+
});
|
|
781
|
+
}
|
|
782
|
+
function collectObjectBindingAliases(pattern) {
|
|
783
|
+
return (0, import_source.splitTopLevel)(pattern, ",").flatMap((element) => collectObjectBindingElementAliases(element)).filter(Boolean);
|
|
784
|
+
}
|
|
785
|
+
function collectObjectBindingElementAliases(element) {
|
|
786
|
+
const trimmed = element.trim().replace(/^\.\.\./, "").trim();
|
|
787
|
+
if (!trimmed || trimmed.startsWith("{")) {
|
|
788
|
+
return [];
|
|
789
|
+
}
|
|
790
|
+
const colon = (0, import_source.findTopLevelChar)(trimmed, ":");
|
|
791
|
+
if (colon >= 0) {
|
|
792
|
+
const right = (0, import_source.trimBindingElement)(trimmed.slice(colon + 1));
|
|
793
|
+
const match2 = right.match(/^([A-Za-z_$][\w$]*)\b/);
|
|
794
|
+
return match2 ? [match2[1]] : [];
|
|
795
|
+
}
|
|
796
|
+
const match = trimmed.match(/^([A-Za-z_$][\w$]*)\b/);
|
|
797
|
+
return match ? [match[1]] : [];
|
|
798
|
+
}
|
|
799
|
+
function isDirectDomMember(member) {
|
|
800
|
+
return member === "innerHTML" || member === "insertAdjacentHTML";
|
|
801
|
+
}
|
|
802
|
+
function isCodeTokenAt(masked, index, token) {
|
|
803
|
+
return masked.slice(index, index + token.length) === token;
|
|
804
|
+
}
|
|
805
|
+
function collectCtxMemberAccesses(masked, bindings) {
|
|
806
|
+
return [...masked.matchAll(/\bctx\s*(?:\?\.|\.)\s*([A-Za-z_$][\w$]*)/g)].filter((match) => !(0, import_bindings.isNameBoundAtIndex)(bindings, "ctx", match.index || 0)).map((match) => ({
|
|
807
|
+
member: match[1],
|
|
808
|
+
index: match.index || 0
|
|
809
|
+
}));
|
|
810
|
+
}
|
|
811
|
+
function isTopLevelFunctionWrapper(masked, functionRanges, topLevelCtxRenderCalls) {
|
|
812
|
+
if (topLevelCtxRenderCalls.length || !functionRanges.length) {
|
|
813
|
+
return false;
|
|
814
|
+
}
|
|
815
|
+
return /^\s*(?:async\s+)?function\b/.test(masked) || /^\s*(?:const|let|var)\s+[A-Za-z_$][\w$]*\s*=/.test(masked);
|
|
816
|
+
}
|
|
817
|
+
function isResourceLikeCtxRequest(source, masked, index) {
|
|
818
|
+
const args = (0, import_source.getCallArgumentSource)(source, masked, index);
|
|
819
|
+
if (!args) {
|
|
820
|
+
return false;
|
|
821
|
+
}
|
|
822
|
+
const firstArg = (0, import_source.getCallFirstArgumentSource)(source, masked, index);
|
|
823
|
+
const firstArgLiteral = firstArg ? (0, import_source.readLeadingStringLiteral)(firstArg) : void 0;
|
|
824
|
+
if (firstArgLiteral) {
|
|
825
|
+
return isResourceLikeCtxRequestUrl(firstArgLiteral.value.trim());
|
|
826
|
+
}
|
|
827
|
+
const urlMatch = args.match(/\burl\s*:\s*(['"`])([^'"`]+)\1/i) || args.match(/^\s*(['"`])([^'"`]+)\1\s*$/);
|
|
828
|
+
if (urlMatch) {
|
|
829
|
+
return isResourceLikeCtxRequestUrl(urlMatch[2].trim());
|
|
830
|
+
}
|
|
831
|
+
return /\b(?:resource|collectionName|collection)\s*:/i.test(args);
|
|
832
|
+
}
|
|
833
|
+
function isResourceLikeCtxRequestUrl(url) {
|
|
834
|
+
if (/^(?:https?:)?\/\//i.test(url)) {
|
|
835
|
+
return false;
|
|
836
|
+
}
|
|
837
|
+
const resourceUrl = url.replace(/^\/api\//i, "").replace(/^\//, "");
|
|
838
|
+
return isResourceLikeRequestUrl(resourceUrl);
|
|
839
|
+
}
|
|
840
|
+
function isResourceLikeRequestUrl(url) {
|
|
841
|
+
return /^(?:[A-Za-z_$][\w$.-]*|\$\{[^}]+\}):(?:list|get)(?:\b|[/?#])/i.test(url);
|
|
842
|
+
}
|
|
843
|
+
function getResourceLikeCtxRunjsEntrypoint(source, masked, index) {
|
|
844
|
+
const firstArg = (0, import_source.getCallFirstArgumentSource)(source, masked, index);
|
|
845
|
+
if (!firstArg) {
|
|
846
|
+
return "";
|
|
847
|
+
}
|
|
848
|
+
const literal = (0, import_source.readLeadingStringLiteral)(firstArg);
|
|
849
|
+
if (literal) {
|
|
850
|
+
const endpoint = literal.value.trim();
|
|
851
|
+
return isResourceLikeRunjsEntrypoint(endpoint) ? endpoint : "";
|
|
852
|
+
}
|
|
853
|
+
const expression = firstArg.trim();
|
|
854
|
+
return isResourceLikeRunjsEntrypointExpression(expression) ? expression : "";
|
|
855
|
+
}
|
|
856
|
+
function isResourceLikeRunjsEntrypoint(value) {
|
|
857
|
+
const trimmed = value.trim();
|
|
858
|
+
const action = import_constants.RUNJS_RESOURCE_ACTION_PATTERN;
|
|
859
|
+
return new RegExp(`^(?:resource|collection):${action}(?:$|[/?#])`, "i").test(trimmed) || new RegExp(`^[A-Za-z_$][\\w$.-]*:${action}(?:$|[/?#])`, "i").test(trimmed) || new RegExp(`\\$\\{[^}]+\\}\\s*:${action}(?:$|[/?#])`, "i").test(trimmed);
|
|
860
|
+
}
|
|
861
|
+
function isResourceLikeRunjsEntrypointExpression(value) {
|
|
862
|
+
const withoutComments = (0, import_source.maskJavaScriptComments)(value);
|
|
863
|
+
return new RegExp(`(['"\`])\\s*:${import_constants.RUNJS_RESOURCE_ACTION_PATTERN}\\1`).test(withoutComments);
|
|
864
|
+
}
|
|
865
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
866
|
+
0 && (module.exports = {
|
|
867
|
+
collectCtxAliases,
|
|
868
|
+
collectCtxLibMemberCaseMismatches,
|
|
869
|
+
collectCtxMemberAccesses,
|
|
870
|
+
collectCtxRenderComponentSignatureCalls,
|
|
871
|
+
collectDirectDomAliases,
|
|
872
|
+
collectDirectDomWrites,
|
|
873
|
+
collectFlowResourceAliases,
|
|
874
|
+
collectForbiddenBareGlobals,
|
|
875
|
+
collectInvalidApiResourceCalls,
|
|
876
|
+
collectInvalidFlowResourceListCalls,
|
|
877
|
+
collectInvalidResourceTypeCalls,
|
|
878
|
+
collectReactComponentAliases,
|
|
879
|
+
collectReactComponentFunctionCalls,
|
|
880
|
+
collectReactComponentPropReferences,
|
|
881
|
+
collectReactHookCalls,
|
|
882
|
+
collectResourceCallsInReactHooks,
|
|
883
|
+
collectUnboundReactCreateElementCalls,
|
|
884
|
+
collectWindowDocumentNavigatorAliases,
|
|
885
|
+
collectWindowDocumentNavigatorUses,
|
|
886
|
+
getResourceLikeCtxRunjsEntrypoint,
|
|
887
|
+
isResourceLikeCtxRequest,
|
|
888
|
+
isTopLevelFunctionWrapper
|
|
889
|
+
});
|