|
|
|
import server.models.models
|
|
|
|
from server.models.models import Jsonifiable
|
|
|
|
from neomodel import StructuredNode, StringProperty, RelationshipManager, \
|
|
|
|
UniqueIdProperty, DateProperty, StructuredRel, DateTimeProperty, StructuredRel, \
|
|
|
|
Property, RelationshipDefinition
|
|
|
|
import json
|
|
|
|
|
|
|
|
from typing import Type, Tuple, Dict, List, Optional, Generator
|
|
|
|
|
|
|
|
|
|
|
|
def constructor(cls: Type[StructuredNode]) -> str:
|
|
|
|
return 'constructor(json) {\n' + \
|
|
|
|
f' super(json)\n' + \
|
|
|
|
' }'
|
|
|
|
|
|
|
|
|
|
|
|
def get_set_attr(name, attr) -> str:
|
|
|
|
if RelationshipDefinition in attr.__class__.__mro__:
|
|
|
|
return f"""
|
|
|
|
get_{name}() {{
|
|
|
|
return this._get_relation('{name}')
|
|
|
|
}}
|
|
|
|
|
|
|
|
link_{name}(ref) {{
|
|
|
|
return this._link_relation('{name}', ref)
|
|
|
|
}}
|
|
|
|
|
|
|
|
unlink_{name}(ref) {{
|
|
|
|
return this._unlink_relation('{name}', ref)
|
|
|
|
}}
|
|
|
|
"""
|
|
|
|
else:
|
|
|
|
return f"""
|
|
|
|
get_{name}() {{
|
|
|
|
return this.json.{name}
|
|
|
|
}}
|
|
|
|
""" + f"""
|
|
|
|
set_{name}(new_val) {{
|
|
|
|
this._set('{name}', new_val)
|
|
|
|
}}
|
|
|
|
""" if name != 'uid' else ''
|
|
|
|
|
|
|
|
|
|
|
|
def all_attrs(cls):
|
|
|
|
return '\n'.join([ get_set_attr(name, val) for name, val in get_relevant_attributes(cls)])
|
|
|
|
|
|
|
|
|
|
|
|
def js_representation(cls: Type[StructuredNode]) -> str:
|
|
|
|
props, rels = get_properties_and_relations(cls)
|
|
|
|
return f"""models.{cls.__name__} = class {cls.__name__} extends StructuredNode {{
|
|
|
|
{constructor(cls)}
|
|
|
|
|
|
|
|
{all_attrs(cls)}
|
|
|
|
}}
|
|
|
|
|
|
|
|
StructuredNode.registerClassDefinition(models.{cls.__name__}, {json.dumps(props)}, {json.dumps(rels)})
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
def get_relevant_attributes(cls: Type[StructuredNode]) -> Generator[None, Tuple[str, Property], None]:
|
|
|
|
for name, value in vars(cls).items():
|
|
|
|
if name[0] == '_' or name[0].isupper() and not isinstance(value, (RelationshipDefinition, Property)):
|
|
|
|
continue
|
|
|
|
yield name, value
|
|
|
|
|
|
|
|
|
|
|
|
def get_properties_and_relations(cls) -> Tuple[Dict[str, dict], Dict[str, dict]]:
|
|
|
|
props = dict()
|
|
|
|
rels = dict()
|
|
|
|
for name, value in get_relevant_attributes(cls):
|
|
|
|
if isinstance(value, RelationshipDefinition):
|
|
|
|
target_cls = value._raw_class.__name__ if not isinstance(value._raw_class, str) else value._raw_class
|
|
|
|
rels[name] = {
|
|
|
|
'field': name,
|
|
|
|
'target': target_cls,
|
|
|
|
'cardinality': value.manager.__name__
|
|
|
|
}
|
|
|
|
elif isinstance(value, Property):
|
|
|
|
props[name] = {
|
|
|
|
'field': name,
|
|
|
|
'type': value.__class__.__name__,
|
|
|
|
'required': value.required
|
|
|
|
}
|
|
|
|
|
|
|
|
return props, rels
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
reps = list()
|
|
|
|
reps.append("// This file was generated by running js_conversion.py\n" +
|
|
|
|
"// It converts the neomodel declaration of this element into js classes.\n" +
|
|
|
|
"(() => {\nconst models = window.models || {}")
|
|
|
|
|
|
|
|
for name, cls in vars(server.models.models).items():
|
|
|
|
if hasattr(cls, '__mro__') and StructuredNode in cls.__mro__ and StructuredNode != cls.__mro__[0]:
|
|
|
|
reps.append(js_representation(cls))
|
|
|
|
|
|
|
|
reps.append('window.models = models;\n})()')
|
|
|
|
|
|
|
|
print('\n\n\n'.join(reps))
|