22import uuid
33import os
44import re
5+ import yaml
56from referencing import Registry , Resource
67from referencing .jsonschema import DRAFT4
78import requests
@@ -13,31 +14,49 @@ def __init__(self, serverless_config, open_api_spec, serverless_dir='.'):
1314 self .serverless_dir = serverless_dir
1415 self .models = self ._standardize_models ()
1516
17+ def _resolve_file_references (self , value ):
18+ if isinstance (value , dict ):
19+ return {k : self ._resolve_file_references (v ) for k , v in value .items ()}
20+ elif isinstance (value , list ):
21+ return [self ._resolve_file_references (item ) for item in value ]
22+ elif isinstance (value , str ):
23+ match = re .match (r'\${file\((.*)\)}' , value )
24+ if match :
25+ file_path = match .group (1 ).strip ()
26+ abs_path = os .path .join (self .serverless_dir , file_path )
27+ try :
28+ with open (abs_path , 'r' ) as f :
29+ if file_path .endswith ('.json' ):
30+ return json .load (f )
31+ else :
32+ return yaml .safe_load (f )
33+ except (IOError , yaml .YAMLError , json .JSONDecodeError ) as e :
34+ print (f"Warning: Could not read or parse file reference { abs_path } : { e } " )
35+ return value
36+ return value
37+
1638 def _standardize_models (self ):
17- documentation = self .serverless_config .get ('custom' , {})
18- if not documentation :
19- service_config = self .serverless_config .get ('service' , {})
20- if isinstance (service_config , dict ):
21- documentation = service_config .get ('custom' , {}).get ('documentation' , {})
22- else :
23- documentation = {}
39+ documentation = self .serverless_config .get ('custom' , {}).get ('documentation' , {})
2440
2541 standardized_models = []
2642 model_sources = []
2743 if 'models' in documentation :
28- models_config = documentation ['models' ]
44+ models_config = self . _resolve_file_references ( documentation ['models' ])
2945 if isinstance (models_config , list ):
3046 model_sources .extend (models_config )
3147 elif isinstance (models_config , dict ):
3248 for name , definition in models_config .items ():
3349 model_sources .append ({'name' : name , ** definition })
3450
3551 if 'modelsList' in documentation :
36- model_sources .extend (documentation ['modelsList' ])
52+ model_sources .extend (self . _resolve_file_references ( documentation ['modelsList' ]) )
3753
3854 for model in model_sources :
3955 if not isinstance (model , dict ) or 'name' not in model :
4056 continue
57+
58+ model = self ._resolve_file_references (model )
59+
4160 std_model = {
4261 'name' : model .get ('name' ),
4362 'description' : model .get ('description' , '' ),
@@ -68,24 +87,6 @@ def create_schema(self, name, schema_definition):
6887 self .open_api ['components' ]['schemas' ][name ] = final_schema
6988 return f"#/components/schemas/{ name } "
7089
71- def _resolve_file_references (self , value ):
72- if isinstance (value , dict ):
73- return {k : self ._resolve_file_references (v ) for k , v in value .items ()}
74- elif isinstance (value , list ):
75- return [self ._resolve_file_references (item ) for item in value ]
76- elif isinstance (value , str ):
77- match = re .match (r'\${file\((.*)\)}' , value )
78- if match :
79- file_path = match .group (1 ).strip ()
80- abs_path = os .path .join (self .serverless_dir , file_path )
81- try :
82- with open (abs_path , 'r' ) as f :
83- return json .load (f )
84- except (IOError , json .JSONDecodeError ) as e :
85- print (f"Warning: Could not read or parse file reference { abs_path } : { e } " )
86- return value
87- return value
88-
8990 def _resolve_schema_references (self , schema ):
9091 schema = self ._resolve_file_references (schema )
9192 if not isinstance (schema , dict ):
0 commit comments