deep-foundation / deepclient Goto Github PK
View Code? Open in Web Editor NEWDeep Client - a way to connect your favourite language with Deep.
License: The Unlicense
Deep Client - a way to connect your favourite language with Deep.
License: The Unlicense
gitpod /workspace/deepclient (main) $ ( cd python && python -m unittest discover -s tests -v )
test_initialization (test_deep_client.TestDeepClient.test_initialization) ... ok
test_methods_raise_not_implemented (test_deep_client.TestDeepClient.test_methods_raise_not_implemented) ... /workspace/deepclient/python/tests/test_deep_client.py:38: DeprecationWarning: There is no current event loop
loop = asyncio.get_event_loop()
ok
test_select (test_deep_client.TestDeepClient.test_select) ... ERROR
test_serialize_where (test_deep_client.TestDeepClient.test_serialize_where) ... ok
======================================================================
ERROR: test_select (test_deep_client.TestDeepClient.test_select)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/workspace/deepclient/python/tests/test_deep_client.py", line 144, in test_select
loop.run_until_complete(test_async_methods())
File "/home/gitpod/.pyenv/versions/3.11.1/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "/workspace/deepclient/python/tests/test_deep_client.py", line 141, in test_async_methods
await self.client.select(1)
File "/workspace/deepclient/python/deepclient/deep_client.py", line 419, in select
q = await self.client.execute(generate_query({
^^^^^^^^^^^^^^^^
File "/workspace/deepclient/python/deepclient/query.py", line 62, in generate_query
called_queries = [m(alias, i) if callable(m) else m for i, m in enumerate(queries)]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/workspace/deepclient/python/deepclient/query.py", line 62, in <listcomp>
called_queries = [m(alias, i) if callable(m) else m for i, m in enumerate(queries)]
^^^^^^^^^^^
File "/workspace/deepclient/python/deepclient/query.py", line 9, in inner
defs.append(f"${field + index}: {field_types[field]}")
~~~~~~^~~~~~~
TypeError: can only concatenate str (not "int") to str
----------------------------------------------------------------------
Ran 4 tests in 0.003s
FAILED (errors=1)
export const _ids = {
'@deep-foundation/core': {},
};
export const _serialize = {
links: {
fields: {
id: 'number',
from_id: 'number',
to_id: 'number',
type_id: 'number',
},
relations: {
from: 'links',
to: 'links',
type: 'links',
in: 'links',
out: 'links',
typed: 'links',
selected: 'selector',
selectors: 'selector',
value: 'value',
string: 'value',
number: 'value',
object: 'value',
can_rule: 'can',
can_action: 'can',
can_object: 'can',
can_subject: 'can',
down: 'tree',
up: 'tree',
tree: 'tree',
root: 'tree',
},
},
selector: {
fields: {
item_id: 'number',
selector_id: 'number',
query_id: 'number',
selector_include_id: 'number',
},
relations: {
item: 'links',
selector: 'links',
query: 'links',
}
},
can: {
fields: {
rule_id: 'number',
action_id: 'number',
object_id: 'number',
subject_id: 'number',
},
relations: {
rule: 'links',
action: 'links',
object: 'links',
subject: 'links',
}
},
tree: {
fields: {
id: 'number',
link_id: 'number',
tree_id: 'number',
root_id: 'number',
parent_id: 'number',
depth: 'number',
position_id: 'string',
},
relations: {
link: 'links',
tree: 'links',
root: 'links',
parent: 'links',
by_link: 'tree',
by_tree: 'tree',
by_root: 'tree',
by_parent: 'tree',
by_position: 'tree',
}
},
value: {
fields: {
id: 'number',
link_id: 'number',
value: 'value',
},
relations: {
link: 'links',
},
},
};
export const _boolExpFields = {
_and: true,
_not: true,
_or: true,
};
export const pathToWhere = (start: (DeepClientStartItem), ...path: DeepClientPathItem[]): any => {
const pckg = typeof(start) === 'string' ? { type_id: _ids?.['@deep-foundation/core']?.Package, value: start } : { id: start };
let where: any = pckg;
for (let p = 0; p < path.length; p++) {
const item = path[p];
if (typeof(item) !== 'boolean') {
const nextWhere = { in: { type_id: _ids?.['@deep-foundation/core']?.Contain, value: item, from: where } };
where = nextWhere;
}
}
return where;
}
export const serializeWhere = (exp: any, env: string = 'links'): any => {
// if exp is array - map
if (Object.prototype.toString.call(exp) === '[object Array]') return exp.map((e) => serializeWhere(e, env));
else if (typeof(exp) === 'object') {
// if object
const keys = Object.keys(exp);
const result: any = {};
// map keys
for (let k = 0; k < keys.length; k++) {
const key = keys[k];
const type = typeof(exp[key]);
let setted: any = false;
const is_id_field = !!~['type_id', 'from_id', 'to_id'].indexOf(key);
// if this is link
if (env === 'links') {
// if field contain primitive type - string/number
if (type === 'string' || type === 'number') {
if (key === 'value' || key === type) {
// if field id link.value
setted = result[type] = { value: { _eq: exp[key] } };
} else {
// else just equal
setted = result[key] = { _eq: exp[key] };
}
} else if (!_boolExpFields[key] && Object.prototype.toString.call(exp[key]) === '[object Array]') {
// if field is not boolExp (_and _or _not) but contain array
// @ts-ignore
setted = result[key] = serializeWhere(pathToWhere(...exp[key]));
}
} else if (env === 'value') {
// if this is value
if (type === 'string' || type === 'number') {
setted = result[key] = { _eq: exp[key] };
}
}
if (type === 'object' && exp[key].hasOwnProperty('_type_of') && (
(env === 'links' && (is_id_field || key === 'id')) ||
(env === 'selector' && key === 'item_id') ||
(env === 'can' && !!~['rule_id', 'action_id', 'subject_id', 'object_id',].indexOf(key)) ||
(env === 'tree' && !!~['link_id', 'tree_id', 'root_id', 'parent_id'].indexOf(key)) ||
(env === 'value' && key === 'link_id')
)) {
// if field is object, and contain _type_od
const _temp = setted = { _by_item: { path_item_id: { _eq: exp[key]._type_of }, group_id: { _eq: 0 } } };
if (key === 'id') {
result._and = result._and ? [...result._and, _temp] : [_temp];
} else {
result[key.slice(0, -3)] = _temp;
}
} else if (type === 'object' && exp[key].hasOwnProperty('_id') && (
(env === 'links' && (is_id_field || key === 'id')) ||
(env === 'selector' && key === 'item_id') ||
(env === 'can' && !!~['rule_id', 'action_id', 'subject_id', 'object_id',].indexOf(key)) ||
(env === 'tree' && !!~['link_id', 'tree_id', 'root_id', 'parent_id'].indexOf(key)) ||
(env === 'value' && key === 'link_id')
) && Object.prototype.toString.call(exp[key]._id) === '[object Array]' && exp[key]._id.length >= 1) {
// if field is object, and contain _type_od
const _temp = setted = serializeWhere(pathToWhere(exp[key]._id[0], ...exp[key]._id.slice(1)), 'links');
if (key === 'id') {
result._and = result._and ? [...result._and, _temp] : [_temp];
} else {
result[key.slice(0, -3)] = _temp;
}
}
// if not expected
if (!setted) {
const _temp = (
// if _and _or _not
_boolExpFields[key]
) ? (
// just parse each item in array
serializeWhere(exp[key], env)
) : (
// if we know context
_serialize?.[env]?.relations?.[key]
) ? (
// go to this context then
serializeWhere(exp[key], _serialize?.[env]?.relations?.[key])
) : (
// else just stop
exp[key]
);
if (key === '_and') result._and ? result._and.push(..._temp) : result._and = _temp;
else result[key] = _temp;
}
}
return result;
} else {
if (typeof(exp) === 'undefined') throw new Error('undefined in query');
return exp;
}
};
Translate this code to python and add it as serializeWhere field to DeepClient class in deep_client.py file.
test_deep_client (unittest.loader._FailedTest.test_deep_client) ... ERROR
======================================================================
ERROR: test_deep_client (unittest.loader._FailedTest.test_deep_client)
----------------------------------------------------------------------
ImportError: Failed to import test module: test_deep_client
Traceback (most recent call last):
File "/opt/hostedtoolcache/Python/3.[11](https://github.com/deep-foundation/deepclient/actions/runs/4893597496/jobs/8736741225#step:8:12).3/x64/lib/python3.11/unittest/loader.py", line 407, in _find_test_path
module = self._get_module_from_name(name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/hostedtoolcache/Python/3.11.3/x64/lib/python3.11/unittest/loader.py", line 350, in _get_module_from_name
__import__(name)
File "/home/runner/work/deepclient/deepclient/python/tests/test_deep_client.py", line 3, in <module>
from deepclient import DeepClient, DeepClientOptions
File "/home/runner/work/deepclient/deepclient/python/deepclient/__init__.py", line 1, in <module>
from .deep_client import DeepClient
File "/home/runner/work/deepclient/deepclient/python/deepclient/deep_client.py", line 4, in <module>
from .query import generate_query, generate_query_data
File "/home/runner/work/deepclient/deepclient/python/deepclient/query.py", line 63
query_string = f"{operation} {name} ({defs}) {{ {','.join([f'{m["resultAlias"]}: {m["queryName"]}({",".join(m["args"])}) {{ {m["resultReturning"]} }}' for m in called_queries])} }}"
^^^^^^^^^^^
SyntaxError: f-string: unterminated string
----------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (errors=1)
Error: Process completed with exit code 1.
async select<Table extends 'links'|'numbers'|'strings'|'objects'|'can'|'selectors'|'tree'|'handlers', LL = L>(exp: (
Table extends 'numbers' ? BoolExpValue<number> :
Table extends 'strings' ? BoolExpValue<string> :
Table extends 'objects' ? BoolExpValue<object> :
Table extends 'can' ? BoolExpCan :
Table extends 'selectors' ? BoolExpSelector :
Table extends 'tree' ? BoolExpTree :
Table extends 'handlers' ? BoolExpHandler :
BoolExpLink
) | number | number[], options?: {
table?: Table;
returning?: string;
variables?: any;
name?: string;
}): Promise<DeepClientResult<LL[]>> {
if (!exp) {
return { error: { message: '!exp' }, data: undefined, loading: false, networkStatus: undefined };
}
const where = typeof(exp) === 'object' ? Object.prototype.toString.call(exp) === '[object Array]' ? { id: { _in: exp } } : serializeWhere(exp, options?.table || 'links') : { id: { _eq: exp } };
const table = options?.table || this.table;
const returning = options?.returning ??
(table === 'links' ? this.linksSelectReturning :
['strings', 'numbers', 'objects'].includes(table) ? this.valuesSelectReturning :
table === 'selectors' ? this.selectorsSelectReturning :
table === 'files' ? this.filesSelectReturning : `id`);
// console.log(`returning: ${returning}; options.returning:${options?.returning}`)
const variables = options?.variables;
const name = options?.name || this.defaultSelectName;
const q = await this.apolloClient.query(generateQuery({
queries: [
generateQueryData({
tableName: table,
returning,
variables: {
limit: where?.limit,
...variables,
where,
} }),
],
name: name,
}));
// @ts-ignore
return { ...q, data: (q)?.data?.q0 };
};
Translate this code to python and put into select.py
Instead of this.apolloClient use self.client which is from gql pypi package
serializeWhere is available as self.serialize_where
generateQuery as self.generate_query
generateQueryData as self.generate_query_data
While running unittests with the following command:
( cd python && python -m unittest discover -s tests -v )
I encountered an error in the test_select method of the TestDeepClient class:
ERROR: test_select (test_deep_client.TestDeepClient.test_select)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/workspace/deepclient/python/tests/test_deep_client.py", line 144, in test_select
loop.run_until_complete(test_async_methods())
File "/home/gitpod/.pyenv/versions/3.11.1/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete
return future.result()
File "/workspace/deepclient/python/tests/test_deep_client.py", line 141, in test_async_methods
await self.client.select(1)
File "/workspace/deepclient/python/deepclient/deep_client.py", line 424, in select
"variables": {
TypeError: 'NoneType' object is not a mapping
This error seems to be related to the select method in the deep_client.py file, specifically at line 424. It appears that there is an issue with a NoneType object being used as a mapping.
To resolve this issue, please investigate why the mapping is of type NoneType and ensure that a valid mapping is being used. Additionally, consider adding more informative error messages or handling the case when the mapping is NoneType to prevent similar issues in the future.
this.linksSelectReturning = options.linksSelectReturning || options.selectReturning || 'id type_id from_id to_id value';
this.selectReturning = options.selectReturning || this.linksSelectReturning;
this.valuesSelectReturning = options.valuesSelectReturning || 'id link_id value';
this.selectorsSelectReturning = options.selectorsSelectReturning ||'item_id selector_id';
this.filesSelectReturning = options.filesSelectReturning ||'id link_id name mimeType';
this.defaultSelectName = options.defaultSelectName || 'SELECT';
Translate this code to python and update DeepClient and DeepClientOptions to reflect added fields required for select requests.
/**
* Find id of link by packageName/id as first argument, and Contain value (name) as path items.
* @description Thows error if id not founded. You can set last argument true, for disable throwing error.
* @returns number
*/
async id(start: DeepClientStartItem | BoolExpLink, ...path: DeepClientPathItem[]): Promise<number> {
if (typeof(start) === 'object') {
return ((await this.select(start)) as any)?.data?.[0]?.id;
}
if (_ids?.[start]?.[path[0]]) {
return _ids[start][path[0]];
}
const q = await this.select(pathToWhere(start, ...path));
if (q.error) {
throw q.error;
}
// @ts-ignore
const result = (q?.data?.[0]?.id | _ids?.[start]?.[path?.[0]] | 0);
if (!result && path[path.length - 1] !== true) {
throw new Error(`Id not found by [${JSON.stringify([start, ...path])}]`);
}
return result;
};
Translate this code to python and integrate in instead unimplemented id
method in python/deepclient/deep_client.py
.
Transfer will be in two stages:
dev
repository in package.json
export interface IGenerateQueryOptions {
queries: any[];
name: string;
operation?: 'query' | 'subscription';
alias?: string;
};
export interface IGenerateQueryResult {
query: any;
queryString: any;
variables: any;
};
export const generateQuery = ({
queries = [],
operation = 'query',
name = 'QUERY',
alias = 'q',
}: IGenerateQueryOptions): IGenerateQueryResult => {
log('generateQuery', { name, alias, queries });
const calledQueries = queries.map((m,i) => typeof(m) === 'function' ? m(alias, i) : m);
const defs = calledQueries.map(m => m.defs.join(',')).join(',');
const queryString = `${operation} ${name} (${defs}) { ${calledQueries.map(m => `${m.resultAlias}: ${m.queryName}(${m.args.join(',')}) { ${m.resultReturning} }`).join('')} }`;
const query = gql`${queryString}`;
const variables = {};
for (let a = 0; a < calledQueries.length; a++) {
const action = calledQueries[a];
for (const v in action.resultVariables) {
if (Object.prototype.hasOwnProperty.call(action.resultVariables, v)) {
const variable = action.resultVariables[v];
variables[v] = variable;
}
}
}
const result = {
query,
variables,
queryString,
};
log('generateQueryResult', JSON.stringify({ query: queryString, variables }, null, 2));
return result;
};
Translate this code to python and add it to query.py
import Debug from 'debug';
import gql from 'graphql-tag';
const debug = Debug('deeplinks:gql:query');
const log = debug.extend('log');
const error = debug.extend('error');
// Force enable this file errors output
const namespaces = Debug.disable();
Debug.enable(`${namespaces ? `${namespaces},` : ``}${error.namespace}`);
const fieldsInputs = (tableName): IGenerateQueryFieldTypes => ({
'distinct_on': `[${tableName}_select_column!]`,
'limit': `Int`,
'offset': `Int`,
'order_by': `[${tableName}_order_by!]`,
'where': `${tableName}_bool_exp!`,
});
export interface IGenerateQueryDataOptions {
tableName: string;
operation?: 'query' | 'subscription';
queryName?: string;
returning?: string;
variables?: any; // TODO
}
export interface IGenerateQueryDataBuilder {
(alias: string, index: number): IGenerateQueryDataResult
}
export interface IGenerateQueryFieldTypes {
[field: string]: string;
}
export interface IGenerateQueryDataResult extends IGenerateQueryDataOptions {
resultReturning: string;
fields: string[];
fieldTypes: IGenerateQueryFieldTypes;
defs: string[];
args: string[];
alias: string;
index: number;
resultAlias: string;
resultVariables: any;
}
export const generateQueryData = ({
tableName,
operation = 'query',
queryName = `${tableName}`,
returning = `id`,
variables,
}: IGenerateQueryDataOptions): IGenerateQueryDataBuilder => {
log('generateQuery', { tableName, operation, queryName, returning, variables });
const fields = ['distinct_on', 'limit', 'offset', 'order_by', 'where'];
const fieldTypes = fieldsInputs(tableName);
return (alias: string, index: number): IGenerateQueryDataResult => {
log('generateQueryBuilder', { tableName, operation, queryName, returning, variables, alias, index });
const defs = [];
const args = [];
for (let f = 0; f < fields.length; f++) {
const field = fields[f];
defs.push(`$${field + index}: ${fieldTypes[field]}`);
args.push(`${field}: $${field}${index}`);
}
const resultAlias = `${alias}${typeof(index) === 'number' ? index : ''}`;
const resultVariables = {};
for (const v in variables) {
if (Object.prototype.hasOwnProperty.call(variables, v)) {
const variable = variables[v];
resultVariables[v + index] = variable;
}
}
const result = {
tableName,
operation,
queryName,
returning,
variables,
resultReturning: returning,
fields,
fieldTypes,
index,
defs,
args,
alias,
resultAlias,
resultVariables,
};
log('generateQueryResult', result);
return result
};
};
Translate this code to python and put it into query.py file.
describe('client', () => {
it(`{ id: 5 }`, () => {
assert.deepEqual(deepClient.serializeWhere({ id: 5 }), { id: { _eq: 5 } });
});
it(`{ id: { _eq: 5 } }`, () => {
assert.deepEqual(deepClient.serializeWhere({ id: { _eq: 5 } }), { id: { _eq: 5 } });
});
it(`{ value: 5 }`, () => {
assert.deepEqual(deepClient.serializeWhere({ value: 5 }), { number: { value: { _eq: 5 } } });
});
it(`{ value: 'a' }`, () => {
assert.deepEqual(deepClient.serializeWhere({ value: 'a' }), { string: { value: { _eq: 'a' } } });
});
it(`{ number: 5 }`, () => {
assert.deepEqual(deepClient.serializeWhere({ number: 5 }), { number: { value: { _eq: 5 } } });
});
it(`{ string: 'a' }`, () => {
assert.deepEqual(deepClient.serializeWhere({ string: 'a' }), { string: { value: { _eq: 'a' } } });
});
it(`{ number: { value: { _eq: 5 } } }`, () => {
assert.deepEqual(deepClient.serializeWhere({ number: { value: { _eq: 5 } } }), { number: { value: { _eq: 5 } } });
});
it(`{ string: { value: { _eq: 'a' } } }`, () => {
assert.deepEqual(deepClient.serializeWhere({ string: { value: { _eq: 'a' } } }), { string: { value: { _eq: 'a' } } });
});
it(`{ object: { value: { _contains: { a: 'b' } } } }`, () => {
assert.deepEqual(deepClient.serializeWhere({ object: { value: { _contains: { a: 'b' } } } }), { object: { value: { _contains: { a: 'b' } } } });
});
it(`{ from: { value: 5 } }`, () => {
assert.deepEqual(deepClient.serializeWhere({ from: { value: 5 } }), { from: { number: { value: { _eq: 5 } } } });
});
it(`{ out: { type_id: Contain, value: item, from: where } }`, async () => {
assert.deepEqual(deepClient.serializeWhere(
{
out: {
type_id: await deepClient.id('@deep-foundation/core', 'Contain'),
value: 'b',
from: {
type_id: await deepClient.id('@deep-foundation/core', 'Package'),
value: 'a',
},
},
}
), {
out: {
type_id: { _eq: await deepClient.id('@deep-foundation/core', 'Contain') },
string: { value: { _eq: 'b' } },
from: {
type_id: { _eq: await deepClient.id('@deep-foundation/core', 'Package') },
string: { value: { _eq: 'a' } },
},
}
});
});
it(`{ value: 5, link: { type_id: 7 } }`, () => {
assert.deepEqual(deepClient.serializeWhere(
{ value: 5, link: { type_id: 7 } },
'value'
), {
value: { _eq: 5 },
link: {
type_id: { _eq: 7 }
},
});
});
it(`{ type: ['@deep-foundation/core', 'Value'] }`, () => {
assert.deepEqual(
deepClient.serializeWhere({
type: ["@deep-foundation/core", "Value"],
}),
{
type: {
in: {
from: {
string: { value: { _eq: "@deep-foundation/core" } },
type_id: { _eq: 2 },
},
string: { value: { _eq: "Value" } },
type_id: { _eq: 3 },
},
},
},
);
});
it(`{ type: ['@deep-foundation/core', 'Value'] }`, () => {
assert.deepEqual(
deepClient.serializeWhere({
_or: [{
type: ["@deep-foundation/core", "Value"],
}, {
type: ["@deep-foundation/core", "User"],
}]
}),
{
_or: [{
type: {
in: {
from: {
string: { value: { _eq: "@deep-foundation/core" } },
type_id: { _eq: 2 },
},
string: { value: { _eq: "Value" } },
type_id: { _eq: 3 },
},
},
},{
type: {
in: {
from: {
string: { value: { _eq: "@deep-foundation/core" } },
type_id: { _eq: 2 },
},
string: { value: { _eq: "User" } },
type_id: { _eq: 3 },
},
},
}]
},
);
});
it(`id(packageName,contain)`, async () => {
const id = await deepClient.id('@deep-foundation/core', 'Value');
assert.equal(id, 4);
});
it(`{ type_id: { _type_of: 25 } }`, () => {
assert.deepEqual(deepClient.serializeWhere({ type_id: { _type_of: 25 } }), { type: { _by_item: { path_item_id: { _eq: 25 }, group_id: { _eq: 0 } } } });
});
it(`{ from_id: { _type_of: 25 } }`, () => {
assert.deepEqual(deepClient.serializeWhere({ from_id: { _type_of: 25 } }), { from: { _by_item: { path_item_id: { _eq: 25 }, group_id: { _eq: 0 } } } });
});
it(`{ to_id: { _type_of: 25 } }`, () => {
assert.deepEqual(deepClient.serializeWhere({ to_id: { _type_of: 25 } }), { to: { _by_item: { path_item_id: { _eq: 25 }, group_id: { _eq: 0 } } } });
});
});
Translate these tests into python and add them to python/tests/test_deep_client.py file.
Core package is changed, list of IDs should be updated:
deepclient/python/deepclient/deep_client.py
Lines 6 to 192 in 4024767
export const serializeWhere = (exp: any, env: string = 'links'): any => {
if (Object.prototype.toString.call(exp) === '[object Array]') return exp.map((e) => serializeWhere(e, env));
else if (typeof(exp) === 'object') {
const keys = Object.keys(exp);
const result: any = {};
for (let k = 0; k < keys.length; k++) {
const key = keys[k];
const type = typeof(exp[key]);
let setted: any = false;
const is_id_field = !!~['type_id', 'from_id', 'to_id'].indexOf(key);
if (env === 'links') {
if (type === 'string' || type === 'number') {
if (key === 'value' || key === type) {
setted = result[type] = { value: { _eq: exp[key] } };
} else {
setted = result[key] = { _eq: exp[key] };
}
} else if (!_boolExpFields[key] && Object.prototype.toString.call(exp[key]) === '[object Array]') {
setted = result[key] = serializeWhere(pathToWhere(...exp[key]));
}
} else if (env === 'value') {
if (type === 'string' || type === 'number') {
setted = result[key] = { _eq: exp[key] };
}
}
if (type === 'object' && exp[key].hasOwnProperty('_type_of') && (
(env === 'links' && (is_id_field || key === 'id')) ||
(env === 'selector' && key === 'item_id') ||
(env === 'can' && !!~['rule_id', 'action_id', 'subject_id', 'object_id',].indexOf(key)) ||
(env === 'tree' && !!~['link_id', 'tree_id', 'root_id', 'parent_id'].indexOf(key)) ||
(env === 'value' && key === 'link_id')
)) {
const _temp = setted = { _by_item: { path_item_id: { _eq: exp[key]._type_of }, group_id: { _eq: 0 } } };
if (key === 'id') {
result._and = result._and ? [...result._and, _temp] : [_temp];
} else {
result[key.slice(0, -3)] = _temp;
}
} else if (type === 'object' && exp[key].hasOwnProperty('_id') && (
(env === 'links' && (is_id_field || key === 'id')) ||
(env === 'selector' && key === 'item_id') ||
(env === 'can' && !!~['rule_id', 'action_id', 'subject_id', 'object_id',].indexOf(key)) ||
(env === 'tree' && !!~['link_id', 'tree_id', 'root_id', 'parent_id'].indexOf(key)) ||
(env === 'value' && key === 'link_id')
) && Object.prototype.toString.call(exp[key]._id) === '[object Array]' && exp[key]._id.length >= 1) {
const _temp = setted = serializeWhere(pathToWhere(exp[key]._id[0], ...exp[key]._id.slice(1)), 'links');
if (key === 'id') {
result._and = result._and ? [...result._and, _temp] : [_temp];
} else {
result[key.slice(0, -3)] = _temp;
}
}
if (!setted) {
const _temp = (
_boolExpFields[key]
) ? (
serializeWhere(exp[key], env)
) : (
_serialize?.[env]?.relations?.[key]
) ? (
serializeWhere(exp[key], _serialize?.[env]?.relations?.[key])
) : (
exp[key]
);
if (key === '_and') result._and ? result._and.push(..._temp) : result._and = _temp;
else result[key] = _temp;
}
}
return result;
} else {
if (typeof(exp) === 'undefined') throw new Error('undefined in query');
return exp;
}
};
Translate this code to python and put it into serialize_where.py file
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.