@lowdefy/operators 5.6.0 → 6.1.0
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/evaluateOperators.js +30 -5
- package/dist/serverParser.js +18 -3
- package/dist/webParser.js +17 -3
- package/package.json +5 -5
|
@@ -45,7 +45,14 @@ function hasDynamicMarker(value) {
|
|
|
45
45
|
if ((type.isArray(value) || type.isObject(value)) && value['~dyn'] === true) return true;
|
|
46
46
|
return hasDynChild(value);
|
|
47
47
|
}
|
|
48
|
-
|
|
48
|
+
// Build-time prefixes are '_build.' and its escaped forms ('__build.', '___build.', …)
|
|
49
|
+
// produced when _function re-parses its body with `_${operatorPrefix}`. Runtime
|
|
50
|
+
// prefixes ('_', '__', '___', …) never match. Escape depth does not change the
|
|
51
|
+
// evaluation mode: any build prefix means the author asked for build-time evaluation.
|
|
52
|
+
function isBuildPrefix(operatorPrefix) {
|
|
53
|
+
return /^_+build\.$/.test(operatorPrefix);
|
|
54
|
+
}
|
|
55
|
+
function evaluateOperators({ input, operators, operatorPrefix = '_', env, lowdefyApp, dynamicIdentifiers, typeNames, args }) {
|
|
49
56
|
if (type.isUndefined(input)) {
|
|
50
57
|
return {
|
|
51
58
|
output: input,
|
|
@@ -57,6 +64,7 @@ function evaluateOperators({ input, operators, operatorPrefix = '_', env, dynami
|
|
|
57
64
|
}
|
|
58
65
|
const resolvedDynamicIdentifiers = dynamicIdentifiers ?? new Set();
|
|
59
66
|
const resolvedTypeNames = typeNames ?? new Set();
|
|
67
|
+
const isBuildTimePrefix = isBuildPrefix(operatorPrefix);
|
|
60
68
|
const errors = [];
|
|
61
69
|
const parser = {
|
|
62
70
|
parse: ({ args: callArgs, input: callInput, operatorPrefix: callPrefix })=>evaluateOperators({
|
|
@@ -64,6 +72,7 @@ function evaluateOperators({ input, operators, operatorPrefix = '_', env, dynami
|
|
|
64
72
|
operators,
|
|
65
73
|
operatorPrefix: callPrefix ?? operatorPrefix,
|
|
66
74
|
env,
|
|
75
|
+
lowdefyApp,
|
|
67
76
|
dynamicIdentifiers: resolvedDynamicIdentifiers,
|
|
68
77
|
typeNames: resolvedTypeNames,
|
|
69
78
|
args: callArgs
|
|
@@ -100,7 +109,7 @@ function evaluateOperators({ input, operators, operatorPrefix = '_', env, dynami
|
|
|
100
109
|
}
|
|
101
110
|
// Bubble up ~dyn from children (but not at type boundaries).
|
|
102
111
|
// _build.* operators always evaluate even with dynamic params, so skip bubble-up for them.
|
|
103
|
-
const isBuildOperator = isOperatorObject &&
|
|
112
|
+
const isBuildOperator = isOperatorObject && isBuildTimePrefix;
|
|
104
113
|
if (!isTypeBoundary && !isBuildOperator && hasDynamicMarker(node)) {
|
|
105
114
|
return setDynamicMarker(node);
|
|
106
115
|
}
|
|
@@ -111,17 +120,32 @@ function evaluateOperators({ input, operators, operatorPrefix = '_', env, dynami
|
|
|
111
120
|
const [op, methodName] = `_${key.substring(operatorPrefix.length)}`.split('.');
|
|
112
121
|
// Dynamic identifier check — skip for _build.* operators
|
|
113
122
|
const fullIdentifier = methodName ? `${op}.${methodName}` : op;
|
|
114
|
-
if (
|
|
123
|
+
if (!isBuildTimePrefix) {
|
|
115
124
|
if (resolvedDynamicIdentifiers.has(fullIdentifier) || resolvedDynamicIdentifiers.has(op)) {
|
|
116
125
|
return setDynamicMarker(node);
|
|
117
126
|
}
|
|
118
127
|
}
|
|
119
|
-
// Unknown operator
|
|
128
|
+
// Unknown operator. Under a runtime prefix an operator may be runtime-only,
|
|
129
|
+
// so it is deferred by marking it dynamic. Under a build prefix (at any escape
|
|
130
|
+
// depth) the author asked for build-time evaluation, so an unknown operator
|
|
131
|
+
// (typo, or a runtime-only operator misused at build time) is a config error.
|
|
120
132
|
if (type.isUndefined(operators[op])) {
|
|
133
|
+
if (isBuildTimePrefix) {
|
|
134
|
+
const error = new ConfigError(`Operator "${key}" is not a valid _build operator.`, {
|
|
135
|
+
configKey: node['~k'],
|
|
136
|
+
received: {
|
|
137
|
+
[key]: node[key]
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
error.lineNumber = node['~l'];
|
|
141
|
+
error.refId = node['~r'];
|
|
142
|
+
errors.push(error);
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
121
145
|
return setDynamicMarker(node);
|
|
122
146
|
}
|
|
123
147
|
// Dynamic params check — skip for _build.* operators (they always evaluate)
|
|
124
|
-
if (
|
|
148
|
+
if (!isBuildTimePrefix) {
|
|
125
149
|
if (hasDynamicMarker(node[key])) {
|
|
126
150
|
return setDynamicMarker(node);
|
|
127
151
|
}
|
|
@@ -135,6 +159,7 @@ function evaluateOperators({ input, operators, operatorPrefix = '_', env, dynami
|
|
|
135
159
|
args,
|
|
136
160
|
arrayIndices: [],
|
|
137
161
|
env,
|
|
162
|
+
lowdefyApp,
|
|
138
163
|
methodName,
|
|
139
164
|
operators,
|
|
140
165
|
params,
|
package/dist/serverParser.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/ import { ConfigError, OperatorError } from '@lowdefy/errors';
|
|
16
16
|
import { serializer, type } from '@lowdefy/helpers';
|
|
17
17
|
let ServerParser = class ServerParser {
|
|
18
|
-
parse({ args, input, items, location, operatorPrefix = '_', payload, state, steps }) {
|
|
18
|
+
parse({ args, arrayIndices = [], error, input, items, location, operatorPrefix = '_', payload, state, steps }) {
|
|
19
19
|
if (type.isUndefined(input)) {
|
|
20
20
|
return {
|
|
21
21
|
output: input,
|
|
@@ -29,6 +29,20 @@ let ServerParser = class ServerParser {
|
|
|
29
29
|
throw new Error('Operator parser location must be a string.');
|
|
30
30
|
}
|
|
31
31
|
const errors = [];
|
|
32
|
+
// Operators that evaluate nested config (_function) re-enter the parser. Binding the frame here
|
|
33
|
+
// means they only pass what they change, so no frame field can be dropped on the way in.
|
|
34
|
+
const parser = {
|
|
35
|
+
parse: (callOptions)=>this.parse({
|
|
36
|
+
arrayIndices,
|
|
37
|
+
error,
|
|
38
|
+
items,
|
|
39
|
+
location,
|
|
40
|
+
payload,
|
|
41
|
+
state,
|
|
42
|
+
steps,
|
|
43
|
+
...callOptions
|
|
44
|
+
})
|
|
45
|
+
};
|
|
32
46
|
const reviver = (_, value)=>{
|
|
33
47
|
if (!type.isObject(value)) return value;
|
|
34
48
|
if (Object.keys(value).length !== 1) return value;
|
|
@@ -41,8 +55,9 @@ let ServerParser = class ServerParser {
|
|
|
41
55
|
try {
|
|
42
56
|
const res = this.operators[op]({
|
|
43
57
|
args,
|
|
44
|
-
arrayIndices
|
|
58
|
+
arrayIndices,
|
|
45
59
|
env: this.env,
|
|
60
|
+
error,
|
|
46
61
|
i18n: this.i18n,
|
|
47
62
|
items,
|
|
48
63
|
jsMap: this.jsMap,
|
|
@@ -52,7 +67,7 @@ let ServerParser = class ServerParser {
|
|
|
52
67
|
operatorPrefix,
|
|
53
68
|
operators: this.operators,
|
|
54
69
|
params,
|
|
55
|
-
parser
|
|
70
|
+
parser,
|
|
56
71
|
payload,
|
|
57
72
|
runtime: 'node',
|
|
58
73
|
secrets: this.secrets,
|
package/dist/webParser.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/ import { ConfigError, OperatorError } from '@lowdefy/errors';
|
|
16
16
|
import { applyArrayIndices, serializer, type } from '@lowdefy/helpers';
|
|
17
17
|
let WebParser = class WebParser {
|
|
18
|
-
parse({ actions, args, arrayIndices, event, input, location, operatorPrefix = '_' }) {
|
|
18
|
+
parse({ actions, args, arrayIndices, error, event, input, location, operatorPrefix = '_' }) {
|
|
19
19
|
if (type.isUndefined(input)) {
|
|
20
20
|
return {
|
|
21
21
|
output: input,
|
|
@@ -32,6 +32,18 @@ let WebParser = class WebParser {
|
|
|
32
32
|
throw new Error('Operator parser location must be a string.');
|
|
33
33
|
}
|
|
34
34
|
const errors = [];
|
|
35
|
+
// Operators that evaluate nested config (_function) re-enter the parser. Binding the frame here
|
|
36
|
+
// means they only pass what they change, so no frame field can be dropped on the way in.
|
|
37
|
+
const parser = {
|
|
38
|
+
parse: (callOptions)=>this.parse({
|
|
39
|
+
actions,
|
|
40
|
+
arrayIndices,
|
|
41
|
+
error,
|
|
42
|
+
event,
|
|
43
|
+
location,
|
|
44
|
+
...callOptions
|
|
45
|
+
})
|
|
46
|
+
};
|
|
35
47
|
const { apiResponses, basePath, home, i18n, inputs, lowdefyApp, lowdefyGlobal, menus, pageId, theme, user, _internal } = this.context._internal.lowdefy;
|
|
36
48
|
const reviver = (_, value)=>{
|
|
37
49
|
if (!type.isObject(value)) return value;
|
|
@@ -50,6 +62,7 @@ let WebParser = class WebParser {
|
|
|
50
62
|
arrayIndices,
|
|
51
63
|
apiResponses,
|
|
52
64
|
basePath,
|
|
65
|
+
error,
|
|
53
66
|
event,
|
|
54
67
|
eventLog: this.context.eventLog,
|
|
55
68
|
globals: _internal.globals,
|
|
@@ -66,12 +79,13 @@ let WebParser = class WebParser {
|
|
|
66
79
|
operators: this.operators,
|
|
67
80
|
pageId,
|
|
68
81
|
params,
|
|
69
|
-
parser
|
|
82
|
+
parser,
|
|
70
83
|
requests: this.context.requests,
|
|
71
84
|
runtime: 'browser',
|
|
72
85
|
state: this.context.state,
|
|
73
86
|
theme,
|
|
74
|
-
user
|
|
87
|
+
user,
|
|
88
|
+
websockets: this.context.websockets
|
|
75
89
|
});
|
|
76
90
|
return res;
|
|
77
91
|
} catch (e) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lowdefy/operators",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.1.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "",
|
|
6
6
|
"homepage": "https://lowdefy.com",
|
|
@@ -34,13 +34,13 @@
|
|
|
34
34
|
"dist/*"
|
|
35
35
|
],
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@lowdefy/errors": "
|
|
38
|
-
"@lowdefy/helpers": "
|
|
37
|
+
"@lowdefy/errors": "6.1.0",
|
|
38
|
+
"@lowdefy/helpers": "6.1.0"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@jest/globals": "28.1.3",
|
|
42
|
-
"@swc/cli": "0.8.
|
|
43
|
-
"@swc/core": "1.15.
|
|
42
|
+
"@swc/cli": "0.8.1",
|
|
43
|
+
"@swc/core": "1.15.32",
|
|
44
44
|
"@swc/jest": "0.2.39",
|
|
45
45
|
"jest": "28.1.3",
|
|
46
46
|
"jest-environment-jsdom": "28.1.3"
|