diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index d51f259..b511737 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -38,7 +38,8 @@ // Add the IDs of extensions you want installed when the container is created. "extensions": [ "ms-python.python", - "ms-python.vscode-pylance" + "ms-python.vscode-pylance", + "ShivaPrasanth.dothttp-code" ] } }, @@ -47,7 +48,7 @@ // "forwardPorts": [], // Use 'postCreateCommand' to run commands after the container is created. - // "postCreateCommand": "pip3 install --user -r requirements.txt", + "postCreateCommand": "pip3 install --user -r all_requirements.txt", // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. "remoteUser": "vscode", diff --git a/Dockerfile b/Dockerfile index 38116f6..877f191 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.12 +FROM python:3.11 LABEL io.whalebrew.config.networks '["host"]' ADD requirements.txt /app/ WORKDIR /app diff --git a/dotextensions/server/handlers/basic_handlers.py b/dotextensions/server/handlers/basic_handlers.py index cefc2f7..2d9184f 100644 --- a/dotextensions/server/handlers/basic_handlers.py +++ b/dotextensions/server/handlers/basic_handlers.py @@ -283,19 +283,34 @@ def run(self, command: Command) -> Result: def execute(self, command: Command, filename): with open(filename) as f: http_data = f.read() - all_names, all_urls = self.parse_n_get(http_data) + all_names, all_urls, imported_names, imported_urls = self.parse_n_get( + http_data, filename) result = Result( id=command.id, result={ "names": all_names, - "urls": all_urls}) + "urls": all_urls, + "imports": { + "names": imported_names, + "urls": imported_urls + } + }) return result - def parse_n_get(self, http_data): - model = dothttp_model.model_from_str(http_data) + def parse_n_get(self, http_data, filename: str): + model: MultidefHttp = dothttp_model.model_from_str(http_data) all_names = [] all_urls = [] - for index, http in enumerate(model.allhttps): + imported_names = [] + imported_urls = [] + self.get_for_http(model.allhttps, all_names, all_urls) + for new_model, _content in BaseModelProcessor._get_models_from_import(model, filename): + self.get_for_http(new_model.allhttps, + imported_names, imported_urls) + return all_names, all_urls, imported_names, imported_urls + + def get_for_http(self, allhttps, all_names, all_urls): + for index, http in enumerate(allhttps): if http.namewrap: name = http.namewrap.name if http.namewrap else str(index) start = http.namewrap._tx_position @@ -318,7 +333,6 @@ def parse_n_get(self, http_data): } all_names.append(name) all_urls.append(url) - return all_names, all_urls class ContentNameReferencesHandler(GetNameReferencesHandler): @@ -329,10 +343,25 @@ def get_method(self): def execute(self, command, filename): http_data = command.params.get("content", "") - all_names, all_urls = self.parse_n_get(http_data) + context = command.params.get("context", []) + all_names, all_urls, imported_names, imported_urls = self.parse_n_get( + http_data, filename) + for context_context in context: + try: + _all_names, _all_urls, _imported_names, _imported_urls = self.parse_n_get( + context_context, filename) + imported_names += _all_names + _imported_names + imported_urls += _all_urls + _imported_urls + except: + pass result = Result( id=command.id, result={ "names": all_names, - "urls": all_urls}) + "urls": all_urls, + "imports": { + "names": imported_names, + "urls": imported_urls + } + }) return result diff --git a/dothttp/__init__.py b/dothttp/__init__.py index 4614146..7c15e52 100644 --- a/dothttp/__init__.py +++ b/dothttp/__init__.py @@ -522,16 +522,23 @@ def load_model(self): self.model: MultidefHttp = model def load_imports(self): - import_list = [] - BaseModelProcessor._load_imports( - self.model, self.file, self.property_util, import_list) - self.model.allhttps += import_list + self._load_imports(self.model, self.file, + self.property_util, self.model.allhttps) - def _load_imports( + @staticmethod + def _load_imports(model: "BaseModelProcessor", + filename: str, + property_util: PropertyProvider, + import_list: [] + ): + for model, content in BaseModelProcessor._get_models_from_import(model, filename): + import_list += model.allhttps + property_util.add_infile_properties(content) + + @staticmethod + def _get_models_from_import( model: MultidefHttp, - filename: str, - property_util: PropertyProvider, - import_list: List[Http]): + filename: str): if not model.import_list: return for filename_string in model.import_list.filename: @@ -552,15 +559,13 @@ def _load_imports( try: imported_model = dothttp_model.model_from_str( imported_content) - import_list += imported_model.allhttps - property_util.add_infile_properties(imported_content) - BaseModelProcessor._load_imports( - imported_model, import_file, property_util, import_list) + yield imported_model, imported_content except TextXSyntaxError as e: raise HttpFileSyntaxException( file=import_file, message=e.args) except Exception as e: raise HttpFileException(message=e.args) + yield from BaseModelProcessor._get_models_from_import(imported_model, import_file) return def load_content(self): diff --git a/dothttp/http.tx b/dothttp/http.tx index 9d8c399..3beea6e 100644 --- a/dothttp/http.tx +++ b/dothttp/http.tx @@ -1,5 +1,5 @@ //HTTP: ram=HTTP2 -MULTISET: (import_list=IMPORT)? allhttps=HTTP+; +MULTISET: (import_list=IMPORT)? (allhttps=HTTP+)?; IMPORT: ('import' filename=String ';')* ; @@ -123,7 +123,7 @@ PAYLOAD: ( // reordered to provide max performance // most http requests has json input,or urlencoded as input - ('json' '(' json=JSON ')' ) + ('json'? '('? json=JSON ')'? ) | ('data' | 'urlencoded') '(' datajson=JSON (',' type=STRING)? ','? ')' | ('data'| 'text') '(' data+=TRIPLE_OR_DOUBLE_STRING ((','|';') type=STRING)? ','? ')' | (fileswrap=FILES) diff --git a/examples/example.http b/examples/example.http index 7b49eaa..bfcef54 100644 --- a/examples/example.http +++ b/examples/example.http @@ -7,7 +7,11 @@ GET https://req.dothttp.dev/user ? projection, name ? projection, org ? projection, location + +{ + "payload": {{$randomSlug}} +} > {% client.global.set("Server", response.headers.valueOf("Server")); - client.log('server is :'+ value); + client.log('server is :'+ client.global.get('Server')); %} diff --git a/test/extensions/test_commands.py b/test/extensions/test_commands.py index fe8b8c9..6d7ea4f 100644 --- a/test/extensions/test_commands.py +++ b/test/extensions/test_commands.py @@ -17,6 +17,7 @@ class TargetTest(TestBase): def setUp(self) -> None: + self.maxDiff = None self.name_handler = GetNameReferencesHandler() def test_names(self): @@ -59,8 +60,13 @@ def execute_and_compare_names(self, result): {'end': 387, 'method': 'POST', 'start': 359, - 'url': 'https://req.dothttp.dev'}]}, - result.result) + 'url': 'https://req.dothttp.dev'}], + "imports": { + "names": [], + "urls": [] + } + }, + result.result) def test_content_names2(self): filename = f"{command_dir}/names.http"