api-sdk-ts
api-sdk-ts copied to clipboard
jsonParameter parser works counterintuitive
-
I'm submitting a ...
-
[x] feature request
-
Summary
I wish it works like this:
contractsGetBigMapByNameKeys(
address,
'name',
{
value: {
token_id: {
in: ['0', '1'],
},
/* instead of
in: {
jsonPath: 'token_id',
jsonValue: ['0', '1'],
},
*/
},
},
)
- Other information
I suggest to recursively create that.kind.of.path
from object with last nested property as value. And also I suggest to use reduce
for declarativeness.
@Groxan @m-kus what do u think dudes
@souljorje how would you specify this path: ?value.field.array.[*].field2=...
?
@Groxan
{
value: {
field: {
array: {
'[*]': {
field2: {
eq: 'foo',
// also I could specify at one place i.e.
ne: 'bar',
// etc
}
}
}
}
}
}
Actually, would be cool to use proxy instead, and just write it like value.toke_id.in = [0, 1]
and then build path in proxy handler, but it's still not clear what to do with [*]
(value.array['*'].field=123
is not really elegant).
@Groxan my suggestion is kinda mongodb query syntax: nested & intuitive imho 🤷♂️
proxy for what?
Proxy is used for creating dynamic object, so that you can "access" fields that are not defined. Nesting is good because you can merge multiple parameters (paths) into a single object, but it's less handy to write, especially in case of long and complex paths.
Anyway, I don't object. Just my thoughts.
Another issue that I see is constructing a query for a response object, that has in
| ne
| etc. in its fields. Such objects might not YET exist, but they might be there in the future. For the current proposal, the parameter would look something like this
value: {
someField: {
in: {
in: string[]
}
}
}
No sure if it improves readability, not mentioning the complexity of creating a QS parser for such parameter.
Another issue is creating a type for this parameter. The difficulty would be describing a Record of Records of unknown depth with the deepest level always being strongly typed to available eq
, ne
, in
, etc. types.
@souljorje this can be done only knowing the particular contract storage type. We will definitely implement that in TzKT wrappers
Here's a parser for suggested syntax.
const isPlainObject = (v) => {
if (Object.prototype.toString.call(v) !== '[object Object]') return false;
const prototype = Object.getPrototypeOf(v);
return prototype === null || prototype === Object.prototype;
};
const objectToQueryObject = (obj, path) => {
return Object.entries(obj).reduce((acc, [key, value]) => {
const newPath = path ? `${path}.${key}` : key;
if (isPlainObject(value)) {
return {
...acc,
...objectToQueryObject(value, newPath)
};
}
acc[newPath] = value;
return acc;
}, {})
};
const queryObjectRaw = {
value: {
field: {
array: {
'[*]': {
field2: {
eq: 'foo',
ne: 'bar',
}
}
},
someOtherProp: {
in: [1, 2, 3],
ne: 'baz',
}
},
someOtherField: {
gt: 123
},
},
otherValue: {
eq: 2
},
};
const result = objectToQueryObject(queryObjectRaw);
console.log('result', result);
const queryString = new URLSearchParams(result).toString();
console.log('queryString', queryString);