{"config":{"indexing":"full","lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"index.html","text":"Lama2 : Free, Lightweight & Collaborative API Client \u00b6 The Problem \u00b6 Most engineering teams have trouble collaborating on APIs or end up paying too much for Postman/Insomnia. Our 100% FOSS product Lama2 helps your team collaborate on APIs for free based on git, so that you can save money and avoid friction. About \u00b6 Lama2 is a Plain-Text powered REST API client & manager built for serious engineering teams. Lama2 specifies the .l2 syntax for describing APIs, and implements a CLI to execute .l2 files. Engineers collaborate on .l2 files using version control. Lama2 integrates nicely with IDEs and text-editors as well. Think of Lama2 as Markdown for APIs. Benefits \u00b6 Plain-Text files: Store APIs in the Plain-Text .l2 API files. Simple and human-friendly syntax. Learn basics within minutes! Simple CLI: Launch the CLI tool l2 on API files to make REST API requests. Editor support: Invoke Lama2 from your favorite text editor or IDE. Helpful documentation and tool support to build editor extensions included. Longevity & track-ability: Commit .l2 files to git or other version control for long life & change tracking. Collaboration: Share API repo with teammates and colleagues to collaborate Code generation: Convert l2 API definitions into your preferred language/library, be it Python, Javascript, Java or many other options. Powerful chaining: Chain multiple l2 requests through embedded Javascript blocks Documentation: Explore examples, how-tos, explanations, references, FAQ/RAQs, and diagrams. Documentation is a priority, so that you never have to get lost. Extensibility: .l2 syntax is implemented as a recursive descent parser , based on a formal grammar . Dig into details and implement new syntax (ex: to support websockets ) Tip Coming from postman? Let Lama2 help you convert Postman data dumps into a nice Plain-Text Lama2 repo. Terminal Demo: A POST request \u00b6 basic_post.l2 : POST https://httpbin.org/post { \"hello\": \"world\" } --- _METADATA={ \"api_name\": \"Basic POST\", \"sample_response\": { \"args\": {}, \"data\": \"{\\\"hello\\\":\\\"world\\\"}\", \"files\": {}, \"form\": {}, \"headers\": { \"Accept\": \"*/*\", \"Accept-Encoding\": \"gzip, deflate\", \"Content-Length\": \"17\", \"Content-Type\": \"application/json\", \"Host\": \"httpbin.org\", \"User-Agent\": \"python-requests/2.25.1\", \"X-Amzn-Trace-Id\": \"Root=1-6686d0e6-336395f75a7f8a8b474a7563\" }, \"json\": { \"hello\": \"world\" }, \"origin\": \"20.235.244.147\", \"url\": \"https://httpbin.org/post\" } } Execute: l2 basic_post.l2 VSCode Demo: The same POST request \u00b6 Community and Support \u00b6 Full documentation @hexmos.com/lama2 Report issues and propose improvements at Github issues Discuss with the community at Discord","title":"Home"},{"location":"index.html#lama2-free-lightweight-collaborative-api-client","text":"","title":"Lama2: Free, Lightweight &amp; Collaborative API Client"},{"location":"index.html#the-problem","text":"Most engineering teams have trouble collaborating on APIs or end up paying too much for Postman/Insomnia. Our 100% FOSS product Lama2 helps your team collaborate on APIs for free based on git, so that you can save money and avoid friction.","title":"The Problem"},{"location":"index.html#about","text":"Lama2 is a Plain-Text powered REST API client & manager built for serious engineering teams. Lama2 specifies the .l2 syntax for describing APIs, and implements a CLI to execute .l2 files. Engineers collaborate on .l2 files using version control. Lama2 integrates nicely with IDEs and text-editors as well. Think of Lama2 as Markdown for APIs.","title":"About"},{"location":"index.html#benefits","text":"Plain-Text files: Store APIs in the Plain-Text .l2 API files. Simple and human-friendly syntax. Learn basics within minutes! Simple CLI: Launch the CLI tool l2 on API files to make REST API requests. Editor support: Invoke Lama2 from your favorite text editor or IDE. Helpful documentation and tool support to build editor extensions included. Longevity & track-ability: Commit .l2 files to git or other version control for long life & change tracking. Collaboration: Share API repo with teammates and colleagues to collaborate Code generation: Convert l2 API definitions into your preferred language/library, be it Python, Javascript, Java or many other options. Powerful chaining: Chain multiple l2 requests through embedded Javascript blocks Documentation: Explore examples, how-tos, explanations, references, FAQ/RAQs, and diagrams. Documentation is a priority, so that you never have to get lost. Extensibility: .l2 syntax is implemented as a recursive descent parser , based on a formal grammar . Dig into details and implement new syntax (ex: to support websockets ) Tip Coming from postman? Let Lama2 help you convert Postman data dumps into a nice Plain-Text Lama2 repo.","title":"Benefits"},{"location":"index.html#terminal-demo-a-post-request","text":"basic_post.l2 : POST https://httpbin.org/post { \"hello\": \"world\" } --- _METADATA={ \"api_name\": \"Basic POST\", \"sample_response\": { \"args\": {}, \"data\": \"{\\\"hello\\\":\\\"world\\\"}\", \"files\": {}, \"form\": {}, \"headers\": { \"Accept\": \"*/*\", \"Accept-Encoding\": \"gzip, deflate\", \"Content-Length\": \"17\", \"Content-Type\": \"application/json\", \"Host\": \"httpbin.org\", \"User-Agent\": \"python-requests/2.25.1\", \"X-Amzn-Trace-Id\": \"Root=1-6686d0e6-336395f75a7f8a8b474a7563\" }, \"json\": { \"hello\": \"world\" }, \"origin\": \"20.235.244.147\", \"url\": \"https://httpbin.org/post\" } } Execute: l2 basic_post.l2","title":"Terminal Demo: A POST request"},{"location":"index.html#vscode-demo-the-same-post-request","text":"","title":"VSCode Demo: The same POST request"},{"location":"index.html#community-and-support","text":"Full documentation @hexmos.com/lama2 Report issues and propose improvements at Github issues Discuss with the community at Discord","title":"Community and Support"},{"location":"about/contact.html","text":"Discord \u00b6 Join Hexmos Lama2 discord server to discuss with the community Email \u00b6 Drop an email to shrijith 'at' hexmos.com Github Issues & Discussions \u00b6 Report issues and propose improvements at Github Issues and Github Discussions","title":"Talk to us"},{"location":"about/contact.html#discord","text":"Join Hexmos Lama2 discord server to discuss with the community","title":" Discord"},{"location":"about/contact.html#email","text":"Drop an email to shrijith 'at' hexmos.com","title":" Email"},{"location":"about/contact.html#github-issues-discussions","text":"Report issues and propose improvements at Github Issues and Github Discussions","title":" Github Issues &amp; Discussions"},{"location":"about/hexmos.html","text":"We at Hexmos are deeply concerned about the state of organizations all across the world. We possess firm convictions and aspiration towards improving organizational health across the world . Through deep R&D, good software, relevant tools and techniques, we work to improve organizational health. For a sample of our R&D, check these resources out: Turnover and Other Organizational Ailments : A deeply research-backed exploration into the roots of organizational troubles and their cures, this book assimilates 80+ longitudinal and empirical studies to provide recommendations to improve organizational health. Hexmos Feedback , a tool to provide continuous feedback to your colleagues, so that not a single beneficial thing said or done goes unnoticed","title":"Hexmos"},{"location":"explanation/faq.html","text":"FAQs/RAQs \u00b6 Why pick Javascript as the scripting/glue language? \u00b6 Lama2's design philosophy advocates \"delegate to mature and preferably open tools\". After analysis, we finally picked JS due to following reasons: Most people working with APIs probably already know JS Easy to support XPath/JSONPath or even JQ clones right into JS Even if you don't know any of (2), simple JS object notation + good old loops will take you far Native support for JSON (and dom manipulation is common too, for xml type responses) Good amount of power for implementation effort exerted For simple use cases, one barely has to understand any serious JS. Object/map notation is quite intuitive. Ultimately, we believe JS passes our \"Intern Test\" for usability. What is the Intern Test ? \u00b6 Lama2 API files must remain easy for interns to get used with minimal handholding from more experienced engineers. If it doesn't work for interns, then it doesn't work for our teams at Hexmos as well. Why did you create Lama2 ? \u00b6 At Hexmos , our engineering infrastructure is split into dozens of self-contained software services. We deal with 100s of internal APIs, and so felt a need for a robust workflow for defining, sharing and updating APIs within our teams. Traditional solutions such as Postman/Insomnia implement the collaboration features within their applications, and also tend to charge a fee for collaboration. We felt using git is the right way to collaborate on APIs, rather than any custom built solution. So, in a matter of 2-days we got a regex-based prototype DSL language to store API files. Lots of issues cropped up over time, but we kept making improvements to Lama2 as needs arose. Hexmos accumulated 100s of APIS over time. Then, we decided that the tool deserves to be out there, benefitting teams that want to collaborate on APIs over git . So, to make it happen, first we invested into formalizing the grammar, and implementing the DSL as a hand-written recursive descent parser. Then we invested into helpful documentation, demos and so on. Once we had the basics, we released Lama2 into the world.","title":"FAQ/RAQ"},{"location":"explanation/faq.html#faqsraqs","text":"","title":"FAQs/RAQs"},{"location":"explanation/faq.html#why-pick-javascript-as-the-scriptingglue-language","text":"Lama2's design philosophy advocates \"delegate to mature and preferably open tools\". After analysis, we finally picked JS due to following reasons: Most people working with APIs probably already know JS Easy to support XPath/JSONPath or even JQ clones right into JS Even if you don't know any of (2), simple JS object notation + good old loops will take you far Native support for JSON (and dom manipulation is common too, for xml type responses) Good amount of power for implementation effort exerted For simple use cases, one barely has to understand any serious JS. Object/map notation is quite intuitive. Ultimately, we believe JS passes our \"Intern Test\" for usability.","title":"Why pick Javascript as the scripting/glue language?"},{"location":"explanation/faq.html#what-is-the-intern-test","text":"Lama2 API files must remain easy for interns to get used with minimal handholding from more experienced engineers. If it doesn't work for interns, then it doesn't work for our teams at Hexmos as well.","title":"What is the Intern Test?"},{"location":"explanation/faq.html#why-did-you-create-lama2","text":"At Hexmos , our engineering infrastructure is split into dozens of self-contained software services. We deal with 100s of internal APIs, and so felt a need for a robust workflow for defining, sharing and updating APIs within our teams. Traditional solutions such as Postman/Insomnia implement the collaboration features within their applications, and also tend to charge a fee for collaboration. We felt using git is the right way to collaborate on APIs, rather than any custom built solution. So, in a matter of 2-days we got a regex-based prototype DSL language to store API files. Lots of issues cropped up over time, but we kept making improvements to Lama2 as needs arose. Hexmos accumulated 100s of APIS over time. Then, we decided that the tool deserves to be out there, benefitting teams that want to collaborate on APIs over git . So, to make it happen, first we invested into formalizing the grammar, and implementing the DSL as a hand-written recursive descent parser. Then we invested into helpful documentation, demos and so on. Once we had the basics, we released Lama2 into the world.","title":"Why did you create Lama2?"},{"location":"explanation/l2format.html","text":"Find in this page an informal description of the rules for authoring .l2 API files. This document expects some familiarity with Lama2 . To quickly get started with Lama2 , head over to Examples . On the other hand, if you are a developer and wish to learn more about the formal grammar underlying l2 , visit the Grammar section. Comments start with # \u00b6 Lines starting with # are comments and hence ignored altogether All HTTP Verbs supported - including the common GET/POST/PUT \u00b6 Fully supported: GET|HEAD|POST|PUT|DELETE|CONNECT|OPTIONS|TRACE|PATCH JSON is the default submission type, but MULTIPART is supported too \u00b6 varjson is a simpler syntax to specify flat JSONs \u00b6 varjson values are defined as follows: hello=world foo=bar The above results in a JSON submission of the form: { \"hello\": \"world\", \"foo\": \"bar\" } Nested JSON can simply be dumped at the end of the document \u00b6 The JSON recognition engine is quite lenient. It can deal with minor errors in the format (such as having single quotes instead of double quotes, trailing garbage, or an extra comma after the last element in an array,). POST https://httpbin.org/post { \"a\": \"b\", \"c\": \"d\" } MULTIPART allows both file uploads & the usual fields \u00b6 Example: POST MULTIPART http://localhost:8000/register userid=lince5 file@./helloworld.jpg Note The file path is relative to the request file. Cookies are sent as headers \u00b6 Cookies are specified in a Cookie header as follows: Cookie:'sessionid=foo;another-cookie=bar' Environment Variables \u00b6 API variables can be defined in apirequest.l2 \u00b6 Variables are declared within the JS processor block and serve as dynamic placeholders for data used in API requests. By utilizing these variables, L2 enables flexibility and reusability in defining API endpoints and data payloads. Example login.l2 : let REMOTE = \"httpbin.org\" let EMAIL = \"customer1@gmail.com\" --- POST ${REMOTE}/login { \"email\": \"${EMAIL}\", \"password\": \"customer1@gmail.com\" } Get Source Files API environment variables can be defined locally in l2.env \u00b6 L2 provides a convenient way to define environment variables through the l2.env file. This file is automatically searched for in the present directory, and its contents are loaded to create a set of variables (local). In the l2.env file, you can specify environment-specific values for variables used in your L2 scripts, such as URLs, authentication tokens, or any other data that may vary depending on the environment in which the API requests are executed. Go to Example Get Source File API environment variables can be defined at project root using l2config.env \u00b6 The l2config.env file serves as a centralized storage for environment variables located at the project root, streamlining the management of configuration settings across all L2 scripts. With this file present, every L2 script within the project automatically inherits the defined variables, effectively eliminating the necessity to duplicate configurations in individual subdirectories using l2.env . The search for l2config.env extends from the present directory up to the root directory ( / ). During this process, the variables defined in the root file are loaded and made available for use in all relevant scripts. This approach significantly enhances efficiency and maintainability, as it ensures consistent settings throughout the project while reducing redundancy in configuration data. Go to Example Get Source File If l2config.env (root) variables are redeclared in l2.env (local) \u00b6 In situations where both root and local variables share the same variable name, the local variable takes precedence over the root variable. This behavior remains consistent, even if both l2config.env (root) and l2.env (local) files reside in the same directory. The local variable's value will always be considered over the root variable, ensuring that specific configurations defined at the local level effectively override any corresponding settings present in the root file. This approach provides developers with granular control and flexibility in tailoring environment variables to suit specific needs within different parts of the project while maintaining the overall structure and organization of configuration settings. Go to Example Get Source File The environment file can load results of commands \u00b6 Use the backtick notation \\ command`` to place the results of commands into environment variables: export PHOTO=`base64 image.jpeg` One can load the PHOTO variable in API files. Chain requests through Javascript blocks \u00b6 Lama2 supports plain Javascript (JS) blocks as a glue for manipulating responses and passing on values to later stages. At a higher level, a chain of requests may look like: Javascript 1 --- L2 Request 1 --- Javscript 2 --- L2 Request 2 The triple-dash ( --- ) separator is mandatory. The special variable result contains the response from previous stages. For example, in the above case, Javascript 2 can access the response from L2 Request 1 through the result variable. Learn more about request chaining in Examples .","title":"The l2 Format"},{"location":"explanation/l2format.html#comments-start-with","text":"Lines starting with # are comments and hence ignored altogether","title":"Comments start with #"},{"location":"explanation/l2format.html#all-http-verbs-supported-including-the-common-getpostput","text":"Fully supported: GET|HEAD|POST|PUT|DELETE|CONNECT|OPTIONS|TRACE|PATCH","title":"All HTTP Verbs supported - including the common GET/POST/PUT"},{"location":"explanation/l2format.html#json-is-the-default-submission-type-but-multipart-is-supported-too","text":"","title":"JSON is the default submission type, but MULTIPART is supported too"},{"location":"explanation/l2format.html#varjson-is-a-simpler-syntax-to-specify-flat-jsons","text":"varjson values are defined as follows: hello=world foo=bar The above results in a JSON submission of the form: { \"hello\": \"world\", \"foo\": \"bar\" }","title":"varjson is a simpler syntax to specify flat JSONs"},{"location":"explanation/l2format.html#nested-json-can-simply-be-dumped-at-the-end-of-the-document","text":"The JSON recognition engine is quite lenient. It can deal with minor errors in the format (such as having single quotes instead of double quotes, trailing garbage, or an extra comma after the last element in an array,). POST https://httpbin.org/post { \"a\": \"b\", \"c\": \"d\" }","title":"Nested JSON can simply be dumped at the end of the document"},{"location":"explanation/l2format.html#multipart-allows-both-file-uploads-the-usual-fields","text":"Example: POST MULTIPART http://localhost:8000/register userid=lince5 file@./helloworld.jpg Note The file path is relative to the request file.","title":"MULTIPART allows both file uploads &amp; the usual fields"},{"location":"explanation/l2format.html#cookies-are-sent-as-headers","text":"Cookies are specified in a Cookie header as follows: Cookie:'sessionid=foo;another-cookie=bar'","title":"Cookies are sent as headers"},{"location":"explanation/l2format.html#environment-variables","text":"","title":"Environment Variables"},{"location":"explanation/l2format.html#api-variables-can-be-defined-in-apirequestl2","text":"Variables are declared within the JS processor block and serve as dynamic placeholders for data used in API requests. By utilizing these variables, L2 enables flexibility and reusability in defining API endpoints and data payloads. Example login.l2 : let REMOTE = \"httpbin.org\" let EMAIL = \"customer1@gmail.com\" --- POST ${REMOTE}/login { \"email\": \"${EMAIL}\", \"password\": \"customer1@gmail.com\" } Get Source Files","title":"API variables can be defined in apirequest.l2"},{"location":"explanation/l2format.html#api-environment-variables-can-be-defined-locally-in-l2env","text":"L2 provides a convenient way to define environment variables through the l2.env file. This file is automatically searched for in the present directory, and its contents are loaded to create a set of variables (local). In the l2.env file, you can specify environment-specific values for variables used in your L2 scripts, such as URLs, authentication tokens, or any other data that may vary depending on the environment in which the API requests are executed. Go to Example Get Source File","title":"API environment variables can be defined locally in l2.env"},{"location":"explanation/l2format.html#api-environment-variables-can-be-defined-at-project-root-using-l2configenv","text":"The l2config.env file serves as a centralized storage for environment variables located at the project root, streamlining the management of configuration settings across all L2 scripts. With this file present, every L2 script within the project automatically inherits the defined variables, effectively eliminating the necessity to duplicate configurations in individual subdirectories using l2.env . The search for l2config.env extends from the present directory up to the root directory ( / ). During this process, the variables defined in the root file are loaded and made available for use in all relevant scripts. This approach significantly enhances efficiency and maintainability, as it ensures consistent settings throughout the project while reducing redundancy in configuration data. Go to Example Get Source File","title":"API environment variables can be defined at project root using l2config.env"},{"location":"explanation/l2format.html#if-l2configenvroot-variables-are-redeclared-in-l2envlocal","text":"In situations where both root and local variables share the same variable name, the local variable takes precedence over the root variable. This behavior remains consistent, even if both l2config.env (root) and l2.env (local) files reside in the same directory. The local variable's value will always be considered over the root variable, ensuring that specific configurations defined at the local level effectively override any corresponding settings present in the root file. This approach provides developers with granular control and flexibility in tailoring environment variables to suit specific needs within different parts of the project while maintaining the overall structure and organization of configuration settings. Go to Example Get Source File","title":"If l2config.env(root) variables are redeclared in l2.env(local)"},{"location":"explanation/l2format.html#the-environment-file-can-load-results-of-commands","text":"Use the backtick notation \\ command`` to place the results of commands into environment variables: export PHOTO=`base64 image.jpeg` One can load the PHOTO variable in API files.","title":"The environment file can load results of commands"},{"location":"explanation/l2format.html#chain-requests-through-javascript-blocks","text":"Lama2 supports plain Javascript (JS) blocks as a glue for manipulating responses and passing on values to later stages. At a higher level, a chain of requests may look like: Javascript 1 --- L2 Request 1 --- Javscript 2 --- L2 Request 2 The triple-dash ( --- ) separator is mandatory. The special variable result contains the response from previous stages. For example, in the above case, Javascript 2 can access the response from L2 Request 1 through the result variable. Learn more about request chaining in Examples .","title":"Chain requests through Javascript blocks"},{"location":"explanation/syntax.html","text":"The following is the recommended flow for a simple .l2 file. The grammar offers some additional flexibilities in ordering the various components, but it is preferable to stick to the following ordering to help with consistency. Also, for chaining requests , one needs a little bit more syntax -- See Examples %%{init: {'securityLevel': 'loose', 'theme':'base'}}%% graph TD Z(Start) Z --> A A[\"HTTP Verb (get/post/put/delete)\"] --> B[Multipart] C[\"URL (http://blah.com)\"] A --> C B --> C D[\"Headers (header_key: header_value)\"] E{Payload} C --> D D --> E F[\"VarJSON (key=value)\"] G[\"JSON {'key': 'value'}\"] H[\"Multipart files (filename@filepath)\"] E --> F F --> H E --> G I(\"End\") H --> I G --> I","title":"Syntax Guidance"},{"location":"liveapi/aboutliveapi.html","text":"LiveAPI: Capture Developer Attention Instantly with Executable API Docs \u00b6 Static API docs often lose customer attention before the developers even try your APIs. With LiveAPI, developers can execute APIs instantly right within their browser, so that you capture developer attention within the first 30 seconds of their visit. LiveAPI uses Lama2 Language for executing the API requests, and supports language conversion as well. Features available \u00b6 1. Execute APIs from Anywhere \u00b6 With LiveAPI integrated into your API documentation, users can directly test your API by simply clicking the \"Try it\" button. 2. Easy to Plug-in \u00b6 LiveAPI is designed with simplicity in mind. You only need to import a single script with your desired parameters to get started. No complex setup required. 3. Customization Options \u00b6 LiveAPI provides plenty of customization to suit your needs, you can personalize the widget by adding Logos as well as links to your API Docs. A Theme selector is also available, so you can make sure the widget fits in well with your documentation style. 4. Code Generator \u00b6 Our built-in code generator feature allows the users to convert the Lama2 requests to any language of their choice. This makes it easier for the developers to integrate APIs to any environment.","title":"About"},{"location":"liveapi/aboutliveapi.html#liveapi-capture-developer-attention-instantly-with-executable-api-docs","text":"Static API docs often lose customer attention before the developers even try your APIs. With LiveAPI, developers can execute APIs instantly right within their browser, so that you capture developer attention within the first 30 seconds of their visit. LiveAPI uses Lama2 Language for executing the API requests, and supports language conversion as well.","title":"LiveAPI: Capture Developer Attention Instantly with Executable API Docs"},{"location":"liveapi/aboutliveapi.html#features-available","text":"","title":"Features available"},{"location":"liveapi/aboutliveapi.html#1-execute-apis-from-anywhere","text":"With LiveAPI integrated into your API documentation, users can directly test your API by simply clicking the \"Try it\" button.","title":"1. Execute APIs from Anywhere"},{"location":"liveapi/aboutliveapi.html#2-easy-to-plug-in","text":"LiveAPI is designed with simplicity in mind. You only need to import a single script with your desired parameters to get started. No complex setup required.","title":"2. Easy to Plug-in"},{"location":"liveapi/aboutliveapi.html#3-customization-options","text":"LiveAPI provides plenty of customization to suit your needs, you can personalize the widget by adding Logos as well as links to your API Docs. A Theme selector is also available, so you can make sure the widget fits in well with your documentation style.","title":"3. Customization Options"},{"location":"liveapi/aboutliveapi.html#4-code-generator","text":"Our built-in code generator feature allows the users to convert the Lama2 requests to any language of their choice. This makes it easier for the developers to integrate APIs to any environment.","title":"4. Code Generator"},{"location":"liveapi/setupliveapi.html","text":"How to setup LiveAPI on your API Docs \u00b6 Step 1: Add the following script to your project \u00b6 < script > (( w , d , s ) => { w . liveAPI = (... args ) => ( w . liveAPI . q = w . liveAPI . q || []). push ( args ); d . head . appendChild ( Object . assign ( d . createElement ( \"script\" ), { src : s , async : true })); })( window , document , `https://d2q4vn0gqet98u.cloudfront.net/latest/liveapi.js?foo= ${ Math . random (). toString ( 36 ). slice ( 2 ) } ` ); liveAPI ( \"loadwidget\" , { selectors : [ '#liveapi-element' ], // Specify selectors to control where you want the widget to be rendered }); </ script > Step 2 \u00b6 Use the following format in your code block < code id = \"liveapi-element\" > GET url_to_be_executed </ code > Example \u00b6 < code id = \"liveapi-element\" > GET https://httpbin.org/ip </ code > This will render the LiveAPI Widget on your page, like so GET https://httpbin.org/ip Additional Configurations \u00b6 Logo and link to the site \u00b6 You can add your own logo to the widget and provide a link to your website by doing the following Towards the end of the script used for importing the script, you can modify it as so window . liveAPI ( \"liveapi\" , { selectors : [ '#liveapi-element' ], logoUrl : \"LINK_TO_YOUR_LOGO_IMAGE\" , siteLink : \"LINK_TO_YOUR_WEBSITE\" , }) Adding Metadata to the widgets \u00b6 You can add Metadata to each widget, like providing the API name and the sample response Adding metadata is done like so GET url_to_be_executed --- _METADATA = {\"sample_response\":\"Sample_Response_JSON\", \"api_name\":\"Name of your API\" } Here is a real example. GET https://httpbin.org/ip --- _METADATA = {\"sample_response\":{ \"origin\": \"IP_ADDRESS\" }, \"api_name\":\"Get the IP\" } This will render the widget like so. GET https://httpbin.org/ip --- _METADATA = {\"sample_response\":{ \"origin\": \"IP_ADDRESS\" }, \"api_name\":\"Get the IP\" }","title":"Easy Installation"},{"location":"liveapi/setupliveapi.html#how-to-setup-liveapi-on-your-api-docs","text":"","title":"How to setup LiveAPI on your API Docs"},{"location":"liveapi/setupliveapi.html#step-1-add-the-following-script-to-your-project","text":"< script > (( w , d , s ) => { w . liveAPI = (... args ) => ( w . liveAPI . q = w . liveAPI . q || []). push ( args ); d . head . appendChild ( Object . assign ( d . createElement ( \"script\" ), { src : s , async : true })); })( window , document , `https://d2q4vn0gqet98u.cloudfront.net/latest/liveapi.js?foo= ${ Math . random (). toString ( 36 ). slice ( 2 ) } ` ); liveAPI ( \"loadwidget\" , { selectors : [ '#liveapi-element' ], // Specify selectors to control where you want the widget to be rendered }); </ script >","title":"Step 1: Add the following script to your project"},{"location":"liveapi/setupliveapi.html#step-2","text":"Use the following format in your code block < code id = \"liveapi-element\" > GET url_to_be_executed </ code >","title":"Step 2"},{"location":"liveapi/setupliveapi.html#example","text":"< code id = \"liveapi-element\" > GET https://httpbin.org/ip </ code > This will render the LiveAPI Widget on your page, like so GET https://httpbin.org/ip","title":"Example"},{"location":"liveapi/setupliveapi.html#additional-configurations","text":"","title":"Additional Configurations"},{"location":"liveapi/setupliveapi.html#logo-and-link-to-the-site","text":"You can add your own logo to the widget and provide a link to your website by doing the following Towards the end of the script used for importing the script, you can modify it as so window . liveAPI ( \"liveapi\" , { selectors : [ '#liveapi-element' ], logoUrl : \"LINK_TO_YOUR_LOGO_IMAGE\" , siteLink : \"LINK_TO_YOUR_WEBSITE\" , })","title":"Logo and link to the site"},{"location":"liveapi/setupliveapi.html#adding-metadata-to-the-widgets","text":"You can add Metadata to each widget, like providing the API name and the sample response Adding metadata is done like so GET url_to_be_executed --- _METADATA = {\"sample_response\":\"Sample_Response_JSON\", \"api_name\":\"Name of your API\" } Here is a real example. GET https://httpbin.org/ip --- _METADATA = {\"sample_response\":{ \"origin\": \"IP_ADDRESS\" }, \"api_name\":\"Get the IP\" } This will render the widget like so. GET https://httpbin.org/ip --- _METADATA = {\"sample_response\":{ \"origin\": \"IP_ADDRESS\" }, \"api_name\":\"Get the IP\" }","title":"Adding Metadata to the widgets"},{"location":"reference/api.html","text":"parser cmdexec cmdgen controller lama2cmd outputmanager preprocess utils","title":"API Reference"},{"location":"reference/architecture.html","text":"Diagram \u00b6 %%{init: {'securityLevel': 'loose', 'theme':'base'}}%% graph TD K[\"Controller Entry <br/>(controller)\"] A[\"Parse CLI <br/>(lama2cmd)\"] B[\"Parser <br/>(parser)\"] D[\"Request Executor <br/>(cmdexec)\"] E[\"Output Format Manager <br/>(outputmanager)\"] F[\"Error Reporting (TODO)\"] G[\"Load input & environment vars <br/>(preprocess)\"] H[\"Request Command Generator <br/>(cmdgen)\"] I[\"Lama2 Prettifier\"] J[\"Data Importer (importer)\"] L[\"Iterate over blocks <br/>(controller)\"] M[\"Init Javascript processor VM <br/>(cmdexec)\"] N[\"Execute JS <br/>(cmdexec)\"] P[\"Variable expansion (JS + env) <br/>(preprocess)\"] A --> G A --> J G --> B H --> D K --> A B --> M M --> L L --> |Requestor| P L --> |Processor| N N --> E D --> E B --> F A --> I P --> H L --> L Description \u00b6 From a high level, how does it work now? Read API file Create a tree-like structure based on *gabs.Container Initialize Javascript VM for executing JS blocks For each block If block is JS Processor block Execute JS code in VM Else if block is Requestor block Replace variables with values in the following order Try fetch variable from Javascript VM If (1) fails, try fetch Local env variable from l2.env Try fetch root env variable from l2config.env Use the processed elements to create an httpie-go request Fetch response If necessary, write the last transaction to .json file","title":"Architecture"},{"location":"reference/architecture.html#diagram","text":"%%{init: {'securityLevel': 'loose', 'theme':'base'}}%% graph TD K[\"Controller Entry <br/>(controller)\"] A[\"Parse CLI <br/>(lama2cmd)\"] B[\"Parser <br/>(parser)\"] D[\"Request Executor <br/>(cmdexec)\"] E[\"Output Format Manager <br/>(outputmanager)\"] F[\"Error Reporting (TODO)\"] G[\"Load input & environment vars <br/>(preprocess)\"] H[\"Request Command Generator <br/>(cmdgen)\"] I[\"Lama2 Prettifier\"] J[\"Data Importer (importer)\"] L[\"Iterate over blocks <br/>(controller)\"] M[\"Init Javascript processor VM <br/>(cmdexec)\"] N[\"Execute JS <br/>(cmdexec)\"] P[\"Variable expansion (JS + env) <br/>(preprocess)\"] A --> G A --> J G --> B H --> D K --> A B --> M M --> L L --> |Requestor| P L --> |Processor| N N --> E D --> E B --> F A --> I P --> H L --> L","title":"Diagram"},{"location":"reference/architecture.html#description","text":"From a high level, how does it work now? Read API file Create a tree-like structure based on *gabs.Container Initialize Javascript VM for executing JS blocks For each block If block is JS Processor block Execute JS code in VM Else if block is Requestor block Replace variables with values in the following order Try fetch variable from Javascript VM If (1) fails, try fetch Local env variable from l2.env Try fetch root env variable from l2config.env Use the processed elements to create an httpie-go request Fetch response If necessary, write the last transaction to .json file","title":"Description"},{"location":"reference/cmdexec.html","text":"cmdexec \u00b6 import \"github.com/HexmosTech/lama2/cmdexec\" Package `cmdexec` provides a facility to execute l2 commands, stream output to stdout, while also providing ability to retrieve the command output as a string. Index \u00b6 func ExecCommand(cmdSlice []string, stdinBody string, apiDir string) (httpie.ExResponse, error) func GenerateChainCode(httpRespBody string) string func GetJSVm() *goja.Runtime func RunVMCode(jsCode string, vm *goja.Runtime) func ExecCommand \u00b6 func ExecCommand ( cmdSlice [] string , stdinBody string , apiDir string ) ( httpie . ExResponse , error ) ExecCommand changes directory to the given `apiDir` and then executes the command specified in `cmdStr` During command execution, ExecCommand streams output to stdout. Once execution finishes, previous CWD is restored, and the command output is returned as a string func GenerateChainCode \u00b6 func GenerateChainCode ( httpRespBody string ) string GenerateChainCode takes in an HTTP response body and comes up with some JS code to define the \"magic variable\" result. What does the code do? The result is stored as a JS object, if the input value can be parsed as JSON. Otherwise the value is stored as a simple string. func GetJSVm \u00b6 func GetJSVm () * goja . Runtime GetJSVm creates a new goja runtime instance with console.log enabled func RunVMCode \u00b6 func RunVMCode ( jsCode string , vm * goja . Runtime ) RunVMCode takes in a JS snippet as a string, executes the code in a JS VM, finally checks whether there are any errors, and if yes, logs the problem. Note: the vm runtime remains modified; so if you reuse the vm for other operations, the state from previous invocations carry over Generated by gomarkdoc","title":"Cmdexec"},{"location":"reference/cmdexec.html#cmdexec","text":"import \"github.com/HexmosTech/lama2/cmdexec\" Package `cmdexec` provides a facility to execute l2 commands, stream output to stdout, while also providing ability to retrieve the command output as a string.","title":"cmdexec"},{"location":"reference/cmdexec.html#index","text":"func ExecCommand(cmdSlice []string, stdinBody string, apiDir string) (httpie.ExResponse, error) func GenerateChainCode(httpRespBody string) string func GetJSVm() *goja.Runtime func RunVMCode(jsCode string, vm *goja.Runtime)","title":"Index"},{"location":"reference/cmdexec.html#func-execcommand","text":"func ExecCommand ( cmdSlice [] string , stdinBody string , apiDir string ) ( httpie . ExResponse , error ) ExecCommand changes directory to the given `apiDir` and then executes the command specified in `cmdStr` During command execution, ExecCommand streams output to stdout. Once execution finishes, previous CWD is restored, and the command output is returned as a string","title":"func ExecCommand"},{"location":"reference/cmdexec.html#func-generatechaincode","text":"func GenerateChainCode ( httpRespBody string ) string GenerateChainCode takes in an HTTP response body and comes up with some JS code to define the \"magic variable\" result. What does the code do? The result is stored as a JS object, if the input value can be parsed as JSON. Otherwise the value is stored as a simple string.","title":"func GenerateChainCode"},{"location":"reference/cmdexec.html#func-getjsvm","text":"func GetJSVm () * goja . Runtime GetJSVm creates a new goja runtime instance with console.log enabled","title":"func GetJSVm"},{"location":"reference/cmdexec.html#func-runvmcode","text":"func RunVMCode ( jsCode string , vm * goja . Runtime ) RunVMCode takes in a JS snippet as a string, executes the code in a JS VM, finally checks whether there are any errors, and if yes, logs the problem. Note: the vm runtime remains modified; so if you reuse the vm for other operations, the state from previous invocations carry over Generated by gomarkdoc","title":"func RunVMCode"},{"location":"reference/cmdgen.html","text":"cmdgen \u00b6 import \"github.com/HexmosTech/lama2/cmdgen\" Package `cmdgen` provides an API to generate API request commands (by default based on HTTPie) based on the parsed API file contents and the `l2` command invocation parameters Index \u00b6 func ConstructCommandHelper(parsedInput *gabs.Container) (string, string, *gabs.Container, *gabs.Container, bool, bool) func ConstructCommandHelper \u00b6 func ConstructCommandHelper ( parsedInput * gabs . Container ) ( string , string , * gabs . Container , * gabs . Container , bool , bool ) ConstructCommand extracts the HTTP verb, url and other API file inputs, figures out the type of target command and finally generates a string representing the generated command Generated by gomarkdoc","title":"Cmdgen"},{"location":"reference/cmdgen.html#cmdgen","text":"import \"github.com/HexmosTech/lama2/cmdgen\" Package `cmdgen` provides an API to generate API request commands (by default based on HTTPie) based on the parsed API file contents and the `l2` command invocation parameters","title":"cmdgen"},{"location":"reference/cmdgen.html#index","text":"func ConstructCommandHelper(parsedInput *gabs.Container) (string, string, *gabs.Container, *gabs.Container, bool, bool)","title":"Index"},{"location":"reference/cmdgen.html#func-constructcommandhelper","text":"func ConstructCommandHelper ( parsedInput * gabs . Container ) ( string , string , * gabs . Container , * gabs . Container , bool , bool ) ConstructCommand extracts the HTTP verb, url and other API file inputs, figures out the type of target command and finally generates a string representing the generated command Generated by gomarkdoc","title":"func ConstructCommandHelper"},{"location":"reference/controller.html","text":"contoller \u00b6 import \"github.com/HexmosTech/lama2/controller\" Package controller coordinates all the other components in the `Lama2` project. The high level overview of command execution is easily understood from this package Index \u00b6 func GetParsedAPIBlocks(parsedAPI *gabs.Container) []*gabs.Container func HandleParsedFileHelper(parsedAPI *gabs.Container, args ...interface{}) (httpie.ExResponse, *lama2cmd.Opts, []outputmanager.ResponseTime, []outputmanager.StatusCode, []outputmanager.ContentSize, error) func GetParsedAPIBlocks \u00b6 func GetParsedAPIBlocks ( parsedAPI * gabs . Container ) [] * gabs . Container func HandleParsedFileHelper \u00b6 func HandleParsedFileHelper ( parsedAPI * gabs . Container , args ... interface {}) ( httpie . ExResponse , * lama2cmd . Opts , [] outputmanager . ResponseTime , [] outputmanager . StatusCode , [] outputmanager . ContentSize , error ) Generated by gomarkdoc","title":"Controller"},{"location":"reference/controller.html#contoller","text":"import \"github.com/HexmosTech/lama2/controller\" Package controller coordinates all the other components in the `Lama2` project. The high level overview of command execution is easily understood from this package","title":"contoller"},{"location":"reference/controller.html#index","text":"func GetParsedAPIBlocks(parsedAPI *gabs.Container) []*gabs.Container func HandleParsedFileHelper(parsedAPI *gabs.Container, args ...interface{}) (httpie.ExResponse, *lama2cmd.Opts, []outputmanager.ResponseTime, []outputmanager.StatusCode, []outputmanager.ContentSize, error)","title":"Index"},{"location":"reference/controller.html#func-getparsedapiblocks","text":"func GetParsedAPIBlocks ( parsedAPI * gabs . Container ) [] * gabs . Container","title":"func GetParsedAPIBlocks"},{"location":"reference/controller.html#func-handleparsedfilehelper","text":"func HandleParsedFileHelper ( parsedAPI * gabs . Container , args ... interface {}) ( httpie . ExResponse , * lama2cmd . Opts , [] outputmanager . ResponseTime , [] outputmanager . StatusCode , [] outputmanager . ContentSize , error ) Generated by gomarkdoc","title":"func HandleParsedFileHelper"},{"location":"reference/grammar.html","text":"Grammar \u00b6 What follows is a rough rendition of the Lama2 grammar, followed by a visual exploration of the grammar in the railroad diagram format (thanks to Railroad Diagram Generator ) EBNF Description \u00b6 Lama2File ::= (Proceessor Separator)? Requestor (Separator Processor Separator Requestor)* Separator ::= `^---$` Processor ::= `(?!(get|post|head|put|delete|connect|trace|patch))` Requestor ::= HTTPVerb Multipart? TheURL Details? HTTPVerb ::= \"get\" | \"head\" | \"post\" | \"put\" | \"delete\" | \"connect\" | \"trace\" | \"patch\" Multipart ::= \"multipart\" TheURL ::= \"http\" \"s\"? \"://\" [A-Za-z0-9-._~:/?#[@!$&'()*+,;%=]+ /* ws: explicit */ Details ::= HeaderData | DataHeader HeaderData ::= Headers DataInput? DataHeader ::= DataInput Headers? Headers ::= HeaderPair HeaderPair* HeaderPair ::= (QuotedString | Unquoted) \":\" (QuotedString | Unquoted) DataInput ::= VarJSON | JSONType VarJSON ::= VarJSONPair VarJSONPair* FilesPair? VarJSONPair ::= (QuotedString | VarJSONUnquoted) \"=\" (QuotedString | VarJSONUnquoted) FilesPair ::= FilesPair FilesPair* FilesPair ::= (QuotedString | FilesUnquoted) \"@\" (QuotedString | FilesUnquoted) VarJSONUnquoted ::= [@0-9A-Za-z \\t!$%&()*+./;<>?^_`|~-]+ /* ws: explicit */ FilesUnquoted ::= [0-9A-Za-z \\t!$%&()*+./;<>?^_`|~-]+ /* ws: explicit */ QuotedString ::= ['\"] Char* ['\"] Unquoted ::= [0-9A-Za-z \\t!$%&()*+./;<=>?^_`|~-]+ /* ws: explicit */ JSONType ::= ComplexType | PrimitiveType ComplexType ::= List | Map PrimitiveType ::= Null | Boolean | QuotedString | Number Map ::= \"{\" Pair? (Pair \",\")* \"}\" List ::= \"[\" JSONType? (JSONType \",\")* \"]\" Pair ::= QuotedString \":\" JSONType Boolean ::= \"true\" | \"false\" Null ::= \"null\" Number ::= Integer Fraction? Exponent? Exponent ::= [eE] Sign? Digits Fraction ::= \".\" Digits Integer ::= IntegerRule4 | IntegerRule3 | IntegerRule2 | IntegerRule1 IntegerRule1 ::= Digit IntegerRule2 ::= OneNine Digits IntegerRule3 ::= Sign IntegerRule1 IntegerRule4 ::= Sign IntegerRule2 Digits ::= Digit Digit* Digit ::= \"0\"? OneNine OneNine ::= [1-9] Sign ::= [-+] Railroad Diagram \u00b6 ::-moz-selection { color: #FFFCF0; background: #0F0C00; } ::selection { color: #FFFCF0; background: #0F0C00; } .ebnf a, .grammar a { text-decoration: none; } .ebnf a:hover, .grammar a:hover { color: #050400; text-decoration: underline; } .signature { color: #806600; font-size: 11px; text-align: right; } body { font: normal 12px Verdana, sans-serif; color: #0F0C00; background: #FFFCF0; } a:link, a:visited { color: #0F0C00; } a:link.signature, a:visited.signature { color: #806600; } a.button, #tabs li a { padding: 0.25em 0.5em; border: 1px solid #806600; background: #F1E8C6; color: #806600; text-decoration: none; font-weight: bold; } a.button:hover, #tabs li a:hover { color: #050400; background: #FFF6D1; border-color: #050400; } #tabs { padding: 3px 10px; margin-left: 0; margin-top: 58px; border-bottom: 1px solid #0F0C00; } #tabs li { list-style: none; margin-left: 5px; display: inline; } #tabs li a { border-bottom: 1px solid #0F0C00; } #tabs li a.active { color: #0F0C00; background: #FFFCF0; border-color: #0F0C00; border-bottom: 1px solid #FFFCF0; outline: none; } #divs div { display: none; overflow:auto; } #divs div.active { display: block; } #text { border-color: #806600; background: #FFFEFA; color: #050400; } .small { vertical-align: top; text-align: right; font-size: 9px; font-weight: normal; line-height: 120%; } td.small { padding-top: 0px; } .hidden { visibility: hidden; } td:hover .hidden { visibility: visible; } div.download { display: none; background: #FFFCF0; position: absolute; right: 34px; top: 94px; padding: 10px; border: 1px dotted #0F0C00; } #divs div.ebnf, .ebnf code { display: block; padding: 10px; background: #FFF6D1; width: 992px; } #divs div.grammar { display: block; padding-left: 16px; padding-top: 2px; padding-bottom: 2px; background: #FFF6D1; } pre { margin: 0px; } .ebnf div { padding-left: 13ch; text-indent: -13ch; } .ebnf code, .grammar code, textarea, pre { font:12px SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace; } tr.option-line td:first-child { text-align: right } tr.option-text td { padding-bottom: 10px } table.palette { border-top: 1px solid #050400; border-right: 1px solid #050400; margin-bottom: 4px } td.palette { border-bottom: 1px solid #050400; border-left: 1px solid #050400; } a.palette { padding: 2px 3px 2px 10px; text-decoration: none; } .palette { -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -o-user-select: none; -ms-user-select: none; } @namespace \"http://www.w3.org/2000/svg\"; .line {fill: none; stroke: #332900; stroke-width: 1;} .bold-line {stroke: #141000; shape-rendering: crispEdges; stroke-width: 2;} .thin-line {stroke: #1F1800; shape-rendering: crispEdges} .filled {fill: #332900; stroke: none;} text.terminal {font-family: Verdana, Sans-serif; font-size: 12px; fill: #141000; font-weight: bold; } text.nonterminal {font-family: Verdana, Sans-serif; font-size: 12px; fill: #1A1400; font-weight: normal; } text.regexp {font-family: Verdana, Sans-serif; font-size: 12px; fill: #1F1800; font-weight: normal; } rect, circle, polygon {fill: #332900; stroke: #332900;} rect.terminal {fill: #FFDB4D; stroke: #332900; stroke-width: 1;} rect.nonterminal {fill: #FFEC9E; stroke: #332900; stroke-width: 1;} rect.text {fill: none; stroke: none;} polygon.regexp {fill: #FFF4C7; stroke: #332900; stroke-width: 1;} Lama2File: Proceessor Separator Requestor Separator Processor Separator Lama2File ::= ( Proceessor Separator )? Requestor ( Separator Processor Separator Requestor )* no references Separator: --- Separator ::= '---' referenced by: Lama2File Processor: (?!(get|post|head|put|delete|connect|trace|patch)) Processor ::= '(?!(get|post|head|put|delete|connect|trace|patch))' referenced by: Lama2File Requestor: HTTPVerb Multipart TheURL Details Requestor ::= HTTPVerb Multipart ? TheURL Details ? referenced by: Lama2File HTTPVerb: get head post put delete connect trace patch HTTPVerb ::= 'get' | 'head' | 'post' | 'put' | 'delete' | 'connect' | 'trace' | 'patch' referenced by: Requestor Multipart: multipart Multipart ::= 'multipart' referenced by: Requestor TheURL: http s :// [A-Z] [a-z] [0-9] - . _ ~ : / ? # [ @ ! $ & ' ( ) * + , ; % = TheURL ::= 'http' 's'? '://' [A-Za-z0-9._~:/?[@!$&'()*+,;%=#x2D#x23]+ /* ws: explicit */ referenced by: Requestor Details: HeaderData DataHeader Details ::= HeaderData | DataHeader referenced by: Requestor HeaderData: Headers DataInput HeaderData ::= Headers DataInput ? referenced by: Details DataHeader: DataInput Headers DataHeader ::= DataInput Headers ? referenced by: Details Headers: HeaderPair Headers ::= HeaderPair HeaderPair * referenced by: DataHeader HeaderData HeaderPair: QuotedString Unquoted : QuotedString Unquoted HeaderPair ::= ( QuotedString | Unquoted ) ':' ( QuotedString | Unquoted ) referenced by: Headers DataInput: VarJSON JSONType DataInput ::= VarJSON | JSONType referenced by: DataHeader HeaderData VarJSON: VarJSONPair FilesPair VarJSON ::= VarJSONPair VarJSONPair * FilesPair ? referenced by: DataInput VarJSONPair: QuotedString VarJSONUnquoted = QuotedString VarJSONUnquoted VarJSONPair ::= ( QuotedString | VarJSONUnquoted ) '=' ( QuotedString | VarJSONUnquoted ) referenced by: VarJSON FilesPair: FilesPair QuotedString FilesUnquoted @ QuotedString FilesUnquoted FilesPair ::= FilesPair FilesPair * | ( QuotedString | FilesUnquoted ) '@' ( QuotedString | FilesUnquoted ) referenced by: FilesPair VarJSON VarJSONUnquoted: @ [0-9] [A-Z] [a-z] \\ t ! $ % & ( ) * + . / ; < > ? ^ _ ` | ~ - VarJSONUnquoted ::= [@0-9A-Za-z \\t!$%&()*+./;<>?^_`|~#x2D]+ /* ws: explicit */ referenced by: VarJSONPair FilesUnquoted: [0-9] [A-Z] [a-z] \\ t ! $ % & ( ) * + . / ; < > ? ^ _ ` | ~ - FilesUnquoted ::= [0-9A-Za-z \\t!$%&()*+./;<>?^_`|~#x2D]+ /* ws: explicit */ referenced by: FilesPair QuotedString: ' \" Char ' \" QuotedString ::= ['\"] Char * ['\"] referenced by: FilesPair HeaderPair Pair PrimitiveType VarJSONPair Unquoted: [0-9] [A-Z] [a-z] \\ t ! $ % & ( ) * + . / ; < = > ? ^ _ ` | ~ - Unquoted ::= [0-9A-Za-z \\t!$%&()*+./;<=>?^_`|~#x2D]+ /* ws: explicit */ referenced by: HeaderPair JSONType: ComplexType PrimitiveType JSONType ::= ComplexType | PrimitiveType referenced by: DataInput List Pair ComplexType: List Map ComplexType ::= List | Map referenced by: JSONType PrimitiveType: Null Boolean QuotedString Number PrimitiveType ::= Null | Boolean | QuotedString | Number referenced by: JSONType Map: { Pair Pair , } Map ::= '{' Pair ? ( Pair ',' )* '}' referenced by: ComplexType List: [ JSONType JSONType , ] List ::= '[' JSONType ? ( JSONType ',' )* ']' referenced by: ComplexType Pair: QuotedString : JSONType Pair ::= QuotedString ':' JSONType referenced by: Map Boolean: true false Boolean ::= 'true' | 'false' referenced by: PrimitiveType Null: null Null ::= 'null' referenced by: PrimitiveType Number: Integer Fraction Exponent Number ::= Integer Fraction ? Exponent ? referenced by: PrimitiveType Exponent: e E Sign Digits Exponent ::= [eE] Sign ? Digits referenced by: Number Fraction: . Digits Fraction ::= '.' Digits referenced by: Number Integer: IntegerRule4 IntegerRule3 IntegerRule2 IntegerRule1 Integer ::= IntegerRule4 | IntegerRule3 | IntegerRule2 | IntegerRule1 referenced by: Number IntegerRule1: Digit IntegerRule1 ::= Digit referenced by: Integer IntegerRule3 IntegerRule2: OneNine Digits IntegerRule2 ::= OneNine Digits referenced by: Integer IntegerRule4 IntegerRule3: Sign IntegerRule1 IntegerRule3 ::= Sign IntegerRule1 referenced by: Integer IntegerRule4: Sign IntegerRule2 IntegerRule4 ::= Sign IntegerRule2 referenced by: Integer Digits: Digit Digits ::= Digit Digit * referenced by: Exponent Fraction IntegerRule2 Digit: 0 OneNine Digit ::= '0'? OneNine referenced by: Digits IntegerRule1 OneNine: [1-9] OneNine ::= [1-9] referenced by: Digit IntegerRule2 Sign: - + Sign ::= [-+] referenced by: Exponent IntegerRule3 IntegerRule4 ... generated by RR - Railroad Diagram Generator R R","title":"Formal Grammar"},{"location":"reference/grammar.html#grammar","text":"What follows is a rough rendition of the Lama2 grammar, followed by a visual exploration of the grammar in the railroad diagram format (thanks to Railroad Diagram Generator )","title":"Grammar"},{"location":"reference/grammar.html#ebnf-description","text":"Lama2File ::= (Proceessor Separator)? Requestor (Separator Processor Separator Requestor)* Separator ::= `^---$` Processor ::= `(?!(get|post|head|put|delete|connect|trace|patch))` Requestor ::= HTTPVerb Multipart? TheURL Details? HTTPVerb ::= \"get\" | \"head\" | \"post\" | \"put\" | \"delete\" | \"connect\" | \"trace\" | \"patch\" Multipart ::= \"multipart\" TheURL ::= \"http\" \"s\"? \"://\" [A-Za-z0-9-._~:/?#[@!$&'()*+,;%=]+ /* ws: explicit */ Details ::= HeaderData | DataHeader HeaderData ::= Headers DataInput? DataHeader ::= DataInput Headers? Headers ::= HeaderPair HeaderPair* HeaderPair ::= (QuotedString | Unquoted) \":\" (QuotedString | Unquoted) DataInput ::= VarJSON | JSONType VarJSON ::= VarJSONPair VarJSONPair* FilesPair? VarJSONPair ::= (QuotedString | VarJSONUnquoted) \"=\" (QuotedString | VarJSONUnquoted) FilesPair ::= FilesPair FilesPair* FilesPair ::= (QuotedString | FilesUnquoted) \"@\" (QuotedString | FilesUnquoted) VarJSONUnquoted ::= [@0-9A-Za-z \\t!$%&()*+./;<>?^_`|~-]+ /* ws: explicit */ FilesUnquoted ::= [0-9A-Za-z \\t!$%&()*+./;<>?^_`|~-]+ /* ws: explicit */ QuotedString ::= ['\"] Char* ['\"] Unquoted ::= [0-9A-Za-z \\t!$%&()*+./;<=>?^_`|~-]+ /* ws: explicit */ JSONType ::= ComplexType | PrimitiveType ComplexType ::= List | Map PrimitiveType ::= Null | Boolean | QuotedString | Number Map ::= \"{\" Pair? (Pair \",\")* \"}\" List ::= \"[\" JSONType? (JSONType \",\")* \"]\" Pair ::= QuotedString \":\" JSONType Boolean ::= \"true\" | \"false\" Null ::= \"null\" Number ::= Integer Fraction? Exponent? Exponent ::= [eE] Sign? Digits Fraction ::= \".\" Digits Integer ::= IntegerRule4 | IntegerRule3 | IntegerRule2 | IntegerRule1 IntegerRule1 ::= Digit IntegerRule2 ::= OneNine Digits IntegerRule3 ::= Sign IntegerRule1 IntegerRule4 ::= Sign IntegerRule2 Digits ::= Digit Digit* Digit ::= \"0\"? OneNine OneNine ::= [1-9] Sign ::= [-+]","title":"EBNF Description"},{"location":"reference/grammar.html#railroad-diagram","text":"::-moz-selection { color: #FFFCF0; background: #0F0C00; } ::selection { color: #FFFCF0; background: #0F0C00; } .ebnf a, .grammar a { text-decoration: none; } .ebnf a:hover, .grammar a:hover { color: #050400; text-decoration: underline; } .signature { color: #806600; font-size: 11px; text-align: right; } body { font: normal 12px Verdana, sans-serif; color: #0F0C00; background: #FFFCF0; } a:link, a:visited { color: #0F0C00; } a:link.signature, a:visited.signature { color: #806600; } a.button, #tabs li a { padding: 0.25em 0.5em; border: 1px solid #806600; background: #F1E8C6; color: #806600; text-decoration: none; font-weight: bold; } a.button:hover, #tabs li a:hover { color: #050400; background: #FFF6D1; border-color: #050400; } #tabs { padding: 3px 10px; margin-left: 0; margin-top: 58px; border-bottom: 1px solid #0F0C00; } #tabs li { list-style: none; margin-left: 5px; display: inline; } #tabs li a { border-bottom: 1px solid #0F0C00; } #tabs li a.active { color: #0F0C00; background: #FFFCF0; border-color: #0F0C00; border-bottom: 1px solid #FFFCF0; outline: none; } #divs div { display: none; overflow:auto; } #divs div.active { display: block; } #text { border-color: #806600; background: #FFFEFA; color: #050400; } .small { vertical-align: top; text-align: right; font-size: 9px; font-weight: normal; line-height: 120%; } td.small { padding-top: 0px; } .hidden { visibility: hidden; } td:hover .hidden { visibility: visible; } div.download { display: none; background: #FFFCF0; position: absolute; right: 34px; top: 94px; padding: 10px; border: 1px dotted #0F0C00; } #divs div.ebnf, .ebnf code { display: block; padding: 10px; background: #FFF6D1; width: 992px; } #divs div.grammar { display: block; padding-left: 16px; padding-top: 2px; padding-bottom: 2px; background: #FFF6D1; } pre { margin: 0px; } .ebnf div { padding-left: 13ch; text-indent: -13ch; } .ebnf code, .grammar code, textarea, pre { font:12px SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace; } tr.option-line td:first-child { text-align: right } tr.option-text td { padding-bottom: 10px } table.palette { border-top: 1px solid #050400; border-right: 1px solid #050400; margin-bottom: 4px } td.palette { border-bottom: 1px solid #050400; border-left: 1px solid #050400; } a.palette { padding: 2px 3px 2px 10px; text-decoration: none; } .palette { -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -o-user-select: none; -ms-user-select: none; } @namespace \"http://www.w3.org/2000/svg\"; .line {fill: none; stroke: #332900; stroke-width: 1;} .bold-line {stroke: #141000; shape-rendering: crispEdges; stroke-width: 2;} .thin-line {stroke: #1F1800; shape-rendering: crispEdges} .filled {fill: #332900; stroke: none;} text.terminal {font-family: Verdana, Sans-serif; font-size: 12px; fill: #141000; font-weight: bold; } text.nonterminal {font-family: Verdana, Sans-serif; font-size: 12px; fill: #1A1400; font-weight: normal; } text.regexp {font-family: Verdana, Sans-serif; font-size: 12px; fill: #1F1800; font-weight: normal; } rect, circle, polygon {fill: #332900; stroke: #332900;} rect.terminal {fill: #FFDB4D; stroke: #332900; stroke-width: 1;} rect.nonterminal {fill: #FFEC9E; stroke: #332900; stroke-width: 1;} rect.text {fill: none; stroke: none;} polygon.regexp {fill: #FFF4C7; stroke: #332900; stroke-width: 1;} Lama2File: Proceessor Separator Requestor Separator Processor Separator Lama2File ::= ( Proceessor Separator )? Requestor ( Separator Processor Separator Requestor )* no references Separator: --- Separator ::= '---' referenced by: Lama2File Processor: (?!(get|post|head|put|delete|connect|trace|patch)) Processor ::= '(?!(get|post|head|put|delete|connect|trace|patch))' referenced by: Lama2File Requestor: HTTPVerb Multipart TheURL Details Requestor ::= HTTPVerb Multipart ? TheURL Details ? referenced by: Lama2File HTTPVerb: get head post put delete connect trace patch HTTPVerb ::= 'get' | 'head' | 'post' | 'put' | 'delete' | 'connect' | 'trace' | 'patch' referenced by: Requestor Multipart: multipart Multipart ::= 'multipart' referenced by: Requestor TheURL: http s :// [A-Z] [a-z] [0-9] - . _ ~ : / ? # [ @ ! $ & ' ( ) * + , ; % = TheURL ::= 'http' 's'? '://' [A-Za-z0-9._~:/?[@!$&'()*+,;%=#x2D#x23]+ /* ws: explicit */ referenced by: Requestor Details: HeaderData DataHeader Details ::= HeaderData | DataHeader referenced by: Requestor HeaderData: Headers DataInput HeaderData ::= Headers DataInput ? referenced by: Details DataHeader: DataInput Headers DataHeader ::= DataInput Headers ? referenced by: Details Headers: HeaderPair Headers ::= HeaderPair HeaderPair * referenced by: DataHeader HeaderData HeaderPair: QuotedString Unquoted : QuotedString Unquoted HeaderPair ::= ( QuotedString | Unquoted ) ':' ( QuotedString | Unquoted ) referenced by: Headers DataInput: VarJSON JSONType DataInput ::= VarJSON | JSONType referenced by: DataHeader HeaderData VarJSON: VarJSONPair FilesPair VarJSON ::= VarJSONPair VarJSONPair * FilesPair ? referenced by: DataInput VarJSONPair: QuotedString VarJSONUnquoted = QuotedString VarJSONUnquoted VarJSONPair ::= ( QuotedString | VarJSONUnquoted ) '=' ( QuotedString | VarJSONUnquoted ) referenced by: VarJSON FilesPair: FilesPair QuotedString FilesUnquoted @ QuotedString FilesUnquoted FilesPair ::= FilesPair FilesPair * | ( QuotedString | FilesUnquoted ) '@' ( QuotedString | FilesUnquoted ) referenced by: FilesPair VarJSON VarJSONUnquoted: @ [0-9] [A-Z] [a-z] \\ t ! $ % & ( ) * + . / ; < > ? ^ _ ` | ~ - VarJSONUnquoted ::= [@0-9A-Za-z \\t!$%&()*+./;<>?^_`|~#x2D]+ /* ws: explicit */ referenced by: VarJSONPair FilesUnquoted: [0-9] [A-Z] [a-z] \\ t ! $ % & ( ) * + . / ; < > ? ^ _ ` | ~ - FilesUnquoted ::= [0-9A-Za-z \\t!$%&()*+./;<>?^_`|~#x2D]+ /* ws: explicit */ referenced by: FilesPair QuotedString: ' \" Char ' \" QuotedString ::= ['\"] Char * ['\"] referenced by: FilesPair HeaderPair Pair PrimitiveType VarJSONPair Unquoted: [0-9] [A-Z] [a-z] \\ t ! $ % & ( ) * + . / ; < = > ? ^ _ ` | ~ - Unquoted ::= [0-9A-Za-z \\t!$%&()*+./;<=>?^_`|~#x2D]+ /* ws: explicit */ referenced by: HeaderPair JSONType: ComplexType PrimitiveType JSONType ::= ComplexType | PrimitiveType referenced by: DataInput List Pair ComplexType: List Map ComplexType ::= List | Map referenced by: JSONType PrimitiveType: Null Boolean QuotedString Number PrimitiveType ::= Null | Boolean | QuotedString | Number referenced by: JSONType Map: { Pair Pair , } Map ::= '{' Pair ? ( Pair ',' )* '}' referenced by: ComplexType List: [ JSONType JSONType , ] List ::= '[' JSONType ? ( JSONType ',' )* ']' referenced by: ComplexType Pair: QuotedString : JSONType Pair ::= QuotedString ':' JSONType referenced by: Map Boolean: true false Boolean ::= 'true' | 'false' referenced by: PrimitiveType Null: null Null ::= 'null' referenced by: PrimitiveType Number: Integer Fraction Exponent Number ::= Integer Fraction ? Exponent ? referenced by: PrimitiveType Exponent: e E Sign Digits Exponent ::= [eE] Sign ? Digits referenced by: Number Fraction: . Digits Fraction ::= '.' Digits referenced by: Number Integer: IntegerRule4 IntegerRule3 IntegerRule2 IntegerRule1 Integer ::= IntegerRule4 | IntegerRule3 | IntegerRule2 | IntegerRule1 referenced by: Number IntegerRule1: Digit IntegerRule1 ::= Digit referenced by: Integer IntegerRule3 IntegerRule2: OneNine Digits IntegerRule2 ::= OneNine Digits referenced by: Integer IntegerRule4 IntegerRule3: Sign IntegerRule1 IntegerRule3 ::= Sign IntegerRule1 referenced by: Integer IntegerRule4: Sign IntegerRule2 IntegerRule4 ::= Sign IntegerRule2 referenced by: Integer Digits: Digit Digits ::= Digit Digit * referenced by: Exponent Fraction IntegerRule2 Digit: 0 OneNine Digit ::= '0'? OneNine referenced by: Digits IntegerRule1 OneNine: [1-9] OneNine ::= [1-9] referenced by: Digit IntegerRule2 Sign: - + Sign ::= [-+] referenced by: Exponent IntegerRule3 IntegerRule4 ... generated by RR - Railroad Diagram Generator R R","title":"Railroad Diagram"},{"location":"reference/lama2cmd.html","text":"lama2cmd \u00b6 import \"github.com/HexmosTech/lama2/lama2cmd\" Package `lama2cmd` provides CLI argument parsing facilities. It hosts the `Opts` structure to record user intentions Index \u00b6 func ArgParsing(o *Opts, version string) func SetLSPServer(server LSPServer) type LSPServer type Opts func GetAndValidateCmd(ipArgs []string) *Opts func ArgParsing \u00b6 func ArgParsing ( o * Opts , version string ) func SetLSPServer \u00b6 func SetLSPServer ( server LSPServer ) type LSPServer \u00b6 LSPServer defines the interface for starting an LSP server type LSPServer interface { StartLspServer () } type Opts \u00b6 The Opts structure stores user preferences, and is used throughout the module to make various decisions. type Opts struct { Output string `short:\"o\" long:\"output\" description:\"Path to output JSON file to store logs, headers and result\"` Verbose [] bool `short:\"v\" long:\"verbose\" description:\"Show verbose debug information\"` Prettify bool `short:\"b\" long:\"prettify\" description:\"Prettify specified .l2 file\"` // Sort bool `short:\"s\" long:\"sort\" description:\"Sort specification into recommended order\"` Convert string `short:\"c\" long:\"convert\" description:\"Generate code in given language and library (ex: python.requests); reference: tinyurl.com/l2codegen\"` Nocolor bool `short:\"n\" long:\"nocolor\" description:\"Disable color in httpie output\"` Update bool `short:\"u\" long:\"update\" description:\"Update l2 binary to the latest released version (Linux/MacOS only)\"` PostmanFile string `short:\"p\" long:\"postmanfile\" description:\"JSON export from Postman (Settings -> Data -> Export Data)\"` LamaDir string `short:\"l\" long:\"lama2dir\" description:\"Output directory to put .l2 files after conversion from Postman format\"` Help bool `short:\"h\" long:\"help\" group:\"AddHelp\" description:\"Usage help for Lama2\"` Lsp bool `short:\"z\" long:\"lsp\" description:\"Start the lsp server\"` Version bool `long:\"version\" description:\"Print Lama2 binary version\"` Positional struct { LamaAPIFile string } `positional-args:\"yes\"` } func GetAndValidateCmd \u00b6 func GetAndValidateCmd ( ipArgs [] string ) * Opts GetAndValidateCmd takes in the user's CLI input, and checks for validity. If not OK, displays a help message in stdout. Otherwise, fills the Opts structure and returns it Moreover, based on user input, the outputManager gets configured (whether user prefers trace/debug/info level) Generated by gomarkdoc","title":"Lama2cmd"},{"location":"reference/lama2cmd.html#lama2cmd","text":"import \"github.com/HexmosTech/lama2/lama2cmd\" Package `lama2cmd` provides CLI argument parsing facilities. It hosts the `Opts` structure to record user intentions","title":"lama2cmd"},{"location":"reference/lama2cmd.html#index","text":"func ArgParsing(o *Opts, version string) func SetLSPServer(server LSPServer) type LSPServer type Opts func GetAndValidateCmd(ipArgs []string) *Opts","title":"Index"},{"location":"reference/lama2cmd.html#func-argparsing","text":"func ArgParsing ( o * Opts , version string )","title":"func ArgParsing"},{"location":"reference/lama2cmd.html#func-setlspserver","text":"func SetLSPServer ( server LSPServer )","title":"func SetLSPServer"},{"location":"reference/lama2cmd.html#type-lspserver","text":"LSPServer defines the interface for starting an LSP server type LSPServer interface { StartLspServer () }","title":"type LSPServer"},{"location":"reference/lama2cmd.html#type-opts","text":"The Opts structure stores user preferences, and is used throughout the module to make various decisions. type Opts struct { Output string `short:\"o\" long:\"output\" description:\"Path to output JSON file to store logs, headers and result\"` Verbose [] bool `short:\"v\" long:\"verbose\" description:\"Show verbose debug information\"` Prettify bool `short:\"b\" long:\"prettify\" description:\"Prettify specified .l2 file\"` // Sort bool `short:\"s\" long:\"sort\" description:\"Sort specification into recommended order\"` Convert string `short:\"c\" long:\"convert\" description:\"Generate code in given language and library (ex: python.requests); reference: tinyurl.com/l2codegen\"` Nocolor bool `short:\"n\" long:\"nocolor\" description:\"Disable color in httpie output\"` Update bool `short:\"u\" long:\"update\" description:\"Update l2 binary to the latest released version (Linux/MacOS only)\"` PostmanFile string `short:\"p\" long:\"postmanfile\" description:\"JSON export from Postman (Settings -> Data -> Export Data)\"` LamaDir string `short:\"l\" long:\"lama2dir\" description:\"Output directory to put .l2 files after conversion from Postman format\"` Help bool `short:\"h\" long:\"help\" group:\"AddHelp\" description:\"Usage help for Lama2\"` Lsp bool `short:\"z\" long:\"lsp\" description:\"Start the lsp server\"` Version bool `long:\"version\" description:\"Print Lama2 binary version\"` Positional struct { LamaAPIFile string } `positional-args:\"yes\"` }","title":"type Opts"},{"location":"reference/lama2cmd.html#func-getandvalidatecmd","text":"func GetAndValidateCmd ( ipArgs [] string ) * Opts GetAndValidateCmd takes in the user's CLI input, and checks for validity. If not OK, displays a help message in stdout. Otherwise, fills the Opts structure and returns it Moreover, based on user input, the outputManager gets configured (whether user prefers trace/debug/info level) Generated by gomarkdoc","title":"func GetAndValidateCmd"},{"location":"reference/lsp.html","text":"How to Add a New Method to the LSP Binary \u00b6 This guide will walk you through the process of adding a new method to the LSP binary in the Lama2 project. 1. Understanding the Entry Point at lama2cmd.go \u00b6 The LSP server is initiated by l2 --lsp . This is handled in the ArgParsing function: func ArgParsing ( o * Opts , version string ) { if o . Lsp { l2lsp . StartLspServer () // Incoming requests to the LSP will be processed by l2lsp.StartLspServer() } } 2. Directing the Input \u00b6 The input is directed to the HandleMethod function: rpcResponse := HandleMethod ( rpcRequest ) You can view the implementation of this function in the identify_method.go file. 3. Adding Your Method \u00b6 To add your custom method, modify the HandleMethod function by adding a new case to the switch statement. 4. Implementing the Logic \u00b6 Write the logic for your method in the methods directory. 5. Using and Defining Structs \u00b6 For general request structures, refer to JSONRPCRequest in general_request.go . If you need to define a custom struct for your method, add it in the request directory. For general response structures, refer to JSONRPCResponse in general_response.go . 6. Utilizing Helper Functions \u00b6 The respond.go file provides helper functions to create success and error responses: func CreateSuccessResponse ( requestID int , result interface {}) JSONRPCResponse { ... } func ErrorResp ( req request . JSONRPCRequest , errorCode int , errorMsg string ) JSONRPCResponse { ... } Use these functions to streamline the response creation process.","title":"Contribute to LSP"},{"location":"reference/lsp.html#how-to-add-a-new-method-to-the-lsp-binary","text":"This guide will walk you through the process of adding a new method to the LSP binary in the Lama2 project.","title":"How to Add a New Method to the LSP Binary"},{"location":"reference/lsp.html#1-understanding-the-entry-point-at-lama2cmdgo","text":"The LSP server is initiated by l2 --lsp . This is handled in the ArgParsing function: func ArgParsing ( o * Opts , version string ) { if o . Lsp { l2lsp . StartLspServer () // Incoming requests to the LSP will be processed by l2lsp.StartLspServer() } }","title":"1. Understanding the Entry Point at lama2cmd.go"},{"location":"reference/lsp.html#2-directing-the-input","text":"The input is directed to the HandleMethod function: rpcResponse := HandleMethod ( rpcRequest ) You can view the implementation of this function in the identify_method.go file.","title":"2. Directing the Input"},{"location":"reference/lsp.html#3-adding-your-method","text":"To add your custom method, modify the HandleMethod function by adding a new case to the switch statement.","title":"3. Adding Your Method"},{"location":"reference/lsp.html#4-implementing-the-logic","text":"Write the logic for your method in the methods directory.","title":"4. Implementing the Logic"},{"location":"reference/lsp.html#5-using-and-defining-structs","text":"For general request structures, refer to JSONRPCRequest in general_request.go . If you need to define a custom struct for your method, add it in the request directory. For general response structures, refer to JSONRPCResponse in general_response.go .","title":"5. Using and Defining Structs"},{"location":"reference/lsp.html#6-utilizing-helper-functions","text":"The respond.go file provides helper functions to create success and error responses: func CreateSuccessResponse ( requestID int , result interface {}) JSONRPCResponse { ... } func ErrorResp ( req request . JSONRPCRequest , errorCode int , errorMsg string ) JSONRPCResponse { ... } Use these functions to streamline the response creation process.","title":"6. Utilizing Helper Functions"},{"location":"reference/outputmanager.html","text":"outputmanager \u00b6 import \"github.com/HexmosTech/lama2/outputManager\" Package `outputmanager` provides facilities for controlling the logging library as well as capabilities to post-process API execution results (such as store results as a JSON file) Index \u00b6 Variables func ConfigureZeroLog(level string) func DisableLogBuff() func ResponseToJSON(resp httpie.ExResponse, responseTimes []ResponseTime, statusCode []StatusCode, contentSizes []ContentSize) (*gabs.Container, error) func WriteJSONOutput(resp httpie.ExResponse, targetPath string, responseTime []ResponseTime, statusCodes []StatusCode, contentSizes []ContentSize) type ContentSize type ResponseTime type StatusCode Variables \u00b6 LogBuff is used to append various log statements into memory. If the user toggles the `Output (-o)` option, then the contents of LogBuff is pushed into a JSON file var LogBuff bytes . Buffer func ConfigureZeroLog \u00b6 func ConfigureZeroLog ( level string ) ConfigureZeroLog provides global log level setting. By default, ZeroLog uses the DEBUG level; however, the function makes the desired level more explicit func DisableLogBuff \u00b6 func DisableLogBuff () func ResponseToJSON \u00b6 func ResponseToJSON ( resp httpie . ExResponse , responseTimes [] ResponseTime , statusCode [] StatusCode , contentSizes [] ContentSize ) ( * gabs . Container , error ) func WriteJSONOutput \u00b6 func WriteJSONOutput ( resp httpie . ExResponse , targetPath string , responseTime [] ResponseTime , statusCodes [] StatusCode , contentSizes [] ContentSize ) WriteJSONOutput is primarily built for helping with Extension/Integration building with external tools. Extension writers may simply call `l2 -n -o /tmp/lama2.json ...` to invoke WriteJSONOutput; the generated json file contains three keys: `logs`, `headers`, `body` type ContentSize \u00b6 type ContentSize struct { Type string `json:\"type\"` SizeInBytes int `json:\"sizeInBytes\"` } type ResponseTime \u00b6 type ResponseTime struct { Type string `json:\"type\"` TimeInMs int64 `json:\"timeInMs\"` } type StatusCode \u00b6 type StatusCode struct { Type string `json:\"type\"` Status int `json:\"statusCode\"` } Generated by gomarkdoc","title":"Outputmanager"},{"location":"reference/outputmanager.html#outputmanager","text":"import \"github.com/HexmosTech/lama2/outputManager\" Package `outputmanager` provides facilities for controlling the logging library as well as capabilities to post-process API execution results (such as store results as a JSON file)","title":"outputmanager"},{"location":"reference/outputmanager.html#index","text":"Variables func ConfigureZeroLog(level string) func DisableLogBuff() func ResponseToJSON(resp httpie.ExResponse, responseTimes []ResponseTime, statusCode []StatusCode, contentSizes []ContentSize) (*gabs.Container, error) func WriteJSONOutput(resp httpie.ExResponse, targetPath string, responseTime []ResponseTime, statusCodes []StatusCode, contentSizes []ContentSize) type ContentSize type ResponseTime type StatusCode","title":"Index"},{"location":"reference/outputmanager.html#variables","text":"LogBuff is used to append various log statements into memory. If the user toggles the `Output (-o)` option, then the contents of LogBuff is pushed into a JSON file var LogBuff bytes . Buffer","title":"Variables"},{"location":"reference/outputmanager.html#func-configurezerolog","text":"func ConfigureZeroLog ( level string ) ConfigureZeroLog provides global log level setting. By default, ZeroLog uses the DEBUG level; however, the function makes the desired level more explicit","title":"func ConfigureZeroLog"},{"location":"reference/outputmanager.html#func-disablelogbuff","text":"func DisableLogBuff ()","title":"func DisableLogBuff"},{"location":"reference/outputmanager.html#func-responsetojson","text":"func ResponseToJSON ( resp httpie . ExResponse , responseTimes [] ResponseTime , statusCode [] StatusCode , contentSizes [] ContentSize ) ( * gabs . Container , error )","title":"func ResponseToJSON"},{"location":"reference/outputmanager.html#func-writejsonoutput","text":"func WriteJSONOutput ( resp httpie . ExResponse , targetPath string , responseTime [] ResponseTime , statusCodes [] StatusCode , contentSizes [] ContentSize ) WriteJSONOutput is primarily built for helping with Extension/Integration building with external tools. Extension writers may simply call `l2 -n -o /tmp/lama2.json ...` to invoke WriteJSONOutput; the generated json file contains three keys: `logs`, `headers`, `body`","title":"func WriteJSONOutput"},{"location":"reference/outputmanager.html#type-contentsize","text":"type ContentSize struct { Type string `json:\"type\"` SizeInBytes int `json:\"sizeInBytes\"` }","title":"type ContentSize"},{"location":"reference/outputmanager.html#type-responsetime","text":"type ResponseTime struct { Type string `json:\"type\"` TimeInMs int64 `json:\"timeInMs\"` }","title":"type ResponseTime"},{"location":"reference/outputmanager.html#type-statuscode","text":"type StatusCode struct { Type string `json:\"type\"` Status int `json:\"statusCode\"` } Generated by gomarkdoc","title":"type StatusCode"},{"location":"reference/parser.html","text":"parser \u00b6 import \"github.com/HexmosTech/lama2/parser\" The `parser` package provides primitives that help with writing recursive descent parsers. This version is a golang port of the original Python implementation from https://tinyurl.com/rdescent The `Parser` struct is supposed to be extended to support parsing a new language. Take a look at `lama2parser.go` for an example. Essentially the actual parsing begins from the `Start()` method. Index \u00b6 Variables func CustomPairMerge(destination, source interface{}) interface{} type Lama2Parser func NewLama2Parser() *Lama2Parser func (p *Lama2Parser) AnyType() (*gabs.Container, error) func (p *Lama2Parser) Boolean() (*gabs.Container, error) func (p *Lama2Parser) ComplexType() (*gabs.Container, error) func (p *Lama2Parser) DataHeader() (*gabs.Container, error) func (p *Lama2Parser) DataInput() (*gabs.Container, error) func (p *Lama2Parser) Details() (*gabs.Container, error) func (p *Lama2Parser) Digit() (*gabs.Container, error) func (p *Lama2Parser) Digits() (*gabs.Container, error) func (p *Lama2Parser) Exponent() (*gabs.Container, error) func (p *Lama2Parser) FilesPair() (*gabs.Container, error) func (p *Lama2Parser) FilesUnquoted() (*gabs.Container, error) func (p *Lama2Parser) Form() (*gabs.Container, error) func (p *Lama2Parser) Fraction() (*gabs.Container, error) func (p *Lama2Parser) FractionRule1() (*gabs.Container, error) func (p *Lama2Parser) HTTPVerb() (*gabs.Container, error) func (p *Lama2Parser) HeaderData() (*gabs.Container, error) func (p *Lama2Parser) HeaderPair() (*gabs.Container, error) func (p *Lama2Parser) Headers() (*gabs.Container, error) func (p *Lama2Parser) Integer() (*gabs.Container, error) func (p *Lama2Parser) IntegerRule1() (*gabs.Container, error) func (p *Lama2Parser) IntegerRule2() (*gabs.Container, error) func (p *Lama2Parser) IntegerRule3() (*gabs.Container, error) func (p *Lama2Parser) IntegerRule4() (*gabs.Container, error) func (p *Lama2Parser) L2Variable() (*gabs.Container, error) func (p *Lama2Parser) Lama2File() (*gabs.Container, error) func (p *Lama2Parser) List() (*gabs.Container, error) func (p *Lama2Parser) Map() (*gabs.Container, error) func (p *Lama2Parser) Multipart() (*gabs.Container, error) func (p *Lama2Parser) Null() (*gabs.Container, error) func (p *Lama2Parser) Number() (*gabs.Container, error) func (p *Lama2Parser) OneNine() (*gabs.Container, error) func (p *Lama2Parser) Pair() (*gabs.Container, error) func (p *Lama2Parser) PrimitiveType() (*gabs.Container, error) func (p *Lama2Parser) Processor() (*gabs.Container, error) func (p *Lama2Parser) QuotedString() (*gabs.Container, error) func (p *Lama2Parser) Requester() (*gabs.Container, error) func (p *Lama2Parser) Separator() (*gabs.Container, error) func (p *Lama2Parser) Sign() (*gabs.Container, error) func (p *Lama2Parser) Start() (*gabs.Container, error) func (p *Lama2Parser) TheURL() (*gabs.Container, error) func (p *Lama2Parser) Unquoted() (*gabs.Container, error) func (p *Lama2Parser) VarJSON() (*gabs.Container, error) func (p *Lama2Parser) VarJSONPair() (*gabs.Container, error) func (p *Lama2Parser) VarJSONUnquoted() (*gabs.Container, error) type MinimalParser type Parser func (p *Parser) Char() (rune, error) func (p *Parser) CharClass(charClass string) (rune, error) func (p *Parser) Init() func (p *Parser) Keyword(kw string, eatWsStart bool, eatWsEnd bool, caseInsensitive bool) ([]rune, error) func (p *Parser) LookAhead(rules []string) bool func (p *Parser) Match(rules []string) (*gabs.Container, error) func (p *Parser) MatchUntil(end string) (*gabs.Container, error) func (p *Parser) Parse(text string) (*gabs.Container, error) func (p *Parser) SetText(text string) func (p *Parser) SplitCharRanges(charClass string) ([]string, error) func (p *Parser) Start() *gabs.Container Variables \u00b6 var DataInputType string func CustomPairMerge \u00b6 func CustomPairMerge ( destination , source interface {}) interface {} CustomPairMerge uses a gabs feature to deal with merge conflicts. More here: https://github.com/HexmosTech/gabs/blob/master/gabs.go#L511 type Lama2Parser \u00b6 type Lama2Parser struct { * Parser Context map [ string ] bool MarkRange map [ string ] int } func NewLama2Parser \u00b6 func NewLama2Parser () * Lama2Parser NewLama2Parser creates a new Lama2Parser and initializes it properly func (*Lama2Parser) AnyType \u00b6 func ( p * Lama2Parser ) AnyType () ( * gabs . Container , error ) AnyType is the top-most element of a JSON structure It consists of Complex and Primitive Types func (*Lama2Parser) Boolean \u00b6 func ( p * Lama2Parser ) Boolean () ( * gabs . Container , error ) func (*Lama2Parser) ComplexType \u00b6 func ( p * Lama2Parser ) ComplexType () ( * gabs . Container , error ) func (*Lama2Parser) DataHeader \u00b6 func ( p * Lama2Parser ) DataHeader () ( * gabs . Container , error ) func (*Lama2Parser) DataInput \u00b6 func ( p * Lama2Parser ) DataInput () ( * gabs . Container , error ) func (*Lama2Parser) Details \u00b6 func ( p * Lama2Parser ) Details () ( * gabs . Container , error ) func (*Lama2Parser) Digit \u00b6 func ( p * Lama2Parser ) Digit () ( * gabs . Container , error ) func (*Lama2Parser) Digits \u00b6 func ( p * Lama2Parser ) Digits () ( * gabs . Container , error ) func (*Lama2Parser) Exponent \u00b6 func ( p * Lama2Parser ) Exponent () ( * gabs . Container , error ) An Exponent consists of mandatory 'e' or 'E', optional Sign, followed by Digits func (*Lama2Parser) FilesPair \u00b6 func ( p * Lama2Parser ) FilesPair () ( * gabs . Container , error ) FilesPair tries to match key and value separated by `@`. The key and value can either be a quoted string, or an unquoted Files Unquoted String. If there is no match for either, a ParseError is returned. func (*Lama2Parser) FilesUnquoted \u00b6 func ( p * Lama2Parser ) FilesUnquoted () ( * gabs . Container , error ) FilesUnquoted matches a string of characters other than `@` and returns them as a String func (*Lama2Parser) Form \u00b6 func ( p * Lama2Parser ) Form () ( * gabs . Container , error ) func (*Lama2Parser) Fraction \u00b6 func ( p * Lama2Parser ) Fraction () ( * gabs . Container , error ) func (*Lama2Parser) FractionRule1 \u00b6 func ( p * Lama2Parser ) FractionRule1 () ( * gabs . Container , error ) A Fraction consists of mandatory \".\" (dot), followed by Digits. func (*Lama2Parser) HTTPVerb \u00b6 func ( p * Lama2Parser ) HTTPVerb () ( * gabs . Container , error ) func (*Lama2Parser) HeaderData \u00b6 func ( p * Lama2Parser ) HeaderData () ( * gabs . Container , error ) func (*Lama2Parser) HeaderPair \u00b6 func ( p * Lama2Parser ) HeaderPair () ( * gabs . Container , error ) func (*Lama2Parser) Headers \u00b6 func ( p * Lama2Parser ) Headers () ( * gabs . Container , error ) Headers detects HTTP headers; essentially strings separated by \":\" character func (*Lama2Parser) Integer \u00b6 func ( p * Lama2Parser ) Integer () ( * gabs . Container , error ) func (*Lama2Parser) IntegerRule1 \u00b6 func ( p * Lama2Parser ) IntegerRule1 () ( * gabs . Container , error ) InterRule1 matches a Digit func (*Lama2Parser) IntegerRule2 \u00b6 func ( p * Lama2Parser ) IntegerRule2 () ( * gabs . Container , error ) IntegerRule2 matches 1-9 mandatorily, and then tries to follow it with Digits func (*Lama2Parser) IntegerRule3 \u00b6 func ( p * Lama2Parser ) IntegerRule3 () ( * gabs . Container , error ) IntegerRule3 starts with a mandatory Sign, and follows with IntegerRule1 (Digit) func (*Lama2Parser) IntegerRule4 \u00b6 func ( p * Lama2Parser ) IntegerRule4 () ( * gabs . Container , error ) IntegerRule4 starts with a mandatory Sign, and follows with IntegerRule2 func (*Lama2Parser) L2Variable \u00b6 func ( p * Lama2Parser ) L2Variable () ( * gabs . Container , error ) func (*Lama2Parser) Lama2File \u00b6 func ( p * Lama2Parser ) Lama2File () ( * gabs . Container , error ) func (*Lama2Parser) List \u00b6 func ( p * Lama2Parser ) List () ( * gabs . Container , error ) List is a slightly lenient version of standard JSON list. In Lama2 List, it is OK to have a trailing comma after the last element (whereas in strict JSON, it is not OK to have trailing comma) func (*Lama2Parser) Map \u00b6 func ( p * Lama2Parser ) Map () ( * gabs . Container , error ) Map is a slightly lenient version of standard JSON map. In Lama2 Map, it is OK to have a trailing comma after the last element (whereas in strict JSON, it is not OK to have trailing comma) func (*Lama2Parser) Multipart \u00b6 func ( p * Lama2Parser ) Multipart () ( * gabs . Container , error ) func (*Lama2Parser) Null \u00b6 func ( p * Lama2Parser ) Null () ( * gabs . Container , error ) func (*Lama2Parser) Number \u00b6 func ( p * Lama2Parser ) Number () ( * gabs . Container , error ) A Number consists of a mandatory integer part, and optional Fraction and Exponent parts. The Number method \"collects\" these three elements, converts them into a json.Number() type, and finally returns the Number wrapped within a gabs Container func (*Lama2Parser) OneNine \u00b6 func ( p * Lama2Parser ) OneNine () ( * gabs . Container , error ) func (*Lama2Parser) Pair \u00b6 func ( p * Lama2Parser ) Pair () ( * gabs . Container , error ) func (*Lama2Parser) PrimitiveType \u00b6 func ( p * Lama2Parser ) PrimitiveType () ( * gabs . Container , error ) func (*Lama2Parser) Processor \u00b6 func ( p * Lama2Parser ) Processor () ( * gabs . Container , error ) func (*Lama2Parser) QuotedString \u00b6 func ( p * Lama2Parser ) QuotedString () ( * gabs . Container , error ) QuotedString accepts both single-quoted and double-quoted types of strings. Moreover, it can deal with unicode escape characters, control characters appropriately Ultimately, we get a string wrapped in a gabs container func (*Lama2Parser) Requester \u00b6 func ( p * Lama2Parser ) Requester () ( * gabs . Container , error ) Requester applies the rule: HTTPVerb Multipart? TheURL Details? func (*Lama2Parser) Separator \u00b6 func ( p * Lama2Parser ) Separator () ( * gabs . Container , error ) func (*Lama2Parser) Sign \u00b6 func ( p * Lama2Parser ) Sign () ( * gabs . Container , error ) func (*Lama2Parser) Start \u00b6 func ( p * Lama2Parser ) Start () ( * gabs . Container , error ) Start primarily calls the Lama2File method func (*Lama2Parser) TheURL \u00b6 func ( p * Lama2Parser ) TheURL () ( * gabs . Container , error ) func (*Lama2Parser) Unquoted \u00b6 func ( p * Lama2Parser ) Unquoted () ( * gabs . Container , error ) func (*Lama2Parser) VarJSON \u00b6 func ( p * Lama2Parser ) VarJSON () ( * gabs . Container , error ) Method VarJSON behaves in two ways depending on whether `multipart` or `form` is true or not. If there is no multipart, then VarJSON tries to match one or more VarJSONPairs However, if there is multipart or form, we try to match zero or more VarJSON, followed by zero or more file fields (separated by `@`). If there is no match at all, we return a ParseError; otherwise the we return the parsed data. func (*Lama2Parser) VarJSONPair \u00b6 func ( p * Lama2Parser ) VarJSONPair () ( * gabs . Container , error ) VarJSONPair tries to match key and value separated by `=`. The key and value can either be a quoted string, or an unquoted VarJSON unquoted string. If there is no match for either, a ParseError is returned. func (*Lama2Parser) VarJSONUnquoted \u00b6 func ( p * Lama2Parser ) VarJSONUnquoted () ( * gabs . Container , error ) VarJSONUnquoted matches a string of characters other than `=` and returns them as a String type MinimalParser \u00b6 MinimalParser enforces concrete Types to have a Start() method, from which parsing process begins. In the present case, `Lama2Parser` adds up dozens of of methods to implement `.l2` syntax type MinimalParser interface { Start () ( * gabs . Container , error ) } type Parser \u00b6 Struct Parser stores information about the parsing process throughout. 1. Text: Incoming text is stored as an array of runes, to correctly handle unicode characters 2. Pos: Indicates the index position in Text which has already been scanned; starts with -1 3. TotalLen: Number of runes in the input 4. Pm: Composing an external MinimalParser (such as Lama2Parser) which builds upon Parser to provide the new language recognition capabilities 5. ruleMethodMap: Scans through Pm, and creates a mapping from method name to method value through reflection 6. LineNum: Number of normalized newlines found till now. Used in providing useful context in error messages type Parser struct { Text [] rune Pos int TotalLen int Pm MinimalParser LineNum int // contains filtered or unexported fields } func (*Parser) Char \u00b6 func ( p * Parser ) Char () ( rune , error ) func (*Parser) CharClass \u00b6 func ( p * Parser ) CharClass ( charClass string ) ( rune , error ) CharClass implements the familiar regex syntax for specifying ranges of characters that are deemed acceptable. A good description of CharClass is available here: Read the section \"Processing Character Ranges\" at https://www.booleanworld.com/building-recursive-descent-parsers-definitive-guide/ func (*Parser) Init \u00b6 func ( p * Parser ) Init () Method Init creates the most important data stucture for parsing: ruleMethodMap. We use reflection to create a mapping of each Pm.\\<method_name> to \\<method_value> func (*Parser) Keyword \u00b6 func ( p * Parser ) Keyword ( kw string , eatWsStart bool , eatWsEnd bool , caseInsensitive bool ) ([] rune , error ) Method Keyword is a versatile; it can eat whitespace before/after the expected string, and it can do an optionally case insensitive match for the keyword func (*Parser) LookAhead \u00b6 func ( p * Parser ) LookAhead ( rules [] string ) bool func (*Parser) Match \u00b6 func ( p * Parser ) Match ( rules [] string ) ( * gabs . Container , error ) Method Match is the most important of all in the parser package. Match takes in a slice of rules (essentially method names), and then executes them one by one. On successful match, we return a gabs Container with `error` set to `nil` When a rule fails to match, we reset the scan position to initial position; moreover, we keep a continuous track of the farthest/longest match till present. The farthest match error is potentially the most useful error message to the user; thus, for error report, Match returns the farthest matching error func (*Parser) MatchUntil \u00b6 func ( p * Parser ) MatchUntil ( end string ) ( * gabs . Container , error ) func (*Parser) Parse \u00b6 func ( p * Parser ) Parse ( text string ) ( * gabs . Container , error ) Method Parse normalizes newlines and then creates a rune version of the input data. The Start() method proceeds to process the rune version of data func (*Parser) SetText \u00b6 func ( p * Parser ) SetText ( text string ) Method SetText is a utility used primarily in testing, when we don't want to call Start() automatically as in Parse func (*Parser) SplitCharRanges \u00b6 func ( p * Parser ) SplitCharRanges ( charClass string ) ([] string , error ) func (*Parser) Start \u00b6 func ( p * Parser ) Start () * gabs . Container Start() in Parser provides a dummy default implementation; the expectation is that the higher level Struct (Pm) will implement its own version Generated by gomarkdoc","title":"Parser"},{"location":"reference/parser.html#parser","text":"import \"github.com/HexmosTech/lama2/parser\" The `parser` package provides primitives that help with writing recursive descent parsers. This version is a golang port of the original Python implementation from https://tinyurl.com/rdescent The `Parser` struct is supposed to be extended to support parsing a new language. Take a look at `lama2parser.go` for an example. Essentially the actual parsing begins from the `Start()` method.","title":"parser"},{"location":"reference/parser.html#index","text":"Variables func CustomPairMerge(destination, source interface{}) interface{} type Lama2Parser func NewLama2Parser() *Lama2Parser func (p *Lama2Parser) AnyType() (*gabs.Container, error) func (p *Lama2Parser) Boolean() (*gabs.Container, error) func (p *Lama2Parser) ComplexType() (*gabs.Container, error) func (p *Lama2Parser) DataHeader() (*gabs.Container, error) func (p *Lama2Parser) DataInput() (*gabs.Container, error) func (p *Lama2Parser) Details() (*gabs.Container, error) func (p *Lama2Parser) Digit() (*gabs.Container, error) func (p *Lama2Parser) Digits() (*gabs.Container, error) func (p *Lama2Parser) Exponent() (*gabs.Container, error) func (p *Lama2Parser) FilesPair() (*gabs.Container, error) func (p *Lama2Parser) FilesUnquoted() (*gabs.Container, error) func (p *Lama2Parser) Form() (*gabs.Container, error) func (p *Lama2Parser) Fraction() (*gabs.Container, error) func (p *Lama2Parser) FractionRule1() (*gabs.Container, error) func (p *Lama2Parser) HTTPVerb() (*gabs.Container, error) func (p *Lama2Parser) HeaderData() (*gabs.Container, error) func (p *Lama2Parser) HeaderPair() (*gabs.Container, error) func (p *Lama2Parser) Headers() (*gabs.Container, error) func (p *Lama2Parser) Integer() (*gabs.Container, error) func (p *Lama2Parser) IntegerRule1() (*gabs.Container, error) func (p *Lama2Parser) IntegerRule2() (*gabs.Container, error) func (p *Lama2Parser) IntegerRule3() (*gabs.Container, error) func (p *Lama2Parser) IntegerRule4() (*gabs.Container, error) func (p *Lama2Parser) L2Variable() (*gabs.Container, error) func (p *Lama2Parser) Lama2File() (*gabs.Container, error) func (p *Lama2Parser) List() (*gabs.Container, error) func (p *Lama2Parser) Map() (*gabs.Container, error) func (p *Lama2Parser) Multipart() (*gabs.Container, error) func (p *Lama2Parser) Null() (*gabs.Container, error) func (p *Lama2Parser) Number() (*gabs.Container, error) func (p *Lama2Parser) OneNine() (*gabs.Container, error) func (p *Lama2Parser) Pair() (*gabs.Container, error) func (p *Lama2Parser) PrimitiveType() (*gabs.Container, error) func (p *Lama2Parser) Processor() (*gabs.Container, error) func (p *Lama2Parser) QuotedString() (*gabs.Container, error) func (p *Lama2Parser) Requester() (*gabs.Container, error) func (p *Lama2Parser) Separator() (*gabs.Container, error) func (p *Lama2Parser) Sign() (*gabs.Container, error) func (p *Lama2Parser) Start() (*gabs.Container, error) func (p *Lama2Parser) TheURL() (*gabs.Container, error) func (p *Lama2Parser) Unquoted() (*gabs.Container, error) func (p *Lama2Parser) VarJSON() (*gabs.Container, error) func (p *Lama2Parser) VarJSONPair() (*gabs.Container, error) func (p *Lama2Parser) VarJSONUnquoted() (*gabs.Container, error) type MinimalParser type Parser func (p *Parser) Char() (rune, error) func (p *Parser) CharClass(charClass string) (rune, error) func (p *Parser) Init() func (p *Parser) Keyword(kw string, eatWsStart bool, eatWsEnd bool, caseInsensitive bool) ([]rune, error) func (p *Parser) LookAhead(rules []string) bool func (p *Parser) Match(rules []string) (*gabs.Container, error) func (p *Parser) MatchUntil(end string) (*gabs.Container, error) func (p *Parser) Parse(text string) (*gabs.Container, error) func (p *Parser) SetText(text string) func (p *Parser) SplitCharRanges(charClass string) ([]string, error) func (p *Parser) Start() *gabs.Container","title":"Index"},{"location":"reference/parser.html#variables","text":"var DataInputType string","title":"Variables"},{"location":"reference/parser.html#func-custompairmerge","text":"func CustomPairMerge ( destination , source interface {}) interface {} CustomPairMerge uses a gabs feature to deal with merge conflicts. More here: https://github.com/HexmosTech/gabs/blob/master/gabs.go#L511","title":"func CustomPairMerge"},{"location":"reference/parser.html#type-lama2parser","text":"type Lama2Parser struct { * Parser Context map [ string ] bool MarkRange map [ string ] int }","title":"type Lama2Parser"},{"location":"reference/parser.html#func-newlama2parser","text":"func NewLama2Parser () * Lama2Parser NewLama2Parser creates a new Lama2Parser and initializes it properly","title":"func NewLama2Parser"},{"location":"reference/parser.html#func-lama2parser-anytype","text":"func ( p * Lama2Parser ) AnyType () ( * gabs . Container , error ) AnyType is the top-most element of a JSON structure It consists of Complex and Primitive Types","title":"func (*Lama2Parser) AnyType"},{"location":"reference/parser.html#func-lama2parser-boolean","text":"func ( p * Lama2Parser ) Boolean () ( * gabs . Container , error )","title":"func (*Lama2Parser) Boolean"},{"location":"reference/parser.html#func-lama2parser-complextype","text":"func ( p * Lama2Parser ) ComplexType () ( * gabs . Container , error )","title":"func (*Lama2Parser) ComplexType"},{"location":"reference/parser.html#func-lama2parser-dataheader","text":"func ( p * Lama2Parser ) DataHeader () ( * gabs . Container , error )","title":"func (*Lama2Parser) DataHeader"},{"location":"reference/parser.html#func-lama2parser-datainput","text":"func ( p * Lama2Parser ) DataInput () ( * gabs . Container , error )","title":"func (*Lama2Parser) DataInput"},{"location":"reference/parser.html#func-lama2parser-details","text":"func ( p * Lama2Parser ) Details () ( * gabs . Container , error )","title":"func (*Lama2Parser) Details"},{"location":"reference/parser.html#func-lama2parser-digit","text":"func ( p * Lama2Parser ) Digit () ( * gabs . Container , error )","title":"func (*Lama2Parser) Digit"},{"location":"reference/parser.html#func-lama2parser-digits","text":"func ( p * Lama2Parser ) Digits () ( * gabs . Container , error )","title":"func (*Lama2Parser) Digits"},{"location":"reference/parser.html#func-lama2parser-exponent","text":"func ( p * Lama2Parser ) Exponent () ( * gabs . Container , error ) An Exponent consists of mandatory 'e' or 'E', optional Sign, followed by Digits","title":"func (*Lama2Parser) Exponent"},{"location":"reference/parser.html#func-lama2parser-filespair","text":"func ( p * Lama2Parser ) FilesPair () ( * gabs . Container , error ) FilesPair tries to match key and value separated by `@`. The key and value can either be a quoted string, or an unquoted Files Unquoted String. If there is no match for either, a ParseError is returned.","title":"func (*Lama2Parser) FilesPair"},{"location":"reference/parser.html#func-lama2parser-filesunquoted","text":"func ( p * Lama2Parser ) FilesUnquoted () ( * gabs . Container , error ) FilesUnquoted matches a string of characters other than `@` and returns them as a String","title":"func (*Lama2Parser) FilesUnquoted"},{"location":"reference/parser.html#func-lama2parser-form","text":"func ( p * Lama2Parser ) Form () ( * gabs . Container , error )","title":"func (*Lama2Parser) Form"},{"location":"reference/parser.html#func-lama2parser-fraction","text":"func ( p * Lama2Parser ) Fraction () ( * gabs . Container , error )","title":"func (*Lama2Parser) Fraction"},{"location":"reference/parser.html#func-lama2parser-fractionrule1","text":"func ( p * Lama2Parser ) FractionRule1 () ( * gabs . Container , error ) A Fraction consists of mandatory \".\" (dot), followed by Digits.","title":"func (*Lama2Parser) FractionRule1"},{"location":"reference/parser.html#func-lama2parser-httpverb","text":"func ( p * Lama2Parser ) HTTPVerb () ( * gabs . Container , error )","title":"func (*Lama2Parser) HTTPVerb"},{"location":"reference/parser.html#func-lama2parser-headerdata","text":"func ( p * Lama2Parser ) HeaderData () ( * gabs . Container , error )","title":"func (*Lama2Parser) HeaderData"},{"location":"reference/parser.html#func-lama2parser-headerpair","text":"func ( p * Lama2Parser ) HeaderPair () ( * gabs . Container , error )","title":"func (*Lama2Parser) HeaderPair"},{"location":"reference/parser.html#func-lama2parser-headers","text":"func ( p * Lama2Parser ) Headers () ( * gabs . Container , error ) Headers detects HTTP headers; essentially strings separated by \":\" character","title":"func (*Lama2Parser) Headers"},{"location":"reference/parser.html#func-lama2parser-integer","text":"func ( p * Lama2Parser ) Integer () ( * gabs . Container , error )","title":"func (*Lama2Parser) Integer"},{"location":"reference/parser.html#func-lama2parser-integerrule1","text":"func ( p * Lama2Parser ) IntegerRule1 () ( * gabs . Container , error ) InterRule1 matches a Digit","title":"func (*Lama2Parser) IntegerRule1"},{"location":"reference/parser.html#func-lama2parser-integerrule2","text":"func ( p * Lama2Parser ) IntegerRule2 () ( * gabs . Container , error ) IntegerRule2 matches 1-9 mandatorily, and then tries to follow it with Digits","title":"func (*Lama2Parser) IntegerRule2"},{"location":"reference/parser.html#func-lama2parser-integerrule3","text":"func ( p * Lama2Parser ) IntegerRule3 () ( * gabs . Container , error ) IntegerRule3 starts with a mandatory Sign, and follows with IntegerRule1 (Digit)","title":"func (*Lama2Parser) IntegerRule3"},{"location":"reference/parser.html#func-lama2parser-integerrule4","text":"func ( p * Lama2Parser ) IntegerRule4 () ( * gabs . Container , error ) IntegerRule4 starts with a mandatory Sign, and follows with IntegerRule2","title":"func (*Lama2Parser) IntegerRule4"},{"location":"reference/parser.html#func-lama2parser-l2variable","text":"func ( p * Lama2Parser ) L2Variable () ( * gabs . Container , error )","title":"func (*Lama2Parser) L2Variable"},{"location":"reference/parser.html#func-lama2parser-lama2file","text":"func ( p * Lama2Parser ) Lama2File () ( * gabs . Container , error )","title":"func (*Lama2Parser) Lama2File"},{"location":"reference/parser.html#func-lama2parser-list","text":"func ( p * Lama2Parser ) List () ( * gabs . Container , error ) List is a slightly lenient version of standard JSON list. In Lama2 List, it is OK to have a trailing comma after the last element (whereas in strict JSON, it is not OK to have trailing comma)","title":"func (*Lama2Parser) List"},{"location":"reference/parser.html#func-lama2parser-map","text":"func ( p * Lama2Parser ) Map () ( * gabs . Container , error ) Map is a slightly lenient version of standard JSON map. In Lama2 Map, it is OK to have a trailing comma after the last element (whereas in strict JSON, it is not OK to have trailing comma)","title":"func (*Lama2Parser) Map"},{"location":"reference/parser.html#func-lama2parser-multipart","text":"func ( p * Lama2Parser ) Multipart () ( * gabs . Container , error )","title":"func (*Lama2Parser) Multipart"},{"location":"reference/parser.html#func-lama2parser-null","text":"func ( p * Lama2Parser ) Null () ( * gabs . Container , error )","title":"func (*Lama2Parser) Null"},{"location":"reference/parser.html#func-lama2parser-number","text":"func ( p * Lama2Parser ) Number () ( * gabs . Container , error ) A Number consists of a mandatory integer part, and optional Fraction and Exponent parts. The Number method \"collects\" these three elements, converts them into a json.Number() type, and finally returns the Number wrapped within a gabs Container","title":"func (*Lama2Parser) Number"},{"location":"reference/parser.html#func-lama2parser-onenine","text":"func ( p * Lama2Parser ) OneNine () ( * gabs . Container , error )","title":"func (*Lama2Parser) OneNine"},{"location":"reference/parser.html#func-lama2parser-pair","text":"func ( p * Lama2Parser ) Pair () ( * gabs . Container , error )","title":"func (*Lama2Parser) Pair"},{"location":"reference/parser.html#func-lama2parser-primitivetype","text":"func ( p * Lama2Parser ) PrimitiveType () ( * gabs . Container , error )","title":"func (*Lama2Parser) PrimitiveType"},{"location":"reference/parser.html#func-lama2parser-processor","text":"func ( p * Lama2Parser ) Processor () ( * gabs . Container , error )","title":"func (*Lama2Parser) Processor"},{"location":"reference/parser.html#func-lama2parser-quotedstring","text":"func ( p * Lama2Parser ) QuotedString () ( * gabs . Container , error ) QuotedString accepts both single-quoted and double-quoted types of strings. Moreover, it can deal with unicode escape characters, control characters appropriately Ultimately, we get a string wrapped in a gabs container","title":"func (*Lama2Parser) QuotedString"},{"location":"reference/parser.html#func-lama2parser-requester","text":"func ( p * Lama2Parser ) Requester () ( * gabs . Container , error ) Requester applies the rule: HTTPVerb Multipart? TheURL Details?","title":"func (*Lama2Parser) Requester"},{"location":"reference/parser.html#func-lama2parser-separator","text":"func ( p * Lama2Parser ) Separator () ( * gabs . Container , error )","title":"func (*Lama2Parser) Separator"},{"location":"reference/parser.html#func-lama2parser-sign","text":"func ( p * Lama2Parser ) Sign () ( * gabs . Container , error )","title":"func (*Lama2Parser) Sign"},{"location":"reference/parser.html#func-lama2parser-start","text":"func ( p * Lama2Parser ) Start () ( * gabs . Container , error ) Start primarily calls the Lama2File method","title":"func (*Lama2Parser) Start"},{"location":"reference/parser.html#func-lama2parser-theurl","text":"func ( p * Lama2Parser ) TheURL () ( * gabs . Container , error )","title":"func (*Lama2Parser) TheURL"},{"location":"reference/parser.html#func-lama2parser-unquoted","text":"func ( p * Lama2Parser ) Unquoted () ( * gabs . Container , error )","title":"func (*Lama2Parser) Unquoted"},{"location":"reference/parser.html#func-lama2parser-varjson","text":"func ( p * Lama2Parser ) VarJSON () ( * gabs . Container , error ) Method VarJSON behaves in two ways depending on whether `multipart` or `form` is true or not. If there is no multipart, then VarJSON tries to match one or more VarJSONPairs However, if there is multipart or form, we try to match zero or more VarJSON, followed by zero or more file fields (separated by `@`). If there is no match at all, we return a ParseError; otherwise the we return the parsed data.","title":"func (*Lama2Parser) VarJSON"},{"location":"reference/parser.html#func-lama2parser-varjsonpair","text":"func ( p * Lama2Parser ) VarJSONPair () ( * gabs . Container , error ) VarJSONPair tries to match key and value separated by `=`. The key and value can either be a quoted string, or an unquoted VarJSON unquoted string. If there is no match for either, a ParseError is returned.","title":"func (*Lama2Parser) VarJSONPair"},{"location":"reference/parser.html#func-lama2parser-varjsonunquoted","text":"func ( p * Lama2Parser ) VarJSONUnquoted () ( * gabs . Container , error ) VarJSONUnquoted matches a string of characters other than `=` and returns them as a String","title":"func (*Lama2Parser) VarJSONUnquoted"},{"location":"reference/parser.html#type-minimalparser","text":"MinimalParser enforces concrete Types to have a Start() method, from which parsing process begins. In the present case, `Lama2Parser` adds up dozens of of methods to implement `.l2` syntax type MinimalParser interface { Start () ( * gabs . Container , error ) }","title":"type MinimalParser"},{"location":"reference/parser.html#type-parser","text":"Struct Parser stores information about the parsing process throughout. 1. Text: Incoming text is stored as an array of runes, to correctly handle unicode characters 2. Pos: Indicates the index position in Text which has already been scanned; starts with -1 3. TotalLen: Number of runes in the input 4. Pm: Composing an external MinimalParser (such as Lama2Parser) which builds upon Parser to provide the new language recognition capabilities 5. ruleMethodMap: Scans through Pm, and creates a mapping from method name to method value through reflection 6. LineNum: Number of normalized newlines found till now. Used in providing useful context in error messages type Parser struct { Text [] rune Pos int TotalLen int Pm MinimalParser LineNum int // contains filtered or unexported fields }","title":"type Parser"},{"location":"reference/parser.html#func-parser-char","text":"func ( p * Parser ) Char () ( rune , error )","title":"func (*Parser) Char"},{"location":"reference/parser.html#func-parser-charclass","text":"func ( p * Parser ) CharClass ( charClass string ) ( rune , error ) CharClass implements the familiar regex syntax for specifying ranges of characters that are deemed acceptable. A good description of CharClass is available here: Read the section \"Processing Character Ranges\" at https://www.booleanworld.com/building-recursive-descent-parsers-definitive-guide/","title":"func (*Parser) CharClass"},{"location":"reference/parser.html#func-parser-init","text":"func ( p * Parser ) Init () Method Init creates the most important data stucture for parsing: ruleMethodMap. We use reflection to create a mapping of each Pm.\\<method_name> to \\<method_value>","title":"func (*Parser) Init"},{"location":"reference/parser.html#func-parser-keyword","text":"func ( p * Parser ) Keyword ( kw string , eatWsStart bool , eatWsEnd bool , caseInsensitive bool ) ([] rune , error ) Method Keyword is a versatile; it can eat whitespace before/after the expected string, and it can do an optionally case insensitive match for the keyword","title":"func (*Parser) Keyword"},{"location":"reference/parser.html#func-parser-lookahead","text":"func ( p * Parser ) LookAhead ( rules [] string ) bool","title":"func (*Parser) LookAhead"},{"location":"reference/parser.html#func-parser-match","text":"func ( p * Parser ) Match ( rules [] string ) ( * gabs . Container , error ) Method Match is the most important of all in the parser package. Match takes in a slice of rules (essentially method names), and then executes them one by one. On successful match, we return a gabs Container with `error` set to `nil` When a rule fails to match, we reset the scan position to initial position; moreover, we keep a continuous track of the farthest/longest match till present. The farthest match error is potentially the most useful error message to the user; thus, for error report, Match returns the farthest matching error","title":"func (*Parser) Match"},{"location":"reference/parser.html#func-parser-matchuntil","text":"func ( p * Parser ) MatchUntil ( end string ) ( * gabs . Container , error )","title":"func (*Parser) MatchUntil"},{"location":"reference/parser.html#func-parser-parse","text":"func ( p * Parser ) Parse ( text string ) ( * gabs . Container , error ) Method Parse normalizes newlines and then creates a rune version of the input data. The Start() method proceeds to process the rune version of data","title":"func (*Parser) Parse"},{"location":"reference/parser.html#func-parser-settext","text":"func ( p * Parser ) SetText ( text string ) Method SetText is a utility used primarily in testing, when we don't want to call Start() automatically as in Parse","title":"func (*Parser) SetText"},{"location":"reference/parser.html#func-parser-splitcharranges","text":"func ( p * Parser ) SplitCharRanges ( charClass string ) ([] string , error )","title":"func (*Parser) SplitCharRanges"},{"location":"reference/parser.html#func-parser-start","text":"func ( p * Parser ) Start () * gabs . Container Start() in Parser provides a dummy default implementation; the expectation is that the higher level Struct (Pm) will implement its own version Generated by gomarkdoc","title":"func (*Parser) Start"},{"location":"reference/philosophy.html","text":"Lama2 takes inspiration from Markdown . Think of our approach as Markdown for APIs . In particular, we strive to: Delegate subtasks to mature and preferably open tools: API Collaboration - git API Organization - OS file manager + IDEs API Editing - VSCode/IDEs API Requests - HTTPie ( httpie-go , to be specific) Request Chaining - Embedded Javascript Adhere to a continuous language formalization effort from the beginning (learning from Markdown history) Keep language syntax simple; don't sacrifice readability for tiny functionality gains. Invest into good documentation; however, ensure users can perform competently without referencing documentation as much as possible. Keep components decoupled","title":"Design Philosophy"},{"location":"reference/preprocess.html","text":"preprocess \u00b6 import \"github.com/HexmosTech/lama2/preprocess\" Package preprocess provides facilities to expand environment variables in `.l2` API files and return the contents Index \u00b6 func ExpandEnv(s string, vm interface{}) string func ExpandHeaders(block *gabs.Container, vm interface{}) func ExpandJSON(block *gabs.Container, vm interface{}) func ExpandURL(block *gabs.Container, vm interface{}) func GetL2EnvVariables(dir string) (map[string]map[string]interface{}, error) func GetLamaFileAsString(path string) (string, error) func LamaFile(inputFile string) (string, string) func LoadEnvFile(l2path string) func LoadEnvironments(dir string) func ProcessVarsInBlock(block *gabs.Container, vm interface{}) func SearchL2ConfigEnv(dir string) (string, error) func ExpandEnv \u00b6 func ExpandEnv ( s string , vm interface {}) string ExpandEnv replaces ${var} or $var in the string according to the values of the current environment variables. References to undefined variables are replaced by the empty string. func ExpandHeaders \u00b6 func ExpandHeaders ( block * gabs . Container , vm interface {}) func ExpandJSON \u00b6 func ExpandJSON ( block * gabs . Container , vm interface {}) func ExpandURL \u00b6 func ExpandURL ( block * gabs . Container , vm interface {}) func GetL2EnvVariables \u00b6 func GetL2EnvVariables ( dir string ) ( map [ string ] map [ string ] interface {}, error ) func GetLamaFileAsString \u00b6 func GetLamaFileAsString ( path string ) ( string , error ) func LamaFile \u00b6 func LamaFile ( inputFile string ) ( string , string ) LamaFile takes in a path to an API file. It moves into the API file directory, reads the API contents, loads the `l2.env` file if available, and finally substitutes environment vars in the API contents Once done, it reverts back to the original directory, and returns the processed l2 file. func LoadEnvFile \u00b6 func LoadEnvFile ( l2path string ) func LoadEnvironments \u00b6 func LoadEnvironments ( dir string ) func ProcessVarsInBlock \u00b6 func ProcessVarsInBlock ( block * gabs . Container , vm interface {}) func SearchL2ConfigEnv \u00b6 func SearchL2ConfigEnv ( dir string ) ( string , error ) Generated by gomarkdoc","title":"Preprocess"},{"location":"reference/preprocess.html#preprocess","text":"import \"github.com/HexmosTech/lama2/preprocess\" Package preprocess provides facilities to expand environment variables in `.l2` API files and return the contents","title":"preprocess"},{"location":"reference/preprocess.html#index","text":"func ExpandEnv(s string, vm interface{}) string func ExpandHeaders(block *gabs.Container, vm interface{}) func ExpandJSON(block *gabs.Container, vm interface{}) func ExpandURL(block *gabs.Container, vm interface{}) func GetL2EnvVariables(dir string) (map[string]map[string]interface{}, error) func GetLamaFileAsString(path string) (string, error) func LamaFile(inputFile string) (string, string) func LoadEnvFile(l2path string) func LoadEnvironments(dir string) func ProcessVarsInBlock(block *gabs.Container, vm interface{}) func SearchL2ConfigEnv(dir string) (string, error)","title":"Index"},{"location":"reference/preprocess.html#func-expandenv","text":"func ExpandEnv ( s string , vm interface {}) string ExpandEnv replaces ${var} or $var in the string according to the values of the current environment variables. References to undefined variables are replaced by the empty string.","title":"func ExpandEnv"},{"location":"reference/preprocess.html#func-expandheaders","text":"func ExpandHeaders ( block * gabs . Container , vm interface {})","title":"func ExpandHeaders"},{"location":"reference/preprocess.html#func-expandjson","text":"func ExpandJSON ( block * gabs . Container , vm interface {})","title":"func ExpandJSON"},{"location":"reference/preprocess.html#func-expandurl","text":"func ExpandURL ( block * gabs . Container , vm interface {})","title":"func ExpandURL"},{"location":"reference/preprocess.html#func-getl2envvariables","text":"func GetL2EnvVariables ( dir string ) ( map [ string ] map [ string ] interface {}, error )","title":"func GetL2EnvVariables"},{"location":"reference/preprocess.html#func-getlamafileasstring","text":"func GetLamaFileAsString ( path string ) ( string , error )","title":"func GetLamaFileAsString"},{"location":"reference/preprocess.html#func-lamafile","text":"func LamaFile ( inputFile string ) ( string , string ) LamaFile takes in a path to an API file. It moves into the API file directory, reads the API contents, loads the `l2.env` file if available, and finally substitutes environment vars in the API contents Once done, it reverts back to the original directory, and returns the processed l2 file.","title":"func LamaFile"},{"location":"reference/preprocess.html#func-loadenvfile","text":"func LoadEnvFile ( l2path string )","title":"func LoadEnvFile"},{"location":"reference/preprocess.html#func-loadenvironments","text":"func LoadEnvironments ( dir string )","title":"func LoadEnvironments"},{"location":"reference/preprocess.html#func-processvarsinblock","text":"func ProcessVarsInBlock ( block * gabs . Container , vm interface {})","title":"func ProcessVarsInBlock"},{"location":"reference/preprocess.html#func-searchl2configenv","text":"func SearchL2ConfigEnv ( dir string ) ( string , error ) Generated by gomarkdoc","title":"func SearchL2ConfigEnv"},{"location":"reference/utils.html","text":"utils \u00b6 import \"github.com/HexmosTech/lama2/utils\" Package `utils` provides useful functions for simplifying various programming tasks Index \u00b6 Constants func ContainsRune(s []rune, e rune) bool func ContainsString(s []string, e string) bool func ContainsStringPartial(s []string, e string) bool func GetFilePathComponents(name string) (string, string, string) func PrettyPrint(i interface{}) string func RemoveUnquotedMarker(content string) string func RemoveUnquotedValueMarker(content string) string func SetJSON(parentObj *gabs.Container, childObj *gabs.Container, key string) *gabs.Container func UnicodeCategory(r rune) string func UpdateSelf() type ParseError func NewParseError(pos int, line int, msg string, args []string) *ParseError func (p ParseError) Error() string Constants \u00b6 The following string fragment is used to mark unquoted variables within a JSON body in the lama2 file. For example, Lama2 parser will mark an unquoted variable `hello` as: \"\\<626f4c60-${hello}>\" The above string is actually representative of the user intent: ${hello} Note the lack of quotes around the variable above. This hack is needed to work around Gabs, which is unaware of variables required in the Lama2 system const UNQUOTED_VAR_MARKER = \"626f4c60\" func ContainsRune \u00b6 func ContainsRune ( s [] rune , e rune ) bool ContainsRune searches for rune `e` in a slice of runes `s`; returns a boolean func ContainsString \u00b6 func ContainsString ( s [] string , e string ) bool ContainsString searches for string `e` in a slice of strings `s`; returns a boolean func ContainsStringPartial \u00b6 func ContainsStringPartial ( s [] string , e string ) bool ContainsStringPartial substring-searches for string `e` in a slice of strings `s`; returns a boolean func GetFilePathComponents \u00b6 func GetFilePathComponents ( name string ) ( string , string , string ) GetFilePathComponent returns absolute path, directory, and filename given a filepath func PrettyPrint \u00b6 func PrettyPrint ( i interface {}) string PrettyPrint takes in a generic interface{} objects and uses standard JSON capabilities to try to print with indentation func RemoveUnquotedMarker \u00b6 func RemoveUnquotedMarker ( content string ) string func RemoveUnquotedValueMarker \u00b6 func RemoveUnquotedValueMarker ( content string ) string func SetJSON \u00b6 func SetJSON ( parentObj * gabs . Container , childObj * gabs . Container , key string ) * gabs . Container SetJSON is a helper function to work with the `gabs` library, which in turn is an API on top of the standard JSON library The function helps us create `parentObj.key = childObj` through using the `Merge` primitive available in `gabs` func UnicodeCategory \u00b6 func UnicodeCategory ( r rune ) string UnicodeCategory returns the Unicode Character Category of the given rune. func UpdateSelf \u00b6 func UpdateSelf () UpdateSelf downloads the installation script from the official repository, and executes it to update the l2 binary to the latest version type ParseError \u00b6 type ParseError struct { Pos int LineNum int // contains filtered or unexported fields } func NewParseError \u00b6 func NewParseError ( pos int , line int , msg string , args [] string ) * ParseError func (ParseError) Error \u00b6 func ( p ParseError ) Error () string Generated by gomarkdoc","title":"Utils"},{"location":"reference/utils.html#utils","text":"import \"github.com/HexmosTech/lama2/utils\" Package `utils` provides useful functions for simplifying various programming tasks","title":"utils"},{"location":"reference/utils.html#index","text":"Constants func ContainsRune(s []rune, e rune) bool func ContainsString(s []string, e string) bool func ContainsStringPartial(s []string, e string) bool func GetFilePathComponents(name string) (string, string, string) func PrettyPrint(i interface{}) string func RemoveUnquotedMarker(content string) string func RemoveUnquotedValueMarker(content string) string func SetJSON(parentObj *gabs.Container, childObj *gabs.Container, key string) *gabs.Container func UnicodeCategory(r rune) string func UpdateSelf() type ParseError func NewParseError(pos int, line int, msg string, args []string) *ParseError func (p ParseError) Error() string","title":"Index"},{"location":"reference/utils.html#constants","text":"The following string fragment is used to mark unquoted variables within a JSON body in the lama2 file. For example, Lama2 parser will mark an unquoted variable `hello` as: \"\\<626f4c60-${hello}>\" The above string is actually representative of the user intent: ${hello} Note the lack of quotes around the variable above. This hack is needed to work around Gabs, which is unaware of variables required in the Lama2 system const UNQUOTED_VAR_MARKER = \"626f4c60\"","title":"Constants"},{"location":"reference/utils.html#func-containsrune","text":"func ContainsRune ( s [] rune , e rune ) bool ContainsRune searches for rune `e` in a slice of runes `s`; returns a boolean","title":"func ContainsRune"},{"location":"reference/utils.html#func-containsstring","text":"func ContainsString ( s [] string , e string ) bool ContainsString searches for string `e` in a slice of strings `s`; returns a boolean","title":"func ContainsString"},{"location":"reference/utils.html#func-containsstringpartial","text":"func ContainsStringPartial ( s [] string , e string ) bool ContainsStringPartial substring-searches for string `e` in a slice of strings `s`; returns a boolean","title":"func ContainsStringPartial"},{"location":"reference/utils.html#func-getfilepathcomponents","text":"func GetFilePathComponents ( name string ) ( string , string , string ) GetFilePathComponent returns absolute path, directory, and filename given a filepath","title":"func GetFilePathComponents"},{"location":"reference/utils.html#func-prettyprint","text":"func PrettyPrint ( i interface {}) string PrettyPrint takes in a generic interface{} objects and uses standard JSON capabilities to try to print with indentation","title":"func PrettyPrint"},{"location":"reference/utils.html#func-removeunquotedmarker","text":"func RemoveUnquotedMarker ( content string ) string","title":"func RemoveUnquotedMarker"},{"location":"reference/utils.html#func-removeunquotedvaluemarker","text":"func RemoveUnquotedValueMarker ( content string ) string","title":"func RemoveUnquotedValueMarker"},{"location":"reference/utils.html#func-setjson","text":"func SetJSON ( parentObj * gabs . Container , childObj * gabs . Container , key string ) * gabs . Container SetJSON is a helper function to work with the `gabs` library, which in turn is an API on top of the standard JSON library The function helps us create `parentObj.key = childObj` through using the `Merge` primitive available in `gabs`","title":"func SetJSON"},{"location":"reference/utils.html#func-unicodecategory","text":"func UnicodeCategory ( r rune ) string UnicodeCategory returns the Unicode Character Category of the given rune.","title":"func UnicodeCategory"},{"location":"reference/utils.html#func-updateself","text":"func UpdateSelf () UpdateSelf downloads the installation script from the official repository, and executes it to update the l2 binary to the latest version","title":"func UpdateSelf"},{"location":"reference/utils.html#type-parseerror","text":"type ParseError struct { Pos int LineNum int // contains filtered or unexported fields }","title":"type ParseError"},{"location":"reference/utils.html#func-newparseerror","text":"func NewParseError ( pos int , line int , msg string , args [] string ) * ParseError","title":"func NewParseError"},{"location":"reference/utils.html#func-parseerror-error","text":"func ( p ParseError ) Error () string Generated by gomarkdoc","title":"func (ParseError) Error"},{"location":"tutorials/codegen.html","text":"Lama2 is capable of converting .l2 files into functional code of your preferred language and library. For example, to generate code in python requests , use the following command: l2 -c python.requests myfile.l2 To pick the default library in a language, omit the library as follows: l2 -c python myfile.l2 Languages and libraries supported \u00b6 shell curl (default) httpie wget powershell webrequest (default) restmethod ocaml cohttp (default) csharp restsharp (default) httpclient r httr (default) php curl (default) guzzle http1 http2 ruby native (default) clojure clj_http (default) java unirest (default) asynchttp nethttp okhttp http 1.1 (default) http1.1 swift nsurlsession (default) node native (default) request unirest axios fetch c libcurl (default) go native (default) python python3 (default) requests kotlin okhttp (default) javascript xhr (default) axios fetch jquery objc nsurlsession (default)","title":"Code Generation"},{"location":"tutorials/codegen.html#languages-and-libraries-supported","text":"shell curl (default) httpie wget powershell webrequest (default) restmethod ocaml cohttp (default) csharp restsharp (default) httpclient r httr (default) php curl (default) guzzle http1 http2 ruby native (default) clojure clj_http (default) java unirest (default) asynchttp nethttp okhttp http 1.1 (default) http1.1 swift nsurlsession (default) node native (default) request unirest axios fetch c libcurl (default) go native (default) python python3 (default) requests kotlin okhttp (default) javascript xhr (default) axios fetch jquery objc nsurlsession (default)","title":"Languages and libraries supported"},{"location":"tutorials/collaboration.html","text":"At Hexmos , we use a git repository called APIHub for collaborating on API files. Here is a description of how the workflow functions for us: The new engineer clones APIHub repository If necessary, create a folder for organizing the new API (ex: my_new_service ) Start defining *.l2 files for each service specific API. Use l2 file.l2 to test the newly defined APIs (or execute from VSCode). Push the API files once ready into APIHub repo On the rare merge conflict, the engineer uses standard git conflict resolution mechanisms","title":"Collaboration"},{"location":"tutorials/editor.html","text":"Programmatic ally Executing an l2 file \u00b6 Useful Options \u00b6 The l2 command provides some helpful options for extension developers. The options are: --nocolor or -n disables colored output in httpie-go (in CLI); --output=<target.json or -o writes a structured JSON output to the target file (without colors). The following is the content structure: { \"logs\" : ... , \"headers\" : ... , \"body\" : ... } logs : String value. Contains ASCII-color-coded log output. Control the logging level through -v option headers : A string consisting of HTTP header: Value pairs separated by newline. body : A string containing the HTTP response. Usually a JSON or HTML response. Note Right now, all the three values in the JSON are strings. In the future, we may transform the values further to provide a more parse-friendly structure. The Commands \u00b6 Execute current file \u00b6 Combining the options -n and -o , we get: l2 -n -o /tmp/lama2.json my_api.l2 The command mentioned above disables HTTPie colors, writes the whole transaction to a structured JSON, while also printing details into stdout . The extension author can simply read the file, and display the contents to users appropriately. For an example, see Lama2 for VSCode (also see Marketplace page ). LSP Language services for L2 extension \u00b6 Initilize server \u00b6 Overview: The server initialization is the first step to establish communication with the LSP. This process involves starting a server that listens for incoming JSON RPC 2.0 requests. Steps: 1. Starting the Server: \u00b6 Launch the server using the following command: l2 --lsp Separate Process for Persistence: Typically, language servers run as a separate process to ensure they remain active and responsive. Our implementation follows this best practice, ensuring the server remains available for the duration of your coding session. Interaction via stdin/stdout: Communication with our server is facilitated through stdin (standard input) and stdout (standard output). This approach is in line with the Microsoft Language Server Protocol guidelines, ensuring compatibility and seamless integration with various editors and IDEs. Reference Implementation: For a deeper dive into how we've implemented the server initialization in our extension, check out this section of our codebase. This will provide you with a hands-on understanding of our approach and might serve as a valuable reference if you're looking to extend or adapt the functionality. See how Lama2Code initializes the server 2. Making a Request: \u00b6 Send a JSON RPC 2.0 request to the server's stdin. Here's an example of an initialization request: { \"jsonrpc\" : \"2.0\" , \"id\" : 1 , \"method\" : \"initialize\" , \"params\" : { \"processId\" : null , \"clientInfo\" : { \"name\" : \"MyEditor\" , \"version\" : \"1.0.0\" }, \"rootUri\" : \"file:///path/to/workspace\" } } See how Lama2Code makes a request 3. Receiving a Response: \u00b6 After processing, the server will send a response back. This response can be read from the server's stdout. Environment variable autocompletion \u00b6 Overview: The LSP server offers a custom method, suggest/environmentVariables , which provides autocompletion suggestions for environment variables. This method combines data from both l2.env and l2config.env to present a unified JSON representation of the environment variables. Steps: 1. Making a Request \u00b6 Here's an example request to obtain all environment variables: { \"jsonrpc\" : \"2.0\" , \"id\" : 2 , \"method\" : \"suggest/environmentVariables\" , \"params\" : { \"textDocument\" : { \"uri\" : \"file:///home/Lama2/elfparser/ElfTestSuite/root_variable_override/api/y_0020_root_override.l2\" }, \"position\" : { \"line\" : 1 , \"character\" : 2 }, \"searchQuery\" : \"\" } } Checkout how Lama2Code requests for environment variables 2. Receiving a Response: \u00b6 The server will respond with a JSON object containing the environment variables. Extension authors can then read this response from the server's stdout and present the variables to users in a suitable format. { \"id\" : 2 , \"result\" : { \"AHOST\" : { \"src\" : \"l2env\" , \"val\" : \"http://127.0.0.1:8000\" }, \"BHOST\" : { \"src\" : \"l2configenv\" , \"val\" : \"https://httpbin.org\" } }, \"jsonrpc\" : \"2.0\" } Filtering Results: To narrow down the environment variables based on a specific prefix, you can modify the searchQuery parameter in the previous request. This doesn't represent a new request but rather showcases how to adjust the existing one for more specific results. For instance, to retrieve variables relevant to \"BH\", adjust the searchQuery parameter as follows: { \"searchQuery\" : \"BH\" } This will filter the results to only include environment variables that contain \"BH\". When l2.env is present When both l2.env and l2condig.env is present Go to Example Syntax Highlighting \u00b6 The VSCode plugin implements a rudimentary syntax highlighting for .l2 files. We use Iro for syntax grammar generation. Find more details if interested.","title":"IDE/Editor Support"},{"location":"tutorials/editor.html#programmatic-ally-executing-an-l2-file","text":"","title":"Programmatic ally Executing an l2 file"},{"location":"tutorials/editor.html#useful-options","text":"The l2 command provides some helpful options for extension developers. The options are: --nocolor or -n disables colored output in httpie-go (in CLI); --output=<target.json or -o writes a structured JSON output to the target file (without colors). The following is the content structure: { \"logs\" : ... , \"headers\" : ... , \"body\" : ... } logs : String value. Contains ASCII-color-coded log output. Control the logging level through -v option headers : A string consisting of HTTP header: Value pairs separated by newline. body : A string containing the HTTP response. Usually a JSON or HTML response. Note Right now, all the three values in the JSON are strings. In the future, we may transform the values further to provide a more parse-friendly structure.","title":"Useful Options"},{"location":"tutorials/editor.html#the-commands","text":"","title":"The Commands"},{"location":"tutorials/editor.html#execute-current-file","text":"Combining the options -n and -o , we get: l2 -n -o /tmp/lama2.json my_api.l2 The command mentioned above disables HTTPie colors, writes the whole transaction to a structured JSON, while also printing details into stdout . The extension author can simply read the file, and display the contents to users appropriately. For an example, see Lama2 for VSCode (also see Marketplace page ).","title":"Execute current file"},{"location":"tutorials/editor.html#lsp-language-services-for-l2-extension","text":"","title":"LSP Language services for L2 extension"},{"location":"tutorials/editor.html#initilize-server","text":"Overview: The server initialization is the first step to establish communication with the LSP. This process involves starting a server that listens for incoming JSON RPC 2.0 requests. Steps:","title":"Initilize server"},{"location":"tutorials/editor.html#1-starting-the-server","text":"Launch the server using the following command: l2 --lsp Separate Process for Persistence: Typically, language servers run as a separate process to ensure they remain active and responsive. Our implementation follows this best practice, ensuring the server remains available for the duration of your coding session. Interaction via stdin/stdout: Communication with our server is facilitated through stdin (standard input) and stdout (standard output). This approach is in line with the Microsoft Language Server Protocol guidelines, ensuring compatibility and seamless integration with various editors and IDEs. Reference Implementation: For a deeper dive into how we've implemented the server initialization in our extension, check out this section of our codebase. This will provide you with a hands-on understanding of our approach and might serve as a valuable reference if you're looking to extend or adapt the functionality. See how Lama2Code initializes the server","title":"1. Starting the Server:"},{"location":"tutorials/editor.html#2-making-a-request","text":"Send a JSON RPC 2.0 request to the server's stdin. Here's an example of an initialization request: { \"jsonrpc\" : \"2.0\" , \"id\" : 1 , \"method\" : \"initialize\" , \"params\" : { \"processId\" : null , \"clientInfo\" : { \"name\" : \"MyEditor\" , \"version\" : \"1.0.0\" }, \"rootUri\" : \"file:///path/to/workspace\" } } See how Lama2Code makes a request","title":"2. Making a Request:"},{"location":"tutorials/editor.html#3-receiving-a-response","text":"After processing, the server will send a response back. This response can be read from the server's stdout.","title":"3. Receiving a Response:"},{"location":"tutorials/editor.html#environment-variable-autocompletion","text":"Overview: The LSP server offers a custom method, suggest/environmentVariables , which provides autocompletion suggestions for environment variables. This method combines data from both l2.env and l2config.env to present a unified JSON representation of the environment variables. Steps:","title":"Environment variable autocompletion"},{"location":"tutorials/editor.html#1-making-a-request","text":"Here's an example request to obtain all environment variables: { \"jsonrpc\" : \"2.0\" , \"id\" : 2 , \"method\" : \"suggest/environmentVariables\" , \"params\" : { \"textDocument\" : { \"uri\" : \"file:///home/Lama2/elfparser/ElfTestSuite/root_variable_override/api/y_0020_root_override.l2\" }, \"position\" : { \"line\" : 1 , \"character\" : 2 }, \"searchQuery\" : \"\" } } Checkout how Lama2Code requests for environment variables","title":"1. Making a Request"},{"location":"tutorials/editor.html#2-receiving-a-response","text":"The server will respond with a JSON object containing the environment variables. Extension authors can then read this response from the server's stdout and present the variables to users in a suitable format. { \"id\" : 2 , \"result\" : { \"AHOST\" : { \"src\" : \"l2env\" , \"val\" : \"http://127.0.0.1:8000\" }, \"BHOST\" : { \"src\" : \"l2configenv\" , \"val\" : \"https://httpbin.org\" } }, \"jsonrpc\" : \"2.0\" } Filtering Results: To narrow down the environment variables based on a specific prefix, you can modify the searchQuery parameter in the previous request. This doesn't represent a new request but rather showcases how to adjust the existing one for more specific results. For instance, to retrieve variables relevant to \"BH\", adjust the searchQuery parameter as follows: { \"searchQuery\" : \"BH\" } This will filter the results to only include environment variables that contain \"BH\". When l2.env is present When both l2.env and l2condig.env is present Go to Example","title":"2. Receiving a Response:"},{"location":"tutorials/editor.html#syntax-highlighting","text":"The VSCode plugin implements a rudimentary syntax highlighting for .l2 files. We use Iro for syntax grammar generation. Find more details if interested.","title":"Syntax Highlighting"},{"location":"tutorials/examples.html","text":"Examples \u00b6 The following examples provide a sampling of the various types of requests Lama2 handles presently. Execute each file as: l2 <file_name>.l2 You can also clone the repo and open it up in VSCode, install the Lama2 extension and fire requests from there. GET request \u00b6 GET https://httpbin.org/get --- _METADATA = {\"sample_response\":{ \"args\": {}, \"headers\": { \"Accept\": \"*/*\", \"Accept-Encoding\": \"gzip, deflate\", \"Host\": \"httpbin.org\", \"User-Agent\": \"python-requests/2.25.1\", \"X-Amzn-Trace-Id\": \"Root=1-6686c611-62649d393aae96de5f4afcbf\" }, \"origin\": \"20.235.244.147\", \"url\": \"https://httpbin.org/get\" }, \"api_name\":\"GET Request\", \"api_url\":\"https://httpbin.org/ip\", \"api_description\": \"Does a request to get the IP Address\" } Get Source File JSON POST request \u00b6 One can dump the JSON body at the end of an .l2 file to create a POST request: POST https://httpbin.org/post { \"a\": \"b\", \"c\": \"d\" } --- _METADATA={ \"sample_response\":{ \"args\": {}, \"data\": \"{\\\"a\\\":\\\"b\\\",\\\"c\\\":\\\"d\\\"}\", \"files\": {}, \"form\": {}, \"headers\": { \"Accept\": \"*/*\", \"Accept-Encoding\": \"gzip, deflate\", \"Content-Length\": \"17\", \"Content-Type\": \"application/json\", \"Host\": \"httpbin.org\", \"User-Agent\": \"python-requests/2.25.1\", \"X-Amzn-Trace-Id\": \"Root=1-6686c6c4-43e22f6539f1dae9070b962b\" }, \"json\": { \"a\": \"b\", \"c\": \"d\" }, \"origin\": \"20.235.244.147\", \"url\": \"https://httpbin.org/post\" }, \"api_name\" : \"POST Request\" } Get Source File JSON POST in VarJSON format \u00b6 Make a POST request with JSON body specified as key=value . Lama2 converts the input into a corresponding JSON value {\"a\": \"b\", \"c\": \"d\"} . We call the key=value format VarJSON . This example produces an effect identical to the previous one POST https://httpbin.org/post a=b c=d --- _METADATA={ \"api_name\":\"POST Request in VarJSON\", \"sample_response\":{ \"args\": {}, \"data\": \"{\\\"a\\\":\\\"b\\\",\\\"c\\\":\\\"d\\\"}\", \"files\": {}, \"form\": {}, \"headers\": { \"Accept\": \"*/*\", \"Accept-Encoding\": \"gzip, deflate\", \"Content-Length\": \"17\", \"Content-Type\": \"application/json\", \"Host\": \"httpbin.org\", \"User-Agent\": \"python-requests/2.25.1\", \"X-Amzn-Trace-Id\": \"Root=1-6686c721-0e9da41a16bc944d5fabe460\" }, \"json\": { \"a\": \"b\", \"c\": \"d\" }, \"origin\": \"20.235.244.147\", \"url\": \"https://httpbin.org/post\" } } Get Source File Comments \u00b6 One can start a comment anywhere in the file with the # character. # Pound symbol signifies a comment POST https://httpbin.org/post a=b # Comments may start at the end of lines as well c=d # Comments work even after the payload --- _METADATA={ \"api_name\":\"Request with comments\", \"sample_response\":{ \"args\": {}, \"data\": \"{\\\"a\\\":\\\"b\\\",\\\"c\\\":\\\"d\\\"}\", \"files\": {}, \"form\": {}, \"headers\": { \"Accept\": \"*/*\", \"Accept-Encoding\": \"gzip, deflate\", \"Content-Length\": \"17\", \"Content-Type\": \"application/json\", \"Host\": \"httpbin.org\", \"User-Agent\": \"python-requests/2.25.1\", \"X-Amzn-Trace-Id\": \"Root=1-6686c73a-1c05768a182e50a86b161667\" }, \"json\": { \"a\": \"b\", \"c\": \"d\" }, \"origin\": \"20.235.244.147\", \"url\": \"https://httpbin.org/post\" } } Get Source File Environment Variables: Switch base URL \u00b6 Case 1: l2.env adjacent to an API file \u00b6 For any given .l2 file, one can place an l2.env file to store relevant variables. These variables will be available to be used within the API file project_folder/api/l2.env export AHOST=\"http://127.0.0.1:8000\" project_folder/api/get_users.l2 GET ${AHOST}/users --- _METADATA={ \"api_name\": \"Environment Variables\" } Get Source File Case 2: Root variables \u00b6 In Lama2, you can have a large number of API files stored in a hierarchical folder configuration. The root of such a project can be signified through l2config.env : Within such a structure, you can have an API file anywhere, which can use variables defined in the root variables: project_folder/l2config.env export AHOST=\"https://httpbin.org\" export BHOST=\"https://google.com\" project_folder/api/get_users.l2 GET ${AHOST}/users --- _METADATA={ \"api_name\": \"Environment Variables\" } Get Source File Case 3: Override Root variable with local variable \u00b6 In this structure, if a variable is declared in both l2config.env and l2.env, the value from l2.env takes precedence. project_folder/l2config.env export AHOST=`echo NO URL` export BHOST=\"https://httpbin.org\" project_folder/api/l2.env export AHOST=\"http://127.0.0.1:8000\" project_folder/api/get_users.l2 GET ${AHOST}/users --- _METADATA={ \"api_name\": \"Environment Variables\" } Get Source File Headers \u00b6 Use key:value format to specify headers. Specify strings for key/value in three ways: Double quoted ( \"hello\" ) Single quoted ( 'hello' ) Unquoted ( hello ) POST https://httpbin.org/post # HEADERS X-Parse-Application-Id:'helloworld' X-Parse-REST-API-Key:\"byeworld\" # DATA a=\"b\" # double-quoted string 'c'=d # single-quoted & unquoted strings --- _METADATA={ \"api_name\":\"Header Example 1\", \"sample_response\":{ \"args\": {}, \"data\": \"{\\\"a\\\":\\\"b\\\",\\\"c\\\":\\\"d\\\"}\", \"files\": {}, \"form\": {}, \"headers\": { \"Accept\": \"*/*\", \"Accept-Encoding\": \"gzip, deflate\", \"Content-Length\": \"17\", \"Content-Type\": \"application/json\", \"Host\": \"httpbin.org\", \"User-Agent\": \"python-requests/2.25.1\", \"X-Amzn-Trace-Id\": \"Root=1-6686c782-2fd42fdd70a089580fe2c166\" }, \"json\": { \"a\": \"b\", \"c\": \"d\" }, \"origin\": \"20.235.244.147\", \"url\": \"https://httpbin.org/post\" } } Get Source File Note The data section may appear before headers as well (see below) POST https://httpbin.org/post # DATA a=\"b\" # double-quoted string 'c'=d # single-quoted & unquoted strings # HEADERS X-Parse-Application-Id:'helloworld' X-Parse-REST-API-Key:\"byeworld\" --- _METADATA={ \"api_name\":\"Header Example 2\", \"sample_response\":{ \"args\": {}, \"data\": \"{\\\"a\\\":\\\"b\\\",\\\"c\\\":\\\"d\\\"}\", \"files\": {}, \"form\": {}, \"headers\": { \"Accept\": \"*/*\", \"Accept-Encoding\": \"gzip, deflate\", \"Content-Length\": \"17\", \"Content-Type\": \"application/json\", \"Host\": \"httpbin.org\", \"User-Agent\": \"python-requests/2.25.1\", \"X-Amzn-Trace-Id\": \"Root=1-6686c7f1-7bfd09a2000d33bc12cbf7c1\" }, \"json\": { \"a\": \"b\", \"c\": \"d\" }, \"origin\": \"20.235.244.147\", \"url\": \"https://httpbin.org/post\" }, \"json\": { \"a\": \"b\", \"c\": \"d\" }, \"origin\": \"20.235.244.147\", \"url\": \"https://httpbin.org/post\" } Send cookies in header \u00b6 Headers represent cookies in Lama2 . Just specify cookie key value pairs separated by = within the header value as shown. POST https://httpbin.org/post # HEADERS Cookie:\"sessionid=foo;another-cookie=bar\" # DATA hello=world --- _METADATA={ \"api_name\":\"Cookie Request\", \"sample_response\" : { \"args\": {}, \"data\": \"{\\\"hello\\\":\\\"world\\\"}\", \"files\": {}, \"form\": {}, \"headers\": { \"Accept\": \"*/*\", \"Accept-Encoding\": \"gzip, deflate\", \"Content-Length\": \"17\", \"Content-Type\": \"application/json\", \"Host\": \"httpbin.org\", \"User-Agent\": \"python-requests/2.25.1\", \"X-Amzn-Trace-Id\": \"Root=1-6686c850-33bc68696295ac947eb27420\" }, \"json\": { \"hello\": \"world\" }, \"origin\": \"20.235.244.147\", \"url\": \"https://httpbin.org/post\" } } Get Source File Fill forms & attach files with MULTIPART \u00b6 Use the MULTIPART keyword after the HTTP verb to enable forms and file attachments. The data section may contain any number of form inputs using the key=value syntax. Following the data section, one can specify any number of files in the form of <field_name>@<file_path> . The file path is relative to the API file. POST MULTIPART http://httpbin.org/post 'X-Parse-Application-Id':hello X-Parse-REST-API-Key:\"world\" # DATA first=second # FILES myfile@./image.jpeg --- _METADATA={ \"api_name\" : \"Multipart Request\" } Get Source Files Image as Base64 encoded JSON field \u00b6 We can embed images (or other files) as base64 strings in JSON using Lama2 . First, we define a PHOTO variable, loaded up with the results of the base64 command. l2.env export PHOTO=`base64 -w 0 image.jpeg` Next, we refer to the PHOTO variable in the API file. Pay special attention to the quoting mechanism \"'{PHOTO}'\" . Warning The quoting must look exactly as shown in the following template for the request to work correctly. base64_embed.l2 POST http://httpbin.org/post { \"imageb64_field\": \"'${PHOTO}'\", } --- _METADATA={ \"api_name\" : \"Image Example 2\" } Get Source Files Chain requests using Javascript \u00b6 In Lama2, we have alternating requestor and processor (JS) blocks, separated by --- . Each processor (JS) block has a special variable result , storing the response from previous requestor block. If possible, result is automatically stored as a JS object through JSON.parse() . Otherwise, result is stored as a regular string . url = \"http://google.com\" REMOTE_COORD = \"https://httpbin.org\" --- # stage 1 POST ${REMOTE_COORD}/anything { \"username\": \"admin\", \"password\": \"Password@123\", \"from\": \"${LOCAL_COORD}/anything\", \"url\": \"${url}\", \"Token\": \"MySuperSecretToken\" } --- // filtering, store in var console.log(\"@@Result\", result) TOKEN = result[\"json\"][\"Token\"] console.log(TOKEN) --- # stage 2 GET ${REMOTE_COORD}/bearer Authorization: 'Bearer ${TOKEN}' --- _METADATA={ \"api_name\" : \"Chain Request\" } Get Source Files","title":"Examples"},{"location":"tutorials/examples.html#examples","text":"The following examples provide a sampling of the various types of requests Lama2 handles presently. Execute each file as: l2 <file_name>.l2 You can also clone the repo and open it up in VSCode, install the Lama2 extension and fire requests from there.","title":"Examples"},{"location":"tutorials/examples.html#get-request","text":"GET https://httpbin.org/get --- _METADATA = {\"sample_response\":{ \"args\": {}, \"headers\": { \"Accept\": \"*/*\", \"Accept-Encoding\": \"gzip, deflate\", \"Host\": \"httpbin.org\", \"User-Agent\": \"python-requests/2.25.1\", \"X-Amzn-Trace-Id\": \"Root=1-6686c611-62649d393aae96de5f4afcbf\" }, \"origin\": \"20.235.244.147\", \"url\": \"https://httpbin.org/get\" }, \"api_name\":\"GET Request\", \"api_url\":\"https://httpbin.org/ip\", \"api_description\": \"Does a request to get the IP Address\" } Get Source File","title":"GET request"},{"location":"tutorials/examples.html#json-post-request","text":"One can dump the JSON body at the end of an .l2 file to create a POST request: POST https://httpbin.org/post { \"a\": \"b\", \"c\": \"d\" } --- _METADATA={ \"sample_response\":{ \"args\": {}, \"data\": \"{\\\"a\\\":\\\"b\\\",\\\"c\\\":\\\"d\\\"}\", \"files\": {}, \"form\": {}, \"headers\": { \"Accept\": \"*/*\", \"Accept-Encoding\": \"gzip, deflate\", \"Content-Length\": \"17\", \"Content-Type\": \"application/json\", \"Host\": \"httpbin.org\", \"User-Agent\": \"python-requests/2.25.1\", \"X-Amzn-Trace-Id\": \"Root=1-6686c6c4-43e22f6539f1dae9070b962b\" }, \"json\": { \"a\": \"b\", \"c\": \"d\" }, \"origin\": \"20.235.244.147\", \"url\": \"https://httpbin.org/post\" }, \"api_name\" : \"POST Request\" } Get Source File","title":"JSON POST request"},{"location":"tutorials/examples.html#json-post-in-varjson-format","text":"Make a POST request with JSON body specified as key=value . Lama2 converts the input into a corresponding JSON value {\"a\": \"b\", \"c\": \"d\"} . We call the key=value format VarJSON . This example produces an effect identical to the previous one POST https://httpbin.org/post a=b c=d --- _METADATA={ \"api_name\":\"POST Request in VarJSON\", \"sample_response\":{ \"args\": {}, \"data\": \"{\\\"a\\\":\\\"b\\\",\\\"c\\\":\\\"d\\\"}\", \"files\": {}, \"form\": {}, \"headers\": { \"Accept\": \"*/*\", \"Accept-Encoding\": \"gzip, deflate\", \"Content-Length\": \"17\", \"Content-Type\": \"application/json\", \"Host\": \"httpbin.org\", \"User-Agent\": \"python-requests/2.25.1\", \"X-Amzn-Trace-Id\": \"Root=1-6686c721-0e9da41a16bc944d5fabe460\" }, \"json\": { \"a\": \"b\", \"c\": \"d\" }, \"origin\": \"20.235.244.147\", \"url\": \"https://httpbin.org/post\" } } Get Source File","title":"JSON POST in VarJSON format"},{"location":"tutorials/examples.html#comments","text":"One can start a comment anywhere in the file with the # character. # Pound symbol signifies a comment POST https://httpbin.org/post a=b # Comments may start at the end of lines as well c=d # Comments work even after the payload --- _METADATA={ \"api_name\":\"Request with comments\", \"sample_response\":{ \"args\": {}, \"data\": \"{\\\"a\\\":\\\"b\\\",\\\"c\\\":\\\"d\\\"}\", \"files\": {}, \"form\": {}, \"headers\": { \"Accept\": \"*/*\", \"Accept-Encoding\": \"gzip, deflate\", \"Content-Length\": \"17\", \"Content-Type\": \"application/json\", \"Host\": \"httpbin.org\", \"User-Agent\": \"python-requests/2.25.1\", \"X-Amzn-Trace-Id\": \"Root=1-6686c73a-1c05768a182e50a86b161667\" }, \"json\": { \"a\": \"b\", \"c\": \"d\" }, \"origin\": \"20.235.244.147\", \"url\": \"https://httpbin.org/post\" } } Get Source File","title":"Comments"},{"location":"tutorials/examples.html#environment-variables-switch-base-url","text":"","title":"Environment Variables: Switch base URL"},{"location":"tutorials/examples.html#case-1-l2env-adjacent-to-an-api-file","text":"For any given .l2 file, one can place an l2.env file to store relevant variables. These variables will be available to be used within the API file project_folder/api/l2.env export AHOST=\"http://127.0.0.1:8000\" project_folder/api/get_users.l2 GET ${AHOST}/users --- _METADATA={ \"api_name\": \"Environment Variables\" } Get Source File","title":"Case 1: l2.env adjacent to an API file"},{"location":"tutorials/examples.html#case-2-root-variables","text":"In Lama2, you can have a large number of API files stored in a hierarchical folder configuration. The root of such a project can be signified through l2config.env : Within such a structure, you can have an API file anywhere, which can use variables defined in the root variables: project_folder/l2config.env export AHOST=\"https://httpbin.org\" export BHOST=\"https://google.com\" project_folder/api/get_users.l2 GET ${AHOST}/users --- _METADATA={ \"api_name\": \"Environment Variables\" } Get Source File","title":"Case 2: Root variables"},{"location":"tutorials/examples.html#case-3-override-root-variable-with-local-variable","text":"In this structure, if a variable is declared in both l2config.env and l2.env, the value from l2.env takes precedence. project_folder/l2config.env export AHOST=`echo NO URL` export BHOST=\"https://httpbin.org\" project_folder/api/l2.env export AHOST=\"http://127.0.0.1:8000\" project_folder/api/get_users.l2 GET ${AHOST}/users --- _METADATA={ \"api_name\": \"Environment Variables\" } Get Source File","title":"Case 3: Override Root variable with local variable"},{"location":"tutorials/examples.html#headers","text":"Use key:value format to specify headers. Specify strings for key/value in three ways: Double quoted ( \"hello\" ) Single quoted ( 'hello' ) Unquoted ( hello ) POST https://httpbin.org/post # HEADERS X-Parse-Application-Id:'helloworld' X-Parse-REST-API-Key:\"byeworld\" # DATA a=\"b\" # double-quoted string 'c'=d # single-quoted & unquoted strings --- _METADATA={ \"api_name\":\"Header Example 1\", \"sample_response\":{ \"args\": {}, \"data\": \"{\\\"a\\\":\\\"b\\\",\\\"c\\\":\\\"d\\\"}\", \"files\": {}, \"form\": {}, \"headers\": { \"Accept\": \"*/*\", \"Accept-Encoding\": \"gzip, deflate\", \"Content-Length\": \"17\", \"Content-Type\": \"application/json\", \"Host\": \"httpbin.org\", \"User-Agent\": \"python-requests/2.25.1\", \"X-Amzn-Trace-Id\": \"Root=1-6686c782-2fd42fdd70a089580fe2c166\" }, \"json\": { \"a\": \"b\", \"c\": \"d\" }, \"origin\": \"20.235.244.147\", \"url\": \"https://httpbin.org/post\" } } Get Source File Note The data section may appear before headers as well (see below) POST https://httpbin.org/post # DATA a=\"b\" # double-quoted string 'c'=d # single-quoted & unquoted strings # HEADERS X-Parse-Application-Id:'helloworld' X-Parse-REST-API-Key:\"byeworld\" --- _METADATA={ \"api_name\":\"Header Example 2\", \"sample_response\":{ \"args\": {}, \"data\": \"{\\\"a\\\":\\\"b\\\",\\\"c\\\":\\\"d\\\"}\", \"files\": {}, \"form\": {}, \"headers\": { \"Accept\": \"*/*\", \"Accept-Encoding\": \"gzip, deflate\", \"Content-Length\": \"17\", \"Content-Type\": \"application/json\", \"Host\": \"httpbin.org\", \"User-Agent\": \"python-requests/2.25.1\", \"X-Amzn-Trace-Id\": \"Root=1-6686c7f1-7bfd09a2000d33bc12cbf7c1\" }, \"json\": { \"a\": \"b\", \"c\": \"d\" }, \"origin\": \"20.235.244.147\", \"url\": \"https://httpbin.org/post\" }, \"json\": { \"a\": \"b\", \"c\": \"d\" }, \"origin\": \"20.235.244.147\", \"url\": \"https://httpbin.org/post\" }","title":"Headers"},{"location":"tutorials/examples.html#send-cookies-in-header","text":"Headers represent cookies in Lama2 . Just specify cookie key value pairs separated by = within the header value as shown. POST https://httpbin.org/post # HEADERS Cookie:\"sessionid=foo;another-cookie=bar\" # DATA hello=world --- _METADATA={ \"api_name\":\"Cookie Request\", \"sample_response\" : { \"args\": {}, \"data\": \"{\\\"hello\\\":\\\"world\\\"}\", \"files\": {}, \"form\": {}, \"headers\": { \"Accept\": \"*/*\", \"Accept-Encoding\": \"gzip, deflate\", \"Content-Length\": \"17\", \"Content-Type\": \"application/json\", \"Host\": \"httpbin.org\", \"User-Agent\": \"python-requests/2.25.1\", \"X-Amzn-Trace-Id\": \"Root=1-6686c850-33bc68696295ac947eb27420\" }, \"json\": { \"hello\": \"world\" }, \"origin\": \"20.235.244.147\", \"url\": \"https://httpbin.org/post\" } } Get Source File","title":"Send cookies in header"},{"location":"tutorials/examples.html#fill-forms-attach-files-with-multipart","text":"Use the MULTIPART keyword after the HTTP verb to enable forms and file attachments. The data section may contain any number of form inputs using the key=value syntax. Following the data section, one can specify any number of files in the form of <field_name>@<file_path> . The file path is relative to the API file. POST MULTIPART http://httpbin.org/post 'X-Parse-Application-Id':hello X-Parse-REST-API-Key:\"world\" # DATA first=second # FILES myfile@./image.jpeg --- _METADATA={ \"api_name\" : \"Multipart Request\" } Get Source Files","title":"Fill forms &amp; attach files with MULTIPART"},{"location":"tutorials/examples.html#image-as-base64-encoded-json-field","text":"We can embed images (or other files) as base64 strings in JSON using Lama2 . First, we define a PHOTO variable, loaded up with the results of the base64 command. l2.env export PHOTO=`base64 -w 0 image.jpeg` Next, we refer to the PHOTO variable in the API file. Pay special attention to the quoting mechanism \"'{PHOTO}'\" . Warning The quoting must look exactly as shown in the following template for the request to work correctly. base64_embed.l2 POST http://httpbin.org/post { \"imageb64_field\": \"'${PHOTO}'\", } --- _METADATA={ \"api_name\" : \"Image Example 2\" } Get Source Files","title":"Image as Base64 encoded JSON field"},{"location":"tutorials/examples.html#chain-requests-using-javascript","text":"In Lama2, we have alternating requestor and processor (JS) blocks, separated by --- . Each processor (JS) block has a special variable result , storing the response from previous requestor block. If possible, result is automatically stored as a JS object through JSON.parse() . Otherwise, result is stored as a regular string . url = \"http://google.com\" REMOTE_COORD = \"https://httpbin.org\" --- # stage 1 POST ${REMOTE_COORD}/anything { \"username\": \"admin\", \"password\": \"Password@123\", \"from\": \"${LOCAL_COORD}/anything\", \"url\": \"${url}\", \"Token\": \"MySuperSecretToken\" } --- // filtering, store in var console.log(\"@@Result\", result) TOKEN = result[\"json\"][\"Token\"] console.log(TOKEN) --- # stage 2 GET ${REMOTE_COORD}/bearer Authorization: 'Bearer ${TOKEN}' --- _METADATA={ \"api_name\" : \"Chain Request\" } Get Source Files","title":"Chain requests using Javascript"},{"location":"tutorials/installation.html","text":"Getting Started \u00b6 Installation/Update \u00b6 One-line install/update in Linux/MacOS \u00b6 To install/update Lama2 and its dependencies automatically, run the following: curl -s https://hexmos.com/lama2/install.sh | bash -s One-line install/update in Windows \u00b6 To install/update Lama2 and its dependencies automatically, run the following as Administrator : choco install lama2 --version=1.0.0 --force -y (Optional) Import your collections from Postman \u00b6 Follow guide to import your existing Postman collections into a Plain-Text Lama2 repository. Self update \u00b6 An easier way to update the binary to latest release is through: l2 -u Note Install the VSCode extension to launch requests from within your editor Manual install \u00b6 Step 1: Install HTTPie \u00b6 Lama2 depends on HTTPie for Terminal . Use their official instructions to get the http command functional in your local system. Step 2: Download & install Lama2 binary packages \u00b6 Head over to Lama2 releases . Check under the Assets head to find various packages. Download the relevant package for your operating system and CPU architecture. Once you have the package, run the following: tar --overwrite -xvzf <download>.tar.gz mv l2 /usr/local/bin Build from source \u00b6 Run make in the project root. You'll need to have the following tools in your PATH : go (v1.17+) golangcli-lint gofumpt Also, you'll need to install mkdocs the first time; for that run these: cd docs/Lama2 poetry install # get poetry from https://python-poetry.org/ Once make finishes, find the binary at ./build/l2 . Moreover, you can launch the documentation locally through make serve . Read makefile to find other useful helper commands. How to use \u00b6 From the terminal \u00b6 Type l2 into the terminal. You should get something like: Usage: l2 [OPTIONS] [LamaAPIFile] Application Options: -o, --output= Path to output JSON file to store logs, headers and result -v, --verbose Show verbose debug information -n, --nocolor Disable color in httpie output -e --env= Get a JSON of environment variables revelant to input arg -h, --help Usage help for Lama2 --version Print Lama2 binary version Help Options: -h, --help Show this help message From VS Code \u00b6 Find Lama2 for VSCode at the VSCode Marketplace . The extension requires the l2 command available (usually at /usr/local/bin/l2 for Linux/MacOS and C:\\ProgramData\\chocolatey\\bin for Windows). Once the extension is installed, open the command palette (ctrl + shift + p) and search for Execute current file to execute the file","title":"Installation"},{"location":"tutorials/installation.html#getting-started","text":"","title":"Getting Started"},{"location":"tutorials/installation.html#installationupdate","text":"","title":"Installation/Update"},{"location":"tutorials/installation.html#one-line-installupdate-in-linuxmacos","text":"To install/update Lama2 and its dependencies automatically, run the following: curl -s https://hexmos.com/lama2/install.sh | bash -s","title":"One-line install/update in Linux/MacOS"},{"location":"tutorials/installation.html#one-line-installupdate-in-windows","text":"To install/update Lama2 and its dependencies automatically, run the following as Administrator : choco install lama2 --version=1.0.0 --force -y","title":"One-line install/update in Windows"},{"location":"tutorials/installation.html#optional-import-your-collections-from-postman","text":"Follow guide to import your existing Postman collections into a Plain-Text Lama2 repository.","title":"(Optional) Import your collections from Postman"},{"location":"tutorials/installation.html#self-update","text":"An easier way to update the binary to latest release is through: l2 -u Note Install the VSCode extension to launch requests from within your editor","title":"Self update"},{"location":"tutorials/installation.html#manual-install","text":"","title":"Manual install"},{"location":"tutorials/installation.html#step-1-install-httpie","text":"Lama2 depends on HTTPie for Terminal . Use their official instructions to get the http command functional in your local system.","title":"Step 1: Install HTTPie"},{"location":"tutorials/installation.html#step-2-download-install-lama2-binary-packages","text":"Head over to Lama2 releases . Check under the Assets head to find various packages. Download the relevant package for your operating system and CPU architecture. Once you have the package, run the following: tar --overwrite -xvzf <download>.tar.gz mv l2 /usr/local/bin","title":"Step 2: Download &amp; install Lama2 binary packages"},{"location":"tutorials/installation.html#build-from-source","text":"Run make in the project root. You'll need to have the following tools in your PATH : go (v1.17+) golangcli-lint gofumpt Also, you'll need to install mkdocs the first time; for that run these: cd docs/Lama2 poetry install # get poetry from https://python-poetry.org/ Once make finishes, find the binary at ./build/l2 . Moreover, you can launch the documentation locally through make serve . Read makefile to find other useful helper commands.","title":"Build from source"},{"location":"tutorials/installation.html#how-to-use","text":"","title":"How to use"},{"location":"tutorials/installation.html#from-the-terminal","text":"Type l2 into the terminal. You should get something like: Usage: l2 [OPTIONS] [LamaAPIFile] Application Options: -o, --output= Path to output JSON file to store logs, headers and result -v, --verbose Show verbose debug information -n, --nocolor Disable color in httpie output -e --env= Get a JSON of environment variables revelant to input arg -h, --help Usage help for Lama2 --version Print Lama2 binary version Help Options: -h, --help Show this help message","title":"From the terminal"},{"location":"tutorials/installation.html#from-vs-code","text":"Find Lama2 for VSCode at the VSCode Marketplace . The extension requires the l2 command available (usually at /usr/local/bin/l2 for Linux/MacOS and C:\\ProgramData\\chocolatey\\bin for Windows). Once the extension is installed, open the command palette (ctrl + shift + p) and search for Execute current file to execute the file","title":"From VS Code"},{"location":"tutorials/misc.html","text":"Prettify JSON in l2 files \u00b6 Common experience suggests that l2 files tend to be messy when dealing with larger JSON files. So we have developed a targeted prettifier which fixes the JSON portions of an l2 file (if it exists) Usage: l2 -b targetFile.l2","title":"Misc"},{"location":"tutorials/misc.html#prettify-json-in-l2-files","text":"Common experience suggests that l2 files tend to be messy when dealing with larger JSON files. So we have developed a targeted prettifier which fixes the JSON portions of an l2 file (if it exists) Usage: l2 -b targetFile.l2","title":"Prettify JSON in l2 files"},{"location":"tutorials/postman.html","text":"Lama2 ships with a rudimentary converter from Postman to a Plain-Text Lama2 API repository. The converter presently is in an embryonic state and may merely produce approximate results. 1. Export from Postman \u00b6 1.1 Access Settings \u00b6 1.2 Data Export \u00b6 Warning Although postman offers more selective exporting (collection, folder, request levels), Lama2 presently supports only the whole-data export depicted above. The above step must produce a .json file. 2. Convert Postman .json dump into Lama2 API repo \u00b6 Run the following to convert the postman data dump into a Lama2 API structure. l2 -p postman_dump.json -l my_l2output_dir The command will prompt for an environment. Select the environment which you wish to export. Once you pick the option, Lama2 will produce the my_l2output_dir directory filled with the original organizational hierarchy and a bunch of .l2 and l2.env files.","title":"Import Postman"},{"location":"tutorials/postman.html#1-export-from-postman","text":"","title":"1. Export from Postman"},{"location":"tutorials/postman.html#11-access-settings","text":"","title":"1.1 Access Settings"},{"location":"tutorials/postman.html#12-data-export","text":"Warning Although postman offers more selective exporting (collection, folder, request levels), Lama2 presently supports only the whole-data export depicted above. The above step must produce a .json file.","title":"1.2 Data Export"},{"location":"tutorials/postman.html#2-convert-postman-json-dump-into-lama2-api-repo","text":"Run the following to convert the postman data dump into a Lama2 API structure. l2 -p postman_dump.json -l my_l2output_dir The command will prompt for an environment. Select the environment which you wish to export. Once you pick the option, Lama2 will produce the my_l2output_dir directory filled with the original organizational hierarchy and a bunch of .l2 and l2.env files.","title":"2. Convert Postman .json dump into Lama2 API repo"}]}