@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.
Files changed (28) hide show
  1. package/LICENSE +183 -183
  2. package/dist/context/createApiContext.js +4 -2
  3. package/dist/context/createEvaluateOperators.js +26 -0
  4. package/dist/index.js +3 -2
  5. package/dist/routes/endpoints/addStepResult.js +23 -0
  6. package/dist/routes/endpoints/authorizeApiEndpoint.js +31 -0
  7. package/dist/routes/endpoints/callEndpoint.js +58 -0
  8. package/dist/routes/endpoints/control/controlFor.js +68 -0
  9. package/dist/routes/endpoints/control/controlIf.js +53 -0
  10. package/dist/routes/endpoints/control/controlLog.js +43 -0
  11. package/dist/routes/endpoints/control/controlParallel.js +44 -0
  12. package/dist/routes/endpoints/control/controlParallelFor.js +76 -0
  13. package/dist/routes/endpoints/control/controlReject.js +40 -0
  14. package/dist/routes/endpoints/control/controlReturn.js +32 -0
  15. package/dist/routes/endpoints/control/controlSetState.js +22 -0
  16. package/dist/routes/endpoints/control/controlSwitch.js +60 -0
  17. package/dist/routes/endpoints/control/controlThrow.js +40 -0
  18. package/dist/routes/endpoints/control/controlTry.js +46 -0
  19. package/dist/routes/endpoints/control/handleControl.js +51 -0
  20. package/dist/routes/endpoints/getEndpointConfig.js +30 -0
  21. package/dist/routes/endpoints/handleRequest.js +85 -0
  22. package/dist/routes/endpoints/runRoutine.js +60 -0
  23. package/dist/routes/endpoints/test/runTest.js +107 -0
  24. package/dist/routes/request/callRequest.js +5 -4
  25. package/dist/routes/request/callRequestResolver.js +3 -2
  26. package/dist/routes/request/evaluateOperators.js +4 -18
  27. package/dist/test/testContext.js +4 -1
  28. 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 }, { blockId, connectionProperties, payload, requestConfig, requestProperties, requestResolver }) {
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: requestConfig.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
- */ import { ServerParser } from '@lowdefy/operators';
16
- import { RequestError } from '../../context/errors.js';
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
- if (connectionErrors.length > 0) {
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
@@ -32,7 +32,10 @@ function testContext({ config = {}, connections = {}, headers = {}, logger = {
32
32
  operators,
33
33
  readConfigFile,
34
34
  secrets,
35
- session
35
+ session,
36
+ state: {},
37
+ steps: {},
38
+ user: session?.user
36
39
  };
37
40
  }
38
41
  export default testContext;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lowdefy/api",
3
- "version": "4.4.0",
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.4.0",
38
- "@lowdefy/helpers": "4.4.0",
39
- "@lowdefy/node-utils": "4.4.0",
40
- "@lowdefy/nunjucks": "4.4.0",
41
- "@lowdefy/operators": "4.4.0",
42
- "@lowdefy/operators-js": "4.4.0"
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",