mirror of
https://github.com/lowdefy/lowdefy.git
synced 2025-02-11 14:20:07 +08:00
fix(operators): Allow get from object to take an integer argument.
This commit is contained in:
parent
8d92f5f71a
commit
e8bdbd96a3
@ -22,10 +22,11 @@ _ref:
|
||||
types: |
|
||||
```
|
||||
(key: string): any
|
||||
(key: integer): any
|
||||
(all: boolean): any
|
||||
(arguments: {
|
||||
all?: boolean,
|
||||
key?: string,
|
||||
key?: string | integer,
|
||||
default?: any
|
||||
}): any
|
||||
```
|
||||
@ -35,12 +36,15 @@ _ref:
|
||||
###### string
|
||||
If the `_args` operator is called with a string argument, the value of the key in the `arguments` array is returned. If the value is not found, `null` is returned. Dot notation and [block list indexes](/lists) are supported.
|
||||
|
||||
###### integer
|
||||
If the `_args` operator is called with a integer argument, the value at that index in the `arguments` array is returned. If the value is not found, `null` is returned. Dot notation and [block list indexes](/lists) are supported.
|
||||
|
||||
###### boolean
|
||||
If the `_args` operator is called with boolean argument `true`, the entire `arguments` array is returned.
|
||||
|
||||
###### object
|
||||
- `all: boolean`: If `all` is set to `true`, the entire `arguments` array is returned. One of `all` or `key` are required.
|
||||
- `key: string`: The value of the key in the `arguments` array is returned. If the value is not found, `null`, or the specified default value is returned. Dot notation and [block list indexes](/lists) are supported. One of `all` or `key` are required.
|
||||
- `key: string | integer`: The value of the key or index in the `arguments` array is returned. If the value is not found, `null`, or the specified default value is returned. Dot notation and [block list indexes](/lists) are supported. One of `all` or `key` are required.
|
||||
- `default: any`: A value to return if the `key` is not found in `arguments`. By default, `null` is returned if a value is not found.
|
||||
examples: |
|
||||
###### Map over an array:
|
||||
|
@ -23,7 +23,7 @@ _ref:
|
||||
```
|
||||
(arguments: {
|
||||
from: any[] | object,
|
||||
key: string,
|
||||
key: string | integer,
|
||||
default?: any,
|
||||
}): any
|
||||
```
|
||||
@ -33,7 +33,7 @@ _ref:
|
||||
arguments: |
|
||||
###### object
|
||||
- `from: any[] | object`: __Required__ - The object to get the value from.
|
||||
- `key: string`: __Required__ - The value of the key in the `from` object is returned. If the value is not found, `null`, or the specified default value is returned. Dot notation and [block list indexes](/lists) are supported.
|
||||
- `key: string`: __Required__ - The value of the key or array index to get from the `from` object or array. If the value is not found, `null`, or the specified default value is returned. Dot notation and [block list indexes](/lists) are supported.
|
||||
- `default: any`: A value to return if the `key` is not found in `from`. By default, `null` is returned if a value is not found.
|
||||
|
||||
examples: |
|
||||
|
@ -556,7 +556,7 @@ test('request properties operator error', async () => {
|
||||
requestId: 'requestId',
|
||||
connectionId: 'testConnection',
|
||||
properties: {
|
||||
willError: { _state: 0 },
|
||||
willError: { _state: [] },
|
||||
},
|
||||
};
|
||||
}
|
||||
@ -566,7 +566,7 @@ test('request properties operator error', async () => {
|
||||
const controller = createRequestController(context);
|
||||
await expect(controller.callRequest(defaultInput)).rejects.toThrow(RequestError);
|
||||
await expect(controller.callRequest(defaultInput)).rejects.toThrow(
|
||||
'Error: Operator Error: _state params must be of type string, boolean or object. Received: 0 at requestId.'
|
||||
'Error: Operator Error: _state params must be of type string, integer, boolean or object. Received: [] at requestId.'
|
||||
);
|
||||
});
|
||||
|
||||
@ -578,7 +578,7 @@ test('connection properties operator error', async () => {
|
||||
type: 'TestConnection',
|
||||
connectionId: 'testConnection',
|
||||
properties: {
|
||||
willError: { _state: 0 },
|
||||
willError: { _state: [] },
|
||||
},
|
||||
};
|
||||
}
|
||||
@ -589,7 +589,7 @@ test('connection properties operator error', async () => {
|
||||
const controller = createRequestController(context);
|
||||
await expect(controller.callRequest(defaultInput)).rejects.toThrow(RequestError);
|
||||
await expect(controller.callRequest(defaultInput)).rejects.toThrow(
|
||||
'Error: Operator Error: _state params must be of type string, boolean or object. Received: 0 at testConnection.'
|
||||
'Error: Operator Error: _state params must be of type string, integer, boolean or object. Received: [] at testConnection.'
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -19,6 +19,7 @@ import type from './type';
|
||||
const applyArrayIndices = (arrayIndices, name) => {
|
||||
if (!type.isArray(arrayIndices)) return name;
|
||||
if (arrayIndices.length === 0) return name;
|
||||
if (type.isNumber(name)) return name;
|
||||
const copy = JSON.parse(JSON.stringify(arrayIndices));
|
||||
const index = copy.shift();
|
||||
let newName;
|
||||
|
@ -56,6 +56,11 @@ test('arrayIndices with 1 index, more than 1 $', () => {
|
||||
expect(applyArrayIndices([1], 'a.$.a.$.b')).toEqual('a.1.a.$.b');
|
||||
});
|
||||
|
||||
test('name is a number', () => {
|
||||
expect(applyArrayIndices([], 1)).toEqual(1);
|
||||
expect(applyArrayIndices([], 3.14)).toEqual(3.14);
|
||||
});
|
||||
|
||||
test('does not modify arrayIndices', () => {
|
||||
const arrayIndices = [1];
|
||||
expect(applyArrayIndices(arrayIndices, 'a.$')).toEqual('a.1');
|
||||
|
@ -130,6 +130,11 @@ test('return arr', () => {
|
||||
expect(get(objOne, 'a.b')).toEqual([]);
|
||||
});
|
||||
|
||||
test('get by array index', () => {
|
||||
const arr = [0, 1, 2];
|
||||
expect(get(arr, 1)).toEqual(1);
|
||||
});
|
||||
|
||||
// tests from
|
||||
// https://github.com/jonschlinkert/get-value/blob/master/test/units.js
|
||||
|
||||
|
@ -14,9 +14,10 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { applyArrayIndices, get, type } from '@lowdefy/helpers';
|
||||
import { type } from '@lowdefy/helpers';
|
||||
import getFromObject from '../getFromObject';
|
||||
|
||||
function _get({ params, location, arrayIndices }) {
|
||||
function _get({ arrayIndices, env, location, params }) {
|
||||
if (!type.isObject(params)) {
|
||||
throw new Error(
|
||||
`Operator Error: _get takes an object as params. Received: ${JSON.stringify(
|
||||
@ -24,17 +25,20 @@ function _get({ params, location, arrayIndices }) {
|
||||
)} at ${location}.`
|
||||
);
|
||||
}
|
||||
|
||||
if (!type.isString(params.key)) {
|
||||
if (!type.isObject(params.from) && !type.isArray(params.from)) {
|
||||
throw new Error(
|
||||
`Operator Error: _get.key takes a string. Received ${JSON.stringify(params)} at ${location}.`
|
||||
`Operator Error: _get.from is not an object or array. Received: ${JSON.stringify(
|
||||
params
|
||||
)} at ${location}.`
|
||||
);
|
||||
}
|
||||
if (!type.isObject(params.from) && !type.isArray(params.from)) {
|
||||
return null;
|
||||
}
|
||||
return get(params.from, applyArrayIndices(arrayIndices, params.key), {
|
||||
default: get(params, 'default', { default: null }),
|
||||
return getFromObject({
|
||||
arrayIndices,
|
||||
env,
|
||||
location,
|
||||
object: params.from,
|
||||
operator: '_get',
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -29,10 +29,10 @@ function getFromObject({
|
||||
env,
|
||||
}) {
|
||||
if (params === true) params = { all: true };
|
||||
if (type.isString(params)) params = { key: params };
|
||||
if (type.isString(params) || type.isInt(params)) params = { key: params };
|
||||
if (!type.isObject(params)) {
|
||||
throw new Error(
|
||||
`Operator Error: ${operator} params must be of type string, boolean or object. Received: ${JSON.stringify(
|
||||
`Operator Error: ${operator} params must be of type string, integer, boolean or object. Received: ${JSON.stringify(
|
||||
params
|
||||
)} at ${location}.`
|
||||
);
|
||||
@ -56,9 +56,9 @@ function getFromObject({
|
||||
});
|
||||
}
|
||||
if (params.all === true) return serializer.copy(object);
|
||||
if (!type.isString(params.key)) {
|
||||
if (!type.isString(params.key) && !type.isInt(params.key)) {
|
||||
throw new Error(
|
||||
`Operator Error: ${operator}.key must be of type string. Received: ${JSON.stringify(
|
||||
`Operator Error: ${operator}.key must be of type string or integer. Received: ${JSON.stringify(
|
||||
params
|
||||
)} at ${location}.`
|
||||
);
|
||||
|
@ -52,7 +52,7 @@ test('NodeParser, _function throws on parser errors', () => {
|
||||
const params = { __state: [] };
|
||||
const fn = _function({ location, params, parser });
|
||||
expect(fn).toThrow(
|
||||
'Error: Operator Error: _state params must be of type string, boolean or object. Received: [] at location.'
|
||||
'Error: Operator Error: _state params must be of type string, integer, boolean or object. Received: [] at location.'
|
||||
);
|
||||
});
|
||||
|
||||
@ -78,6 +78,6 @@ test('WebParser, _function throws on parser errors', () => {
|
||||
const params = { __state: [] };
|
||||
const fn = _function({ location, params, parser });
|
||||
expect(fn).toThrow(
|
||||
'Error: Operator Error: _state params must be of type string, boolean or object. Received: [] at location.'
|
||||
'Error: Operator Error: _state params must be of type string, integer, boolean or object. Received: [] at location.'
|
||||
);
|
||||
});
|
||||
|
@ -57,6 +57,36 @@ test('get a field from an object, key as param', () => {
|
||||
expect(res).toEqual('string');
|
||||
});
|
||||
|
||||
test('get a field from an array, integer index, shorthand', () => {
|
||||
const params = 1;
|
||||
const res = getFromObject({
|
||||
params,
|
||||
object: [1, 2, 3],
|
||||
context,
|
||||
contexts,
|
||||
arrayIndices: defaultArrayIndices,
|
||||
operator,
|
||||
location,
|
||||
env: 'node',
|
||||
});
|
||||
expect(res).toEqual(2);
|
||||
});
|
||||
|
||||
test('get a field from an array, integer index', () => {
|
||||
const params = { key: 1 };
|
||||
const res = getFromObject({
|
||||
params,
|
||||
object: [1, 2, 3],
|
||||
context,
|
||||
contexts,
|
||||
arrayIndices: defaultArrayIndices,
|
||||
operator,
|
||||
location,
|
||||
env: 'node',
|
||||
});
|
||||
expect(res).toEqual(2);
|
||||
});
|
||||
|
||||
test('get a field from an object, shorthand, not found returns null', () => {
|
||||
const params = 'not_there';
|
||||
const res = getFromObject({
|
||||
@ -218,7 +248,7 @@ test('params not correct type', () => {
|
||||
location,
|
||||
env: 'node',
|
||||
})
|
||||
).toThrow('Operator Error: _operator params must be of type string, boolean or object.');
|
||||
).toThrow('Operator Error: _operator params must be of type string, integer, boolean or object.');
|
||||
});
|
||||
|
||||
test('params key not a string', () => {
|
||||
@ -233,7 +263,7 @@ test('params key not a string', () => {
|
||||
location,
|
||||
env: 'node',
|
||||
})
|
||||
).toThrow('Operator Error: _operator.key must be of type string.');
|
||||
).toThrow('Operator Error: _operator.key must be of type string or integer.');
|
||||
});
|
||||
|
||||
test('replace arrayIndices', () => {
|
||||
|
@ -83,15 +83,11 @@ test('_get from: null', () => {
|
||||
});
|
||||
|
||||
test('_get key: int', () => {
|
||||
const input = { _get: { from: object, key: 1 } };
|
||||
const input = { _get: { from: [1, 2, 3], key: 1 } };
|
||||
const parser = new NodeParser();
|
||||
const res = parser.parse({ input, location: 'locationId' });
|
||||
expect(res.output).toBe(null);
|
||||
expect(res.errors).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
[Error: Operator Error: _get.key takes a string. Received {"from":{"string":"Some String","number":42,"arr":[{"a":"a1"},{"a":"a2"}]},"key":1} at locationId.],
|
||||
]
|
||||
`);
|
||||
expect(res.output).toBe(2);
|
||||
expect(res.errors).toMatchInlineSnapshot(`Array []`);
|
||||
});
|
||||
|
||||
test('_get replace key arrayIndices', () => {
|
||||
|
@ -120,7 +120,7 @@ test('_event_log null', () => {
|
||||
expect(res.output).toBe(null);
|
||||
expect(res.errors).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
[Error: Operator Error: _event_log params must be of type string, boolean or object. Received: null at locationId.],
|
||||
[Error: Operator Error: _event_log params must be of type string, integer, boolean or object. Received: null at locationId.],
|
||||
]
|
||||
`);
|
||||
});
|
||||
@ -201,7 +201,7 @@ test('_event_log param object invalid', () => {
|
||||
expect(res.output).toEqual(null);
|
||||
expect(res.errors).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
[Error: Operator Error: _event_log.key must be of type string. Received: {"other":true} at locationId.],
|
||||
[Error: Operator Error: _event_log.key must be of type string or integer. Received: {"other":true} at locationId.],
|
||||
]
|
||||
`);
|
||||
});
|
||||
@ -215,7 +215,7 @@ test('_event_log param array', () => {
|
||||
expect(res.output).toEqual(null);
|
||||
expect(res.errors).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
[Error: Operator Error: _event_log params must be of type string, boolean or object. Received: ["string"] at locationId.],
|
||||
[Error: Operator Error: _event_log params must be of type string, integer, boolean or object. Received: ["string"] at locationId.],
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
@ -130,13 +130,9 @@ test('_get from: null', () => {
|
||||
});
|
||||
|
||||
test('_get key: int', () => {
|
||||
const input = { _get: { from: object, key: 1 } };
|
||||
const input = { _get: { from: [1, 2, 3], key: 1 } };
|
||||
const parser = new WebParser({ context, contexts });
|
||||
const res = parser.parse({ input, location: 'locationId', arrayIndices });
|
||||
expect(res.output).toBe(null);
|
||||
expect(res.errors).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
[Error: Operator Error: _get.key takes a string. Received {"from":{"string":"Some String","number":42,"arr":[{"a":"a1"},{"a":"a2"}]},"key":1} at locationId.],
|
||||
]
|
||||
`);
|
||||
expect(res.output).toBe(2);
|
||||
expect(res.errors).toMatchInlineSnapshot(`Array []`);
|
||||
});
|
||||
|
@ -95,7 +95,7 @@ test('_request_details null', () => {
|
||||
expect(res.output).toBe(null);
|
||||
expect(res.errors).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
[Error: Operator Error: _request_details params must be of type string, boolean or object. Received: null at locationId.],
|
||||
[Error: Operator Error: _request_details params must be of type string, integer, boolean or object. Received: null at locationId.],
|
||||
]
|
||||
`);
|
||||
});
|
||||
@ -166,7 +166,7 @@ test('_request_details param object invalid', () => {
|
||||
expect(res.output).toEqual(null);
|
||||
expect(res.errors).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
[Error: Operator Error: _request_details.key must be of type string. Received: {"other":true} at locationId.],
|
||||
[Error: Operator Error: _request_details.key must be of type string or integer. Received: {"other":true} at locationId.],
|
||||
]
|
||||
`);
|
||||
});
|
||||
@ -180,7 +180,7 @@ test('_request_details param array', () => {
|
||||
expect(res.output).toEqual(null);
|
||||
expect(res.errors).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
[Error: Operator Error: _request_details params must be of type string, boolean or object. Received: ["string"] at locationId.],
|
||||
[Error: Operator Error: _request_details params must be of type string, integer, boolean or object. Received: ["string"] at locationId.],
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user