Code Monkey home page Code Monkey logo

deepclient's People

Contributors

archer-lotos avatar cehr2005 avatar flakeed avatar freephoenix888 avatar konard avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

deepclient's Issues

Error in test_select

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)

Add serializeWhere as a field to DeepClient in deep_client.py file

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.

Error in GitHub Actions

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.

Translate function to python and add to select.py

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

TypeError: 'NoneType' object is not a mapping in select method of DeepClient

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.

New fields for DeepClient and DeepClientOptions classes

    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.

Translate id method to python

  /**
   * 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.

Add generateQuery to query.py

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

Add generateQueryData function into 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.

Add serialize_where tests

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.

Update core package IDs

deep-foundation/deeplinks@1767589#diff-0feef32c31e5e1a32345332f96aee62137f6a84a801f083433696f122e958481

Core package is changed, list of IDs should be updated:

class DeepClient:
_ids = {
"@deep-foundation/core": {
"Type": 1,
"Package": 2,
"Contain": 3,
"Value": 4,
"String": 5,
"Number": 6,
"Object": 7,
"Any": 8,
"Promise": 9,
"Then": 10,
"Resolved": 11,
"Rejected": 12,
"typeValue": 13,
"packageValue": 14,
"Selector": 15,
"SelectorInclude": 16,
"Rule": 17,
"RuleSubject": 18,
"RuleObject": 19,
"RuleAction": 20,
"containValue": 21,
"User": 22,
"Operation": 23,
"operationValue": 24,
"AllowInsert": 25,
"AllowUpdate": 26,
"AllowDelete": 27,
"AllowSelect": 28,
"File": 29,
"SyncTextFile": 30,
"syncTextFileValue": 31,
"ExecutionProvider": 32,
"JSExecutionProvider": 33,
"TreeInclude": 34,
"Handler": 35,
"Tree": 36,
"TreeIncludeDown": 37,
"TreeIncludeUp": 38,
"TreeIncludeNode": 39,
"containTree": 40,
"containTreeContain": 41,
"containTreeAny": 42,
"PackageNamespace": 43,
"packageNamespaceValue": 44,
"PackageActive": 45,
"PackageVersion": 46,
"packageVersionValue": 47,
"HandleOperation": 48,
"HandleInsert": 49,
"HandleUpdate": 50,
"HandleDelete": 51,
"PromiseResult": 52,
"promiseResultValueRelationTable": 53,
"PromiseReason": 54,
"Focus": 55,
"focusValue": 56,
"AsyncFile": 57,
"Query": 58,
"queryValue": 59,
"Fixed": 60,
"fixedValue": 61,
"Space": 62,
"spaceValue": 63,
"AllowLogin": 64,
"guests": 65,
"Join": 66,
"joinTree": 67,
"joinTreeJoin": 68,
"joinTreeAny": 69,
"SelectorTree": 70,
"AllowAdmin": 71,
"SelectorExclude": 72,
"SelectorFilter": 73,
"HandleSchedule": 74,
"Schedule": 75,
"scheduleValue": 76,
"Router": 77,
"IsolationProvider": 78,
"DockerIsolationProvider": 79,
"dockerIsolationProviderValue": 80,
"JSDockerIsolationProvider": 81,
"Supports": 82,
"dockerSupportsJs": 83,
"PackageInstall": 84,
"PackagePublish": 85,
"packageInstallCode": 86,
"packageInstallCodeHandler": 87,
"packageInstallCodeHandleInsert": 88,
"packagePublishCode": 89,
"packagePublishCodeHandler": 90,
"packagePublishCodeHandleInsert": 91,
"Active": 92,
"AllowPackageInstall": 93,
"AllowPackagePublish": 94,
"PromiseOut": 95,
"promiseOutValue": 96,
"PackageQuery": 97,
"packageQueryValue": 98,
"Port": 99,
"portValue": 100,
"HandlePort": 101,
"PackageInstalled": 102,
"PackagePublished": 103,
"Route": 104,
"RouterListening": 105,
"RouterStringUse": 106,
"routerStringUseValue": 107,
"HandleRoute": 108,
"routeTree": 109,
"routeTreePort": 110,
"routeTreeRouter": 111,
"routeTreeRoute": 112,
"routeTreeHandler": 113,
"routeTreeRouterListening": 114,
"routeTreeRouterStringUse": 115,
"routeTreeHandleRoute": 116,
"TreeIncludeIn": 117,
"TreeIncludeOut": 118,
"TreeIncludeFromCurrent": 119,
"TreeIncludeToCurrent": 120,
"TreeIncludeCurrentFrom": 121,
"TreeIncludeCurrentTo": 122,
"TreeIncludeFromCurrentTo": 123,
"TreeIncludeToCurrentFrom": 124,
"AllowInsertType": 125,
"AllowUpdateType": 126,
"AllowDeleteType": 127,
"AllowSelectType": 128,
"ruleTree": 129,
"ruleTreeRule": 130,
"ruleTreeRuleAction": 131,
"ruleTreeRuleObject": 132,
"ruleTreeRuleSubject": 133,
"ruleTreeRuleSelector": 134,
"ruleTreeRuleQuery": 135,
"ruleTreeRuleSelectorInclude": 136,
"ruleTreeRuleSelectorExclude": 137,
"ruleTreeRuleSelectorFilter": 138,
"Plv8IsolationProvider": 139,
"JSminiExecutionProvider": 140,
"plv8SupportsJs": 141,
"Authorization": 142,
"GeneratedFrom": 143,
"ClientJSIsolationProvider": 144,
"clientSupportsJs": 145,
"Symbol": 146,
"symbolValue": 147,
"containTreeSymbol": 148,
"containTreeThen": 149,
"containTreeResolved": 150,
"containTreeRejected": 151,
"handlersTree": 152,
"handlersTreeHandler": 153,
"handlersTreeSupports": 154,
"handlersTreeHandleOperation": 155,
"HandleClient": 156,
"HandlingError": 157,
"handlingErrorValue": 158,
"HandlingErrorReason": 159,
"HandlingErrorLink": 160,
"GqlEndpoint": 161,
"MainGqlEndpoint": 162,
"HandleGql": 163,
"SupportsCompatable": 164,
"plv8JSSupportsCompatableHandleInsert": 165,
"plv8JSSupportsCompatableHandleUpdate": 166,
"plv8JSSupportsCompatableHandleDelete": 167,
"dockerJSSupportsCompatableHandleInsert": 168,
"dockerJSSupportsCompatableHandleUpdate": 169,
"dockerJSSupportsCompatableHandleDelete": 170,
"dockerJSSupportsCompatableHandleSchedule": 171,
"dockerJSSupportsCompatableHandlePort": 172,
"dockerJSSupportsCompatableHandleRoute": 173,
"clientJSSupportsCompatableHandleClient": 174,
"promiseTree": 175,
"promiseTreeAny": 176,
"promiseTreeThen": 177,
"promiseTreePromise": 178,
"promiseTreeResolved": 179,
"promiseTreeRejected": 180,
"promiseTreePromiseResult": 181,
"MigrationsEnd": 182
}
}

Add serialize_where.py

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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.