@lowdefy/api 6.0.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/context/createEvaluateOperators.js +3 -1
- package/dist/context/getCurrentEnvironment.js +27 -0
- package/dist/index.js +2 -1
- package/dist/response/buildEndpointResult.js +3 -1
- package/dist/response/createWireProjection.js +88 -0
- package/dist/response/normalizeErrorSources.js +10 -13
- package/dist/response/redactErrorResponse.js +42 -8
- package/dist/response/redactResponse.js +10 -10
- package/dist/routes/agent/prepareAgent.js +6 -0
- package/dist/routes/auth/defaultAuthUrl.js +31 -0
- package/dist/routes/auth/getAuthConfig.js +5 -1
- package/dist/routes/endpoints/callEndpoint.js +1 -0
- package/dist/routes/endpoints/control/controlFor.js +4 -7
- package/dist/routes/endpoints/control/controlIf.js +4 -8
- package/dist/routes/endpoints/control/controlLog.js +6 -14
- package/dist/routes/endpoints/control/controlParallelFor.js +4 -7
- package/dist/routes/endpoints/control/controlReject.js +13 -15
- package/dist/routes/endpoints/control/controlReturn.js +4 -9
- package/dist/routes/endpoints/control/controlSetState.js +4 -8
- package/dist/routes/endpoints/control/controlSwitch.js +4 -8
- package/dist/routes/endpoints/control/controlThrow.js +17 -19
- package/dist/routes/endpoints/control/controlTry.js +20 -10
- package/dist/routes/endpoints/evaluateRoutineOperators.js +26 -0
- package/dist/routes/endpoints/forwardScheduledEndpoint.js +19 -14
- package/dist/routes/endpoints/getEnvironmentSchedules.js +5 -7
- package/dist/routes/endpoints/handleAgentCall.js +4 -7
- package/dist/routes/endpoints/handleEndpointCall.js +4 -7
- package/dist/routes/endpoints/handleRenderNotification.js +15 -8
- package/dist/routes/endpoints/handleRequest.js +1 -5
- package/dist/routes/endpoints/handleValidateSchema.js +12 -10
- package/dist/routes/endpoints/invokeEndpoint.js +1 -0
- package/dist/routes/endpoints/operatorScope.js +27 -0
- package/dist/routes/endpoints/resolveCronEnvironment.js +7 -6
- package/dist/routes/endpoints/runDetachedEndpoint.js +1 -0
- package/dist/routes/endpoints/runScheduledEndpoint.js +1 -0
- package/dist/routes/endpoints/runWebhookEndpoint.js +1 -0
- package/dist/routes/endpoints/test/runTest.js +17 -2
- package/dist/routes/mcp/createMcpServer.js +20 -2
- package/dist/routes/request/callRequest.js +9 -3
- package/dist/routes/request/callRequestResolver.js +6 -0
- package/dist/routes/request/evaluateOperators.js +8 -12
- package/dist/routes/websocket/createChannelRegistry.js +19 -5
- package/dist/routes/websocket/createWebSocketConnection.js +15 -3
- package/dist/test/testContext.js +4 -2
- package/package.json +9 -9
- package/dist/response/omitErrorProps.js +0 -51
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
See the License for the specific language governing permissions and
|
|
14
14
|
limitations under the License.
|
|
15
15
|
*/ import { type } from '@lowdefy/helpers';
|
|
16
|
+
import redactErrorResponse from '../../response/redactErrorResponse.js';
|
|
16
17
|
// Wraps one client websocket connection: parses frames, dispatches
|
|
17
18
|
// subscribe/unsubscribe/publish to the channel registry, and answers every
|
|
18
19
|
// frame with an ack or an error so client actions never hang.
|
|
@@ -21,7 +22,10 @@ function createWebSocketConnection(context, { registry, send }) {
|
|
|
21
22
|
const subscriber = {
|
|
22
23
|
id: context.rid,
|
|
23
24
|
subscriptions: new Map(),
|
|
24
|
-
send
|
|
25
|
+
send,
|
|
26
|
+
// A shared channel broadcasts to every subscriber, so each one carries its
|
|
27
|
+
// own locale for the error message it is sent.
|
|
28
|
+
i18n: context.i18n
|
|
25
29
|
};
|
|
26
30
|
function sendError({ message, requestId, websocketId }) {
|
|
27
31
|
send(JSON.stringify({
|
|
@@ -31,6 +35,14 @@ function createWebSocketConnection(context, { registry, send }) {
|
|
|
31
35
|
message
|
|
32
36
|
}));
|
|
33
37
|
}
|
|
38
|
+
function sendErrorPayload({ error, requestId, websocketId }) {
|
|
39
|
+
send(JSON.stringify({
|
|
40
|
+
type: 'error',
|
|
41
|
+
websocketId,
|
|
42
|
+
requestId,
|
|
43
|
+
error: redactErrorResponse(context, error)
|
|
44
|
+
}));
|
|
45
|
+
}
|
|
34
46
|
async function handleFrame(frame) {
|
|
35
47
|
const { payload, requestId, websocketId } = frame;
|
|
36
48
|
if (!type.isString(websocketId)) {
|
|
@@ -104,8 +116,8 @@ function createWebSocketConnection(context, { registry, send }) {
|
|
|
104
116
|
err: error
|
|
105
117
|
}, error.message);
|
|
106
118
|
context.handleError(error);
|
|
107
|
-
|
|
108
|
-
|
|
119
|
+
sendErrorPayload({
|
|
120
|
+
error,
|
|
109
121
|
requestId: frame.requestId,
|
|
110
122
|
websocketId: frame.websocketId
|
|
111
123
|
});
|
package/dist/test/testContext.js
CHANGED
|
@@ -18,9 +18,9 @@ function testContext({ appMeta = {}, config = {}, configDirectory, connections =
|
|
|
18
18
|
error: ()=>{},
|
|
19
19
|
info: ()=>{},
|
|
20
20
|
warn: ()=>{}
|
|
21
|
-
}, operators = {
|
|
21
|
+
}, mode = 'prod', operators = {
|
|
22
22
|
_test: ()=>'test'
|
|
23
|
-
}, readConfigFile, secrets = {}, session, system } = {}) {
|
|
23
|
+
}, readConfigFile, scrubSecrets = (value)=>value, secrets = {}, session, system } = {}) {
|
|
24
24
|
return {
|
|
25
25
|
appMeta,
|
|
26
26
|
authorize: createAuthorize({
|
|
@@ -39,8 +39,10 @@ function testContext({ appMeta = {}, config = {}, configDirectory, connections =
|
|
|
39
39
|
},
|
|
40
40
|
headers,
|
|
41
41
|
logger,
|
|
42
|
+
mode,
|
|
42
43
|
operators,
|
|
43
44
|
readConfigFile,
|
|
45
|
+
scrubSecrets,
|
|
44
46
|
secrets,
|
|
45
47
|
session,
|
|
46
48
|
steps: {},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lowdefy/api",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.1.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "",
|
|
6
6
|
"homepage": "https://lowdefy.com",
|
|
@@ -34,14 +34,14 @@
|
|
|
34
34
|
"dist/*"
|
|
35
35
|
],
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@lowdefy/ajv": "6.
|
|
38
|
-
"@lowdefy/build": "6.
|
|
39
|
-
"@lowdefy/errors": "6.
|
|
40
|
-
"@lowdefy/helpers": "6.
|
|
41
|
-
"@lowdefy/node-utils": "6.
|
|
42
|
-
"@lowdefy/nunjucks": "6.
|
|
43
|
-
"@lowdefy/operators": "6.
|
|
44
|
-
"@lowdefy/operators-js": "6.
|
|
37
|
+
"@lowdefy/ajv": "6.1.0",
|
|
38
|
+
"@lowdefy/build": "6.1.0",
|
|
39
|
+
"@lowdefy/errors": "6.1.0",
|
|
40
|
+
"@lowdefy/helpers": "6.1.0",
|
|
41
|
+
"@lowdefy/node-utils": "6.1.0",
|
|
42
|
+
"@lowdefy/nunjucks": "6.1.0",
|
|
43
|
+
"@lowdefy/operators": "6.1.0",
|
|
44
|
+
"@lowdefy/operators-js": "6.1.0",
|
|
45
45
|
"@modelcontextprotocol/sdk": "1.29.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
-
|
|
4
|
-
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
you may not use this file except in compliance with the License.
|
|
6
|
-
You may obtain a copy of the License at
|
|
7
|
-
|
|
8
|
-
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
|
|
10
|
-
Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
See the License for the specific language governing permissions and
|
|
14
|
-
limitations under the License.
|
|
15
|
-
*/ import { UserError } from '@lowdefy/errors';
|
|
16
|
-
import { type } from '@lowdefy/helpers';
|
|
17
|
-
// The client-bound error policy: which fields of an error may cross the wire.
|
|
18
|
-
// Passed to serializer.serialize as `omitErrorProps`, so extractErrorProps applies
|
|
19
|
-
// it at EVERY error node the walk emits - the cause chain, an Error-valued own
|
|
20
|
-
// property, and an Error nested inside a plain object or array. The policy is
|
|
21
|
-
// stated against the emitter rather than against a response shape, so it cannot
|
|
22
|
-
// become depth-limited.
|
|
23
|
-
//
|
|
24
|
-
// `received` is not merely "may be sensitive": on the request path
|
|
25
|
-
// callRequestResolver sets it to the EVALUATED request properties, so a _secret
|
|
26
|
-
// resolved into a request header is in it. `stack` exposes server internals,
|
|
27
|
-
// including absolute node_modules paths. Both are unbounded runtime data nobody
|
|
28
|
-
// chose, in every environment - the full value stays in the server log, which is
|
|
29
|
-
// where a developer on their own machine reads it.
|
|
30
|
-
const ALWAYS_OMITTED = [
|
|
31
|
-
'received',
|
|
32
|
-
'stack'
|
|
33
|
-
];
|
|
34
|
-
const OMITTED_WITH_CAUSE = [
|
|
35
|
-
...ALWAYS_OMITTED,
|
|
36
|
-
'cause'
|
|
37
|
-
];
|
|
38
|
-
function omitErrorProps(error) {
|
|
39
|
-
// An Error cause is the trace the browser renders (name + message per level),
|
|
40
|
-
// so it is always kept - fields are taken from causes, causes are never pruned.
|
|
41
|
-
// A non-Error cause is internal server config: the whole endpoint routine, a
|
|
42
|
-
// control node, ajv errors. UserError is the exception, the one class whose
|
|
43
|
-
// payload the author wrote for the client.
|
|
44
|
-
//
|
|
45
|
-
// type.isError is `instanceof Error`, the same test extractErrorProps uses to
|
|
46
|
-
// decide which branch emits the cause - the two must agree.
|
|
47
|
-
if (type.isError(error.cause)) return ALWAYS_OMITTED;
|
|
48
|
-
if (error instanceof UserError) return ALWAYS_OMITTED;
|
|
49
|
-
return OMITTED_WITH_CAUSE;
|
|
50
|
-
}
|
|
51
|
-
export default omitErrorProps;
|