@ -9,7 +9,7 @@ import logging
from datetime import datetime
import inflect
class SwiftModel Generator:
class LeStorage Generator:
def __init__ ( self , json_data : Dict [ str , Any ] ) :
self . data = json_data
self . pluralizer = inflect . engine ( )
@ -27,7 +27,7 @@ class SwiftModelGenerator:
token_exempted = model_data . get ( " tokenExemptedMethods " , [ ] )
copy_server_response = model_data . get ( " copy_server_response " , " false " )
lines = [ " // Generated by SwiftModel Generator " , " // Do not modify this file manually " , " " ]
lines = [ " // Generated by LeStorage Generator " , " // Do not modify this file manually " , " " ]
# Import statement
lines . append ( " import Foundation " )
@ -102,6 +102,11 @@ class SwiftModelGenerator:
lines . extend ( self . _generate_copy_method ( model_name , properties ) )
lines . append ( " " )
# Copy method
# if is_sync:
# lines.extend(self._generate_copy_for_update_method(model_name, properties))
# lines.append("")
# Add relationships function
lines . extend ( self . _generate_relationships ( model_name , properties ) )
lines . append ( " " )
@ -178,21 +183,21 @@ class SwiftModelGenerator:
method_name = f " { prop_name } Value "
is_optional = prop . get ( " optional " , False )
lines . extend ( [ f " func { method_name } () -> { foreign_key . rstrip ( ' * ' ) } ? {{ " ] )
lines . extend ( [ f " func { method_name } () -> { foreign_key . rstrip ( ' ### ' ) } ? {{ " ] )
if is_optional :
lines . extend ( [
f " guard let { prop_name } = self. { prop_name } else {{ return nil }} "
] )
if foreign_key . endswith ( " * " ) :
if foreign_key . endswith ( " ### " ) :
foreign_key = foreign_key [ : - 1 ] # Remove the asterisk
lines . extend ( [
f " return self.store?.findById( { prop_name } ) "
f " return self.store?.storeCenter.mainStore. findById( { prop_name } ) "
] )
else :
lines . extend ( [
f " return Store.main .findById( { prop_name } ) "
f " return self.store? .findById( { prop_name } ) "
] )
lines . extend ( [ " } " , " " ] ) # Close the method and add a blank line
@ -393,6 +398,31 @@ class SwiftModelGenerator:
lines . append ( " } " )
return lines
def _generate_copy_for_update_method ( self , model_name : str , properties : List [ Dict [ str , Any ] ] ) - > List [ str ] :
model_variable = model_name . lower ( )
lines = [ f " public func copyForUpdate(from other: any Storable) {{ " ]
lines . append ( f " guard let { model_variable } = other as? Base { model_name } else {{ return }} " )
# First handle foreign key properties with special deletion logic
for prop in properties :
if " foreignKey " in prop and prop [ " foreignKey " ] != " CustomUser " :
name = prop [ " name " ]
foreign_key = prop [ " foreignKey " ] . rstrip ( ' ### ' ) # Remove asterisk if present
foreign_variable = name + " Value "
# Generate the foreign key check and deletion logic
lines . append ( f " if { model_variable } . { name } != self. { name } , let { name } Object = self. { foreign_variable } (), { name } Object.shared == true, let store = { name } Object.store {{ " )
lines . append ( f " store.deleteUnusedShared( { name } Object) " )
lines . append ( f " }} " )
# Then copy all properties
for prop in properties :
name = prop [ ' name ' ]
lines . append ( f " self. { name } = { model_variable } . { name } " )
lines . append ( " } " )
return lines
def _generate_protocol_requirements ( self , resource_name : str , token_exempted : List [ str ] , copy_server_response : str ) - > List [ str ] :
""" Generate the static functions required by SyncedStorable protocol. """
# Convert HTTP methods to proper format
@ -426,8 +456,9 @@ class SwiftModelGenerator:
# Generate relationship entries
for prop in foreign_key_props :
name = prop [ " name " ]
foreign_key = prop [ " foreignKey " ] . rstrip ( ' * ' ) # Remove asterisk if present
lines . append ( f " Relationship(type: { foreign_key } .self, keyPath: \\ Base { model_name } . { name } ), " )
located_on_main_store = " true " if prop [ " foreignKey " ] . endswith ( ' ### ' ) else " false "
foreign_key = prop [ " foreignKey " ] . rstrip ( ' ### ' ) # Remove asterisk if present
lines . append ( f " Relationship(type: { foreign_key } .self, keyPath: \\ Base { model_name } . { name } , mainStoreLookup: { located_on_main_store } ), " )
# Close the array and function
lines . extend ( [
@ -488,7 +519,7 @@ def process_directory(input_dir: str, output_dir: str, logger: logging.Logger, d
with open ( json_file , ' r ' ) as f :
json_data = json . load ( f )
generator = SwiftModel Generator( json_data )
generator = LeStorage Generator( json_data )
# Generate each model in the JSON file
for model in json_data [ " models " ] :
@ -524,7 +555,7 @@ def process_directory(input_dir: str, output_dir: str, logger: logging.Logger, d
def setup_logging ( verbose : bool ) - > logging . Logger :
""" Configure logging based on verbosity level. """
logger = logging . getLogger ( ' SwiftModel Generator' )
logger = logging . getLogger ( ' LeStorage Generator' )
handler = logging . StreamHandler ( )
if verbose :