@lowdefy/api 4.4.0 → 4.5.1
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/LICENSE +183 -183
- package/dist/context/createApiContext.js +4 -2
- package/dist/context/createEvaluateOperators.js +26 -0
- package/dist/index.js +3 -2
- package/dist/routes/endpoints/addStepResult.js +23 -0
- package/dist/routes/endpoints/authorizeApiEndpoint.js +31 -0
- package/dist/routes/endpoints/callEndpoint.js +58 -0
- package/dist/routes/endpoints/control/controlFor.js +68 -0
- package/dist/routes/endpoints/control/controlIf.js +53 -0
- package/dist/routes/endpoints/control/controlLog.js +43 -0
- package/dist/routes/endpoints/control/controlParallel.js +44 -0
- package/dist/routes/endpoints/control/controlParallelFor.js +76 -0
- package/dist/routes/endpoints/control/controlReject.js +40 -0
- package/dist/routes/endpoints/control/controlReturn.js +32 -0
- package/dist/routes/endpoints/control/controlSetState.js +22 -0
- package/dist/routes/endpoints/control/controlSwitch.js +60 -0
- package/dist/routes/endpoints/control/controlThrow.js +40 -0
- package/dist/routes/endpoints/control/controlTry.js +46 -0
- package/dist/routes/endpoints/control/handleControl.js +51 -0
- package/dist/routes/endpoints/getEndpointConfig.js +30 -0
- package/dist/routes/endpoints/handleRequest.js +85 -0
- package/dist/routes/endpoints/runRoutine.js +60 -0
- package/dist/routes/endpoints/test/runTest.js +107 -0
- package/dist/routes/request/callRequest.js +5 -4
- package/dist/routes/request/callRequestResolver.js +3 -2
- package/dist/routes/request/evaluateOperators.js +4 -18
- package/dist/test/testContext.js +4 -1
- package/package.json +7 -7
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2024 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 { type } from '@lowdefy/helpers';
|
|
16
|
+
import handleRequest from './handleRequest.js';
|
|
17
|
+
import handleControl from './control/handleControl.js';
|
|
18
|
+
async function runRoutine(context, routineContext, { routine }) {
|
|
19
|
+
try {
|
|
20
|
+
if (type.isObject(routine)) {
|
|
21
|
+
if (routine.id?.startsWith?.('request:')) {
|
|
22
|
+
return await handleRequest(context, routineContext, {
|
|
23
|
+
request: routine
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
return await handleControl(context, routineContext, {
|
|
27
|
+
control: routine
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
if (type.isArray(routine)) {
|
|
31
|
+
for (const item of routine){
|
|
32
|
+
const res = await runRoutine(context, routineContext, {
|
|
33
|
+
routine: item
|
|
34
|
+
});
|
|
35
|
+
if ([
|
|
36
|
+
'return',
|
|
37
|
+
'error',
|
|
38
|
+
'reject'
|
|
39
|
+
].includes(res.status)) {
|
|
40
|
+
return res;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
status: 'continue'
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
throw new Error('Invalid routine.', {
|
|
48
|
+
cause: {
|
|
49
|
+
routine
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
} catch (error) {
|
|
53
|
+
context.logger.error(error);
|
|
54
|
+
return {
|
|
55
|
+
status: 'error',
|
|
56
|
+
error
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
export default runRoutine;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { jest } from '@jest/globals';
|
|
2
|
+
import { wait } from '@lowdefy/helpers';
|
|
3
|
+
import { operatorsServer } from '@lowdefy/operators-js';
|
|
4
|
+
import createEvaluateOperators from '../../../context/createEvaluateOperators.js';
|
|
5
|
+
import runRoutine from '../runRoutine.js';
|
|
6
|
+
import testContext from '../../../test/testContext.js';
|
|
7
|
+
// const { _date, _eq, _payload, _secret, _user } = operatorsServer;
|
|
8
|
+
const operators = {
|
|
9
|
+
...operatorsServer,
|
|
10
|
+
_error: ()=>{
|
|
11
|
+
throw new Error('Test error.');
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
const secrets = {
|
|
15
|
+
CONNECTION: 'connectionSecret',
|
|
16
|
+
REQUEST: 'requestSecret'
|
|
17
|
+
};
|
|
18
|
+
const defaultReadConfigImp = ({ connectionConfig = {
|
|
19
|
+
id: 'connection:test',
|
|
20
|
+
type: 'TestConnection',
|
|
21
|
+
connectionId: 'test'
|
|
22
|
+
} } = {})=>(path)=>{
|
|
23
|
+
if (path === 'connections/test.json') {
|
|
24
|
+
return connectionConfig;
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
27
|
+
};
|
|
28
|
+
const mockReadConfigFile = jest.fn().mockImplementation(defaultReadConfigImp());
|
|
29
|
+
const mockTestRequest = jest.fn((request)=>{
|
|
30
|
+
return request.request.response;
|
|
31
|
+
});
|
|
32
|
+
const mockTestRequestError = jest.fn((request)=>{
|
|
33
|
+
throw new Error(request.request.message);
|
|
34
|
+
});
|
|
35
|
+
const mockTestRequestWait = jest.fn((request)=>wait(request.request.ms));
|
|
36
|
+
mockTestRequest.schema = {};
|
|
37
|
+
mockTestRequestError.schema = {};
|
|
38
|
+
mockTestRequestWait.schema = {};
|
|
39
|
+
mockTestRequest.meta = {
|
|
40
|
+
checkRead: false,
|
|
41
|
+
checkWrite: false
|
|
42
|
+
};
|
|
43
|
+
mockTestRequestError.meta = {
|
|
44
|
+
checkRead: false,
|
|
45
|
+
checkWrite: false
|
|
46
|
+
};
|
|
47
|
+
mockTestRequestWait.meta = {
|
|
48
|
+
checkRead: false,
|
|
49
|
+
checkWrite: false
|
|
50
|
+
};
|
|
51
|
+
const connections = {
|
|
52
|
+
TestConnection: {
|
|
53
|
+
schema: {},
|
|
54
|
+
requests: {
|
|
55
|
+
TestRequest: mockTestRequest,
|
|
56
|
+
TestRequestError: mockTestRequestError,
|
|
57
|
+
TestRequestWait: mockTestRequestWait
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
const logger = {
|
|
62
|
+
debug: jest.fn(),
|
|
63
|
+
info: jest.fn(),
|
|
64
|
+
warn: jest.fn(),
|
|
65
|
+
// error: console.error,
|
|
66
|
+
error: jest.fn()
|
|
67
|
+
};
|
|
68
|
+
function createTextContext({ payload }) {
|
|
69
|
+
const context = testContext({
|
|
70
|
+
connections,
|
|
71
|
+
operators,
|
|
72
|
+
logger,
|
|
73
|
+
readConfigFile: mockReadConfigFile,
|
|
74
|
+
secrets,
|
|
75
|
+
session: {
|
|
76
|
+
user: {
|
|
77
|
+
id: 'id'
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
context.payload = payload;
|
|
82
|
+
context.steps = {};
|
|
83
|
+
context.blockId = 'blockId';
|
|
84
|
+
context.pageId = 'pageId';
|
|
85
|
+
context.endpointId = 'endpointId';
|
|
86
|
+
context.evaluateOperators = createEvaluateOperators(context, {
|
|
87
|
+
payload
|
|
88
|
+
});
|
|
89
|
+
return context;
|
|
90
|
+
}
|
|
91
|
+
async function runTest({ routine, payload = {} }) {
|
|
92
|
+
const context = createTextContext({
|
|
93
|
+
payload
|
|
94
|
+
});
|
|
95
|
+
const routineContext = {
|
|
96
|
+
items: {},
|
|
97
|
+
arrayIndices: []
|
|
98
|
+
};
|
|
99
|
+
const res = await runRoutine(context, routineContext, {
|
|
100
|
+
routine
|
|
101
|
+
});
|
|
102
|
+
return {
|
|
103
|
+
res,
|
|
104
|
+
context
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
export default runTest;
|
|
@@ -23,8 +23,13 @@ import getConnectionConfig from './getConnectionConfig.js';
|
|
|
23
23
|
import getRequestConfig from './getRequestConfig.js';
|
|
24
24
|
import getRequestResolver from './getRequestResolver.js';
|
|
25
25
|
import validateSchemas from './validateSchemas.js';
|
|
26
|
+
import createEvaluateOperators from '../../context/createEvaluateOperators.js';
|
|
26
27
|
async function callRequest(context, { blockId, pageId, payload, requestId }) {
|
|
27
28
|
const { logger } = context;
|
|
29
|
+
context.blockId = blockId;
|
|
30
|
+
context.pageId = pageId;
|
|
31
|
+
context.payload = serializer.deserialize(payload);
|
|
32
|
+
context.evaluateOperators = createEvaluateOperators(context);
|
|
28
33
|
logger.debug({
|
|
29
34
|
event: 'debug_request',
|
|
30
35
|
blockId,
|
|
@@ -49,10 +54,8 @@ async function callRequest(context, { blockId, pageId, payload, requestId }) {
|
|
|
49
54
|
connection,
|
|
50
55
|
requestConfig
|
|
51
56
|
});
|
|
52
|
-
const deserializedPayload = serializer.deserialize(payload);
|
|
53
57
|
const { connectionProperties, requestProperties } = evaluateOperators(context, {
|
|
54
58
|
connectionConfig,
|
|
55
|
-
payload: deserializedPayload,
|
|
56
59
|
requestConfig
|
|
57
60
|
});
|
|
58
61
|
checkConnectionRead(context, {
|
|
@@ -75,9 +78,7 @@ async function callRequest(context, { blockId, pageId, payload, requestId }) {
|
|
|
75
78
|
requestProperties
|
|
76
79
|
});
|
|
77
80
|
const response = await callRequestResolver(context, {
|
|
78
|
-
blockId,
|
|
79
81
|
connectionProperties,
|
|
80
|
-
payload: deserializedPayload,
|
|
81
82
|
requestConfig,
|
|
82
83
|
requestProperties,
|
|
83
84
|
requestResolver
|
|
@@ -13,13 +13,14 @@
|
|
|
13
13
|
See the License for the specific language governing permissions and
|
|
14
14
|
limitations under the License.
|
|
15
15
|
*/ import { RequestError } from '../../context/errors.js';
|
|
16
|
-
async function callRequestResolver({ logger }, {
|
|
16
|
+
async function callRequestResolver({ blockId, endpointId, logger, pageId, payload }, { connectionProperties, requestConfig, requestProperties, requestResolver }) {
|
|
17
17
|
try {
|
|
18
18
|
const response = await requestResolver({
|
|
19
19
|
blockId,
|
|
20
|
+
endpointId,
|
|
20
21
|
connection: connectionProperties,
|
|
21
22
|
connectionId: requestConfig.connectionId,
|
|
22
|
-
pageId
|
|
23
|
+
pageId,
|
|
23
24
|
payload,
|
|
24
25
|
request: requestProperties,
|
|
25
26
|
requestId: requestConfig.requestId
|
|
@@ -12,30 +12,16 @@
|
|
|
12
12
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
13
|
See the License for the specific language governing permissions and
|
|
14
14
|
limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
function evaluateOperators({ jsMap, operators, secrets, session }, { connectionConfig, payload, requestConfig }) {
|
|
18
|
-
const operatorsParser = new ServerParser({
|
|
19
|
-
jsMap,
|
|
20
|
-
operators,
|
|
21
|
-
payload,
|
|
22
|
-
secrets,
|
|
23
|
-
user: session?.user
|
|
24
|
-
});
|
|
25
|
-
const { output: connectionProperties, errors: connectionErrors } = operatorsParser.parse({
|
|
15
|
+
*/ function evaluateOperators({ evaluateOperators }, { connectionConfig, items, requestConfig }) {
|
|
16
|
+
const connectionProperties = evaluateOperators({
|
|
26
17
|
input: connectionConfig.properties || {},
|
|
27
18
|
location: connectionConfig.connectionId
|
|
28
19
|
});
|
|
29
|
-
|
|
30
|
-
throw new RequestError(connectionErrors[0]);
|
|
31
|
-
}
|
|
32
|
-
const { output: requestProperties, errors: requestErrors } = operatorsParser.parse({
|
|
20
|
+
const requestProperties = evaluateOperators({
|
|
33
21
|
input: requestConfig.properties || {},
|
|
22
|
+
items,
|
|
34
23
|
location: requestConfig.requestId
|
|
35
24
|
});
|
|
36
|
-
if (requestErrors.length > 0) {
|
|
37
|
-
throw new RequestError(requestErrors[0]);
|
|
38
|
-
}
|
|
39
25
|
return {
|
|
40
26
|
connectionProperties,
|
|
41
27
|
requestProperties
|
package/dist/test/testContext.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lowdefy/api",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.5.1",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "",
|
|
6
6
|
"homepage": "https://lowdefy.com",
|
|
@@ -34,12 +34,12 @@
|
|
|
34
34
|
"dist/*"
|
|
35
35
|
],
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@lowdefy/ajv": "4.
|
|
38
|
-
"@lowdefy/helpers": "4.
|
|
39
|
-
"@lowdefy/node-utils": "4.
|
|
40
|
-
"@lowdefy/nunjucks": "4.
|
|
41
|
-
"@lowdefy/operators": "4.
|
|
42
|
-
"@lowdefy/operators-js": "4.
|
|
37
|
+
"@lowdefy/ajv": "4.5.1",
|
|
38
|
+
"@lowdefy/helpers": "4.5.1",
|
|
39
|
+
"@lowdefy/node-utils": "4.5.1",
|
|
40
|
+
"@lowdefy/nunjucks": "4.5.1",
|
|
41
|
+
"@lowdefy/operators": "4.5.1",
|
|
42
|
+
"@lowdefy/operators-js": "4.5.1"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@jest/globals": "28.1.3",
|