assistance-engine/docs/avap_language_github_docs/AVAP.md

735 lines
26 KiB
Markdown

# SECTION I: Architecture, Memory, and Fundamentals
This section sets the foundations of how AVAP manages service logic and data manipulation in memory. Unlike conventional interpreted languages, AVAP uses a **hybrid evaluation** engine that allows combining declarative commands with dynamic expressions.
---
## 1.1 Endpoint Registration (`registerEndpoint`)
The `registerEndpoint` command is the atomic unit of configuration. It acts as the bridge between the network (HTTP) and the code.
### Interface
`registerEndpoint(path, method, middleware, description, handler, output)`
### Parameter Specification
- **`path` (String):** Defines the URL path. It supports static routes and is prepared for future implementations of path parameters (variable segments).
- **`method` (String):** Specifies the allowed HTTP verb (`GET`, `POST`, `PUT`, `DELETE`). The server will automatically reject any request that does not match this method (Error 405).
- **`middleware` (List):** A list of functions that are executed sequentially before the `handler`. Ideal for JWT token validations or maintenance checks. If a middleware function fails, the flow stops before reaching the main code.
- **`description` (String):** Metadata for automatic documentation (Swagger/OpenAPI). It does not affect execution but is vital for the development lifecycle.
- **`handler` (Function):** The logical Entry Point. It is the name of the main function where the business logic resides.
- **`output` (Variable):** Defines the "master" variable that the engine will automatically return upon completion, unless additional results are specified via `addResult`.
---
## 1.2 Variable Assignment Engine (Dynamic Assignment)
AVAP allows a direct assignment syntax using the `=` symbol, which grants flexibility similar to languages like Python, but under strict context control.
### Internal Mechanics: The `eval` Process
When the interpreter finds an instruction of the type `variable = expression`, it activates a three-step process:
1. **Cleaning and Tokenization:** The engine identifies if the expression contains references to existing variables (using `$`), method calls, or literals.
2. **Expression Evaluation:** Operations are resolved in real-time. This allows:
- **Boolean Logic:** `is_valid = (age > 18 and has_permission == True)`.
- **Arithmetic:** `tax = subtotal * 0.21`.
- **String Formatting:** `query = "SELECT * FROM users WHERE id = %s" % recovered_id`.
3. **Object and Property Resolution:** Allows deep access to complex structures returned by database connectors or APIs: `client_email = user_list[0].profile.email`.
### Effect on Memory
Unlike `addVar`, dynamic assignment is capable of transforming the variable type on the fly (Mutable Type System). If a variable contained a number and is assigned a string after evaluation, the engine updates the variable metadata automatically.
---
## 1.3 State Initialization and References (`addVar`)
`addVar` is the fundamental command to define the global state of the script.
### Interface
`addVar(targetVarName, varValue)`
### Advanced Behavior
- **Intelligent Automatic Typing:** The engine inspects `varValue`. If it detects a numerical format (even if it comes as a string from configuration), it will internally convert it to `int` or `float`. It supports the use of commas and periods interchangeably, normalizing the value for mathematical operations.
- **The Reference Prefix `$`:** This is the dereferencing operator.
- `addVar(copy, $original)`: Indicates to the engine that it should not assign the string "$original", but look in the symbol table for the current value of the variable `original` and copy it.
- **Scope:** Variables created with `addVar` in the main body of the script are considered **Request Session Variables**, meaning they live during the entire execution lifecycle of that specific API call, but are isolated from other concurrent requests to guarantee data security (Thread-Safety).
| **Syntax** | **Usage** | **Description** |
| :--- | :--- | :--- |
| `name = "Juan"` | Direct Assignment | Creates a simple text string. |
| `total = $price * 1.10` | Dynamic Evaluation | Uses the value of `price` for a calculation and saves the result. |
| `addVar(status, 200)` | Initialization | Explicit method to ensure creation in the global context. |
| `data = res[0].info` | Object Access | Extracts a specific property from a JSON object or DB result. |
---
# SECTION II: Input and Output (I/O) Management
This section describes the mechanisms that AVAP uses for external data ingestion, parameter integrity validation, and constructing the response package that will be delivered to the final client.
---
## 2.1 Intelligent Parameter Capture (`addParam`)
The `addParam` command is the component in charge of extracting information from the incoming HTTP request. Its design is **source-agnostic**, which simplifies development by not requiring the programmer to specify where the data comes from.
### Interface
`addParam(param_name, target_variable)`
### Priority Mechanics (Cascading Search)
When `addParam` is invoked, the AVAP engine inspects the request in the following hierarchical order:
1. **Query Arguments:** Parameters present in the URL (e.g., `?id=123`).
2. **JSON Body:** If the request has a `Content-Type: application/json`, it looks for the key inside the JSON object.
3. **Form Data / Body Arguments:** Data sent via standard forms (`x-www-form-urlencoded`).
### Technical Behavior
- **Automatic Decoding:** The engine attempts to decode values to ASCII/UTF-8 format, eliminating encoding inconsistencies.
- **Null Treatment:** If the requested parameter does not exist in any of the sources, the target variable (`target_variable`) is initialized as `None`. This allows performing subsequent security checks via `if` blocks.
---
## 2.2 Validation and Collection Counting (`getListLen`)
To guarantee that an API is robust, it is necessary to validate how much information has been received. `getListLen` acts as AVAP's volume inspector.
### Interface
`getListLen(source_variable, target_variable)`
### I/O Applications
- **Parameter Validation:** Allows counting how many elements a variable contains that has been populated by `addParam` or `getQueryParamList`.
- **Loop Security:** Before starting a `startLoop`, it is recommended to use `getListLen` to define the upper limit of the cycle, avoiding overflow errors.
- **Database Results:** After a query, it determines if records were obtained (length > 0) or if the query resulted empty.
---
## 2.3 Multiple List Capture (`getQueryParamList`)
Scenarios exist where the same parameter is sent several times (e.g., search filters like `?color=red&color=blue`). AVAP manages this through a specialized capture in lists.
### Interface
`getQueryParamList(param_name, target_list_variable)`
### Effect
Transforms all occurrences of `param_name` into a structured list inside `target_list_variable`. If there is only one value, it creates a single-element list. This ensures that subsequent logic can always treat the data as a collection, avoiding type errors.
---
## 2.4 Construction of the Response (`addResult`)
The `addResult` command is in charge of registering which variables will be part of the response body. AVAP dynamically constructs a JSON output object based on calls to this command.
### Interface
`addResult(source_variable)`
### Advanced Features
- **Promise Management:** If the variable passed to `addResult` is the result of an operation initiated with `go_async`, the engine will automatically mark that field as `"promised"` in the response, or return the thread ID if synchronization has not completed.
- **String Cleaning:** The engine detects if the content of the variable has redundant quotes (product of previous evaluations) and normalizes them to ensure that the resulting JSON is valid and clean.
- **Multi-Registration:** Multiple calls to `addResult` can be made. Each call adds a new key to the output JSON object. By default, the key in the JSON will be the variable name, unless a custom key is used in the engine.
---
## 2.5 HTTP Status Control (`_status`)
AVAP uses a reserved system variable to communicate with the underlying web server and define the success or error code of the transaction.
### Use of `_status`
When assigning a numerical value to the `_status` variable (using `addVar` or direct assignment), the programmer defines the HTTP code of the response.
| **Code** | **Common Use in AVAP** |
| :--- | :--- |
| **200** | Successful operation (Default value). |
| **201** | Resource successfully created. |
| **400** | Parameter validation error (Bad Request). |
| **401** | Authentication failure. |
| **500** | Internal error captured in an `exception` block. |
### Section II Integrated Example
```
// We capture input
addParam("user_id", id)
// We validate presence
if(id, None, '==')
addVar(_status, 400)
addVar(error, "The user ID is mandatory")
addResult(error)
return()
end()
// If we reach here, we respond with success
addVar(_status, 200)
addResult(id)
```
---
# SECTION III: Control Logic and Decision Structures
This section details how AVAP manages execution flow. The language uses closed block structures that allow for a clear sequential reading, facilitating the debugging of complex APIs.
---
## 3.1 The Conditional Block (`if / else / end`)
The `if` structure in AVAP is a versatile tool that allows for atomic comparisons or the evaluation of complex logical expressions processed by the dynamic evaluation engine.
### Standard Interface
`if(variable_A, valor_B, operador)`
### Available Operators
| **Operator** | **Description** | **Example** |
| :--- | :--- | :--- |
| `=` | Strict equality (or numerical equivalence). | `if(rol, "admin", "=")` |
| `!=` | Inequality. | `if(status, 200, "!=")` |
| `>` / `<` | Numerical magnitude comparison. | `if(edad, 18, ">")` |
| `in` | Checks if an element belongs to a list or string. | `if(user, lista_negra, "in")` |
### Evaluation of Complex Expressions
AVAP allows omitting comparison parameters to evaluate a complete logical expression directly in the third parameter.
- **Example:** `if(None, None, "age >= 18 and balance > 100")`.
### Closing Structure
Every `if` block can include an optional `else()` block and **must** end with the `end()` command.
---
## 3.2 Iterations and Loops (`startLoop / endLoop`)
For the processing of collections (like database rows or parameter lists), AVAP implements a repetition cycle controlled by indices.
### Interface
`startLoop(contador, inicio, fin)`
### Execution Mechanics
1. **Initialization:** The engine creates the `contador` variable with the value of `inicio`.
2. **Increment:** In each turn, the counter increases automatically by 1 unit.
3. **Exit Condition:** The loop stops when the `contador` exceeds the value of `fin`.
### Practical Example: List Processing
```
// We obtain the length of a list captured in Section II
getListLen(items_received, total)
startLoop(i, 0, total)
current_item = items_received[i]
// Processing logic for each item...
endLoop()
```
---
## 3.3 Error Management and Robustness (`try / exception`)
AVAP is a language designed for production environments where external failures (database timeout, down third-party APIs) are a reality. The `try` block allows capturing these events without stopping the server.
### Interface
`try` ... `exception(error_variable)` ... `end()`
### Technical Operation
- **`try` Block:** The engine attempts to execute the instructions contained within. If a critical failure occurs, it stops execution of that block immediately.
- **`exception` Block:** If an error is detected, control passes to this block. The `error_variable` is automatically populated with a string describing the failure (simplified Stack trace).
- **`end()` Block:** Closes the structure and allows the script to continue its normal execution after the error handling.
### Example of Security in Connectors
```
try
// We attempt a query to an external connector (Section V)
resultado = db.query("SELECT * FROM pagos")
exception(failure_detail)
// If it fails, we log the error and notify
addVar(_status, 500)
addVar(message, "Persistence error: %s" % failure_detail)
addResult(message)
end()
```
---
## 3.4 Premature Exit Control (`return`)
The `return()` command is a control instruction that immediately terminates the execution of the current context (be it a function or the main script).
- If used within a **function**, it returns control (and optionally a value) to the caller.
- If used in the **main flow**, it ends execution of the API and triggers the automatic sending of the JSON response built up to that moment.
---
**Summary of Section III:** With these structures, the AVAP programmer has total control over the dynamic behavior of the code. The combination of **Dynamic Evaluation (Section I)**, **Data Validation (Section II)** and **Control Structures (Section III)** allows for building extremely complex and secure microservices.
# SECTION IV: Concurrency and Asynchrony
AVAP implements a concurrency model based on threads that allows for "fire-and-forget" or parallel execution with subsequent synchronization. This is fundamental for tasks like sending emails, processing logs or querying multiple external APIs simultaneously.
---
## 4.1 Launching Background Processes (`go_async`)
The command `go_async` extracts a block of code from the main sequential flow and places it in a parallel execution queue.
### Interface
`go_async(thread_id)`
### Execution Mechanics
1. **Identification:** The programmer assigns a `thread_id` (a string or variable) to be able to reference that process later.
2. **Bifurcation (Forking):** As soon as it is invoked, the AVAP engine creates a new native thread. The main flow immediately continues to the next instruction after the `go_async` block.
3. **Context Isolation:** The asynchronous thread inherits a copy of the state of the variables at the moment of firing, allowing it to work safely without interfering with the main thread.
### Example: Immediate Response with Long Process
```
addParam("email", destination)
go_async("email_delivery")
// This block takes 5 seconds, but the API does not wait
email_service.send(destination, "Welcome to AVAP")
end()
addVar(msg, "Your email is being processed in the background")
addResult(msg)
// The client receives the response in milliseconds
```
---
## 4.2 Result Synchronization (`gather`)
When the main flow needs data generated by an asynchronous thread to continue, the `gather` synchronization mechanism is used.
### Interface
`gather(thread_id, timeout)`
### Specifications
- **`thread_id`:** The identifier used in the `go_async` command.
- **`timeout` (Seconds):** Maximum time that the main thread will wait. If the thread does not finish in this time, AVAP launches an exception that can be captured (Section III).
### Technical Behavior
- **Controlled Blocking:** The main thread stops (suspends) until the `thread_id` thread finishes.
- **State Recovery:** Once synchronized, any variable modified inside the asynchronous thread is fused with the context of the main thread.
---
## 4.3 Optimized Parallel Execution (Fan-Out Pattern)
AVAP allows launching multiple threads and then waiting for all of them, reducing total execution time to the time of the slowest thread, instead of the sum of all.
### Example: Querying multiple databases
```
go_async("db_north")
data_north = connector_north.query("SELECT...")
end()
go_async("db_south")
data_south = connector_south.query("SELECT...")
end()
// We wait for both (Maximum 10 seconds)
gather("db_north", 10)
gather("db_south", 10)
// We combine results using Section I
total_result = data_north + data_south
addResult(total_result)
```
---
## 4.4 Status of Promises in the Output
As mentioned in **Section II**, if a variable that is still being processed in an asynchronous thread is sent to `addResult`, AVAP manages the response intelligently:
- **If the thread still runs:** The output JSON will show `"variable": "promised"` or the thread ID.
- **If the thread failed:** The error will be registered in the internal log and the variable will be `None`.
- **If `gather` was used before `addResult`:** The real processed value will be sent.
# SECTION V: Persistence, Connectors and Native ORM
AVAP is designed to be database agnostic. It allows data manipulation through three layers: the universal connector, simplified ORM commands and direct SQL execution.
---
## 5.1 The Universal Connector (`avapConnector`)
The `avapConnector` command is the starting point for any external integration. It uses a system of **Connection Tokens** (Base64) that encapsulate the configuration (host, port, credentials, driver) to keep the code clean and safe.
### Interface
`connector_variable = avapConnector("BASE64_TOKEN")`
### Characteristics of Connector Objects
Once the variable is instantiated, it behaves as an object with dynamic methods:
- **DB Connectors:** Expose the `.query(sql_string)` method, which returns objects or lists according to the result.
- **API Connectors (Twilio, Slack, etc.):** Expose native methods of the service (e.g., `.send_sms()`).
### Example: Use of Dynamic Assignment with Connectors
```
// We instantiate the connection
db = avapConnector("REJfQ09OTkVDVE9SR...")
// We execute and use Section I to filter on the fly
users = db.query("SELECT * FROM users")
first_admin = users[0].name if users[0].role == 'admin' else 'N/A'
addResult(first_admin)
```
---
## 5.2 Native ORM Layer (`ormCheckTable` / `ormDirect`)
For quick operations on the local or default database cluster, AVAP offers system-level commands that do not require prior instantiation.
### 5.2.1 `ormCheckTable`
Verifies the existence of a structure in the database. It is vital for installation scripts or automatic migrations.
- **Interface:** `ormCheckTable(table_name, target_var)`
- **Response:** The `target_var` will receive the string values `"True"` or `"False"`.
### 5.2.2 `ormDirect`
Executes SQL commands directly. It differs from `.query()` in that it is optimized for statements that do not necessarily return rows (like `INSERT`, `UPDATE` or `CREATE TABLE`).
- **Interface:** `ormDirect(statement, target_var)`
- **Use of Interpolation:** `ormDirect("UPDATE users SET login = '%s' WHERE id = %s" % (now, id), result)`
---
## 5.3 Data Access Abstraction (Implicit Commands)
AVAP includes specialized commands for the most common CRUD operations, reducing the need to write manual SQL and mitigating injection risks.
### `ormAccessSelect`
Performs filtered queries returning a structure of object lists.
- **Syntax:** `ormAccessSelect(table, filters, target)`
### `ormAccessInsert` / `ormAccessUpdate`
Manages data persistence. If used on an object that already has an ID, `Update` synchronizes changes; otherwise, `Insert` creates the record.
---
## 5.4 Dynamic Query Formatting (Anti-Injection)
As detailed in **Section I**, the AVAP engine processes SQL strings before sending them to the database engine. The official recommendation is to always use interpolation using the `%` operator to ensure that data types (Strings vs Integers) are correctly treated by the driver.
```
// Safe and Recommended Way
sql = "SELECT * FROM %s WHERE status = '%s'" % (table_name, status_recovered)
res = db.query(sql)
```
---
## 5.5 Cryptographic Security Integration (`encodeSHA256`)
In the persistence flow, AVAP provides native tools to secure sensitive data before it touches the disk.
### Interface
`encodeSHA256(source_text, target_variable)`
### Full Registration Flow (Final Example)
This example joins **Sections I, II, III and V**:
```
// II: Capture
addParam("pass", p)
addParam("user", u)
// I and V: Processing and Security
encodeSHA256(p, secure_pass)
// V: Insertion
sql = "INSERT INTO users (username, password) VALUES ('%s', '%s')" % (u, secure_pass)
ormDirect(sql, db_result)
// III and II: Response
if(db_result, "Success", "=")
addVar(msg, "User created")
addResult(msg)
end()
```
# SECTION VI: System Utilities and Transformation
This section documents the native commands for advanced string manipulation, precise time handling and generation of dynamic data.
---
## 6.1 Time and Date Management (`getDateTime` / `stampToDatetime`)
AVAP handles time in two ways: as **Epoch/Timestamp** (numerical, ideal for calculations) and as **Datetime** (formatted text, ideal for humans and databases).
### 6.1.1 `getDateTime`
Generates current time with high precision.
- **Interface:** `getDateTime(format, timeDelta, timeZone, targetVar)`
- **Parameters:**
- `format`: Ej: `"%Y-%m-%d %H:%M:%S"`. If left empty, returns the current Epoch.
- `timeDelta`: Seconds to add (positive) or subtract (negative). Very useful for calculating token expiration.
- `timeZone`: Time zone region (ej: "Europe/Madrid").
### 6.1.2 `stampToDatetime`
Converts a numerical value (Unix Timestamp) into a legible text string.
- **Interface:** `stampToDatetime(timestamp, format, offset, targetVar)`
- **Common use:** Formatting dates recovered from the database (Section V) before sending them to the client (Section II).
---
## 6.2 Advanced String Manipulation (`replace` / `randomString`)
### 6.2.1 `replace`
Allows for cleaning and transformation of texts. It is fundamental when data is received from the client that requires sanitization.
- **Interface:** `replace(sourceText, oldText, newText, targetVar)`
- **Example:** Cleaning spaces or unwanted characters in a username before a SQL query.
### 6.2.2 `randomString`
Generates secure random alphanumeric strings.
- **Interface:** `randomString(length, targetVar)`
- **Applications:** Generation of temporary passwords, session IDs or unique file names.
---
## 6.3 Security and Hash Operations (`encodeSHA256`)
Although mentioned in persistence, its use is a data transformation utility.
- **Mechanics:** It is a deterministic one-way function.
- **Important:** AVAP uses an optimized implementation that guarantees that the same text always produces the same hash, allowing secure "login" comparisons without knowing the real password.
---
## 6.4 The Value Return Command (`return`)
In the context of functions and flows, `return` not only stops execution, but can "inject" the result of a sub-routine into the main flow.
### Example of complete utility flow:
```
// 1. We generate a temporary token
randomString(16, token_raw)
// 2. We calculate expiration (within 1 hour = 3600 seg)
getDateTime("%Y-%m-%d %H:%M:%S", 3600, "UTC", expiration_date)
// 3. We format a system message using Section I
message = "Your token %s expires on %s" % (token_raw, expiration_date)
// 4. We send to the client (Section II)
addResult(message)
```
---
## 6.5 Table of Common Formats (Cheat Sheet)
| **Token** | **Description** | **Example** |
| :--- | :--- | :--- |
| `%Y` | Full year | 2026 |
| `%m` | Month (01-12) | 02 |
| `%d` | Day (01-31) | 23 |
| `%H` | Hour (00-23) | 21 |
| `%M` | Minute (00-59) | 45 |
# SECTION VII: Function Architecture and Scopes
This section details how to encapsulate reusable logic and how AVAP manages isolated memory to avoid side effects between different parts of the program.
---
## 7.1 Definition and Declaration (`function`)
A function in AVAP is an independent block of code that is registered in the engine to be invoked at any moment.
### Interface
`function function_name(argument1, argument2, ...){ ... }`
### Technical Characteristics:
- **Local Scope (`function_local_vars`):** Upon entering a function, AVAP creates a new dictionary of local variables. Variables created within (ej. `temp = 10`) do not exist outside the function, protecting global state.
- **Context Inheritance:** Functions can read global variables using the `$` prefix, but any new assignment (`=`) will remain in local scope unless a global persistence command is used.
---
## 7.2 The Exit Command (`return`)
It is the mechanism to finalize function execution and, optionally, send a value back to the caller.
### Interface
`return(variable_or_value)`
### Behavior:
1. **Finalization:** Immediately stops processing of the function.
2. **Data Transfer:** The value passed to the `return` is injected into the variable that performed the call in the main flow.
3. **Cleaning:** Once `return` is executed, the dictionary of local variables of that function is destroyed to free memory.
---
## 7.3 Invocation and Parameter Passing
Functions are called by their name followed by the values or variables they require.
### Example of Professional Implementation:
```
// Function Definition (Local Scope)
function calculate_discount(base_price, percentage){
factor = percentage / 100
discount = base_price * factor
total = base_price - discount
return(total)
}
// Main Flow (Global Scope)
addVar(pvp, 150)
// Call to the function passing a reference $ and a literal value
final_price = calculate_discount($pvp, 20)
addResult(final_price) // Result: 120
```
---
## 7.4 Functions as Middlewares
In the `registerEndpoint` command (Section I), the `middleware` parameter accepts a list of functions. These functions have special behavior:
- If a middleware executes a `return()` without a value or with an error value, AVAP can be configured to abort the request before reaching the main `handler`.
- They are ideal for **Guard** tasks:
- API Key verification.
- Data schema validation.
- Initial audit registration (logs).
---
## 7.5 Recursivity and Limits
AVAP allows recursivity (a function calling itself), but caution is recommended regarding stack depth for asynchronous processes (Section IV). To process large data volumes, the use of `startLoop` (Section III) is always preferable.