Skip to content

Instantly share code, notes, and snippets.

@solancer
Created August 20, 2024 14:01
Show Gist options
  • Save solancer/640bb30d3ba98f4c2c4470102ef11b4f to your computer and use it in GitHub Desktop.
Save solancer/640bb30d3ba98f4c2c4470102ef11b4f to your computer and use it in GitHub Desktop.
Convert Loopback 3 to Loopback 4 model
# Updated function to handle missing `base` property in the model JSON files.
def convert_lb3_to_lb4(lb3_model_content):
model_name = lb3_model_content['name']
base_model = lb3_model_content.get('base', 'Entity')
base_model = 'Entity' if base_model == 'PersistedModel' else base_model
# Start building the TypeScript model
ts_model = f"import {{Entity, hasMany, hasOne, belongsTo, model, property}} from '@loopback/repository';\n"
# Collect imports for related models
related_models = set()
for relation in lb3_model_content.get('relations', {}).values():
related_models.add(relation['model'])
if 'through' in relation:
related_models.add(relation['through'])
for rel_model in related_models:
ts_model += f"import {{{rel_model}}} from './{rel_model.lower()}.model';\n"
ts_model += "\n"
# Start the class definition
ts_model += f"@model({{\n"
ts_model += f" settings: {{\n"
# Add model settings
if 'strict' in lb3_model_content.get('settings', {}):
ts_model += f" strict: {lb3_model_content['settings']['strict']},\n"
if 'validateUpsert' in lb3_model_content.get('options', {}):
ts_model += f" validateUpsert: {str(lb3_model_content['options']['validateUpsert']).lower()},\n"
if 'mongodb' in lb3_model_content.get('settings', {}):
ts_model += f" mongodb: {lb3_model_content['settings']['mongodb']},\n"
ts_model += f" }},\n"
ts_model += f"}})\n"
ts_model += f"export class {model_name} extends {base_model} {{\n"
# Add properties
for prop_name, prop_details in lb3_model_content.get('properties', {}).items():
if isinstance(prop_details, dict):
prop_type = prop_details['type']
required = prop_details.get('required', False)
ts_model += f" @property({{\n"
ts_model += f" type: '{prop_type}',\n"
if required:
ts_model += f" required: true,\n"
ts_model += f" }})\n"
ts_model += f" {prop_name}?: {prop_type};\n\n"
# Add relations
for rel_name, rel_details in lb3_model_content.get('relations', {}).items():
relation_type = rel_details['type']
related_model = rel_details['model']
foreign_key = rel_details.get('foreignKey', None)
through_model = rel_details.get('through', None)
relation_decorator = ''
if relation_type == 'hasMany':
relation_decorator = f"@hasMany(() => {related_model}"
if through_model and isinstance(through_model, dict):
relation_decorator += f", {{through: () => {through_model['model']}}}"
elif foreign_key:
relation_decorator += f", {{keyTo: '{foreign_key}'}}"
relation_decorator += ")"
elif relation_type == 'hasOne':
relation_decorator = f"@hasOne(() => {related_model}"
if foreign_key:
relation_decorator += f", {{keyTo: '{foreign_key}'}}"
relation_decorator += ")"
elif relation_type == 'belongsTo':
relation_decorator = f"@belongsTo(() => {related_model}"
if foreign_key:
relation_decorator += f", {{keyTo: '{foreign_key}'}}"
relation_decorator += ")"
ts_model += f" {relation_decorator}\n"
ts_model += f" {rel_name}: {related_model}[];\n\n"
ts_model += f" constructor(data?: Partial<{model_name}>) {{\n"
ts_model += f" super(data);\n"
ts_model += f" }}\n"
ts_model += f"}}\n\n"
ts_model += f"export interface {model_name}Relations {{\n"
ts_model += f" // describe navigational properties here\n"
ts_model += f"}}\n"
ts_model += f"export type {model_name}WithRelations = {model_name} & {model_name}Relations;\n"
return ts_model
# Re-run the conversion process
converted_models = {}
for model_file in model_files:
if model_file.endswith('.json'):
model_json_path = os.path.join(lb3_models_path, model_file)
with open(model_json_path, 'r') as f:
model_content = json.load(f)
converted_models[model_file] = convert_lb3_to_lb4(model_content)
# Save the converted models to files
output_dir = '/mnt/data/LB4_models/'
os.makedirs(output_dir, exist_ok=True)
for model_file, ts_model in converted_models.items():
model_name = model_file.replace('.json', '.model.ts')
output_path = os.path.join(output_dir, model_name)
with open(output_path, 'w') as f:
f.write(ts_model)
# List the generated files
os.listdir(output_dir)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment