# FQL Toolkit Library
A lightweight and flexible JavaScript toolkit library for Form Query Language (FQL) that provides a fluent API for building and executing FQL queries.

## 📦 Installation
```bash
# Using npm
npm install fql-toolkit
```

## 📦 Running Tests
```bash
# Using npm
npm test
```

## 🔧 Quick Start
```javascript
import { FQL } from 'fql-toolkit';

// Initialize the client
const fql = new FQL({
  url: 'https://api.example.com',
  token: 'FQL USER TOKEN HERE'
});

// Create a form
await fql.createForm('users')
  .addDataDefinition({name: 'name', type: 'text'})
  .addDataDefinition({name: 'age', type: 'number'})
  .addDataDefinition({name: 'email', type: 'text'})
  .execute();

// Show forms
await fql.showForms()
  .setForm("users")
  .execute()
  .then(response => console.log(response.output));

// Insert data
await fql.createNew('users')
  .setValue('John Doe')
  .setValue(30)
  .setValue('john@example.com')
  .execute();

// Show data
await fql.getCase('users')
  .addFields('name', 'age')
  .execute()
  .then(response => console.log(response.output));

// Remove forms
await fql.removeForms()
  .setForm("users")
  .execute();
```

## 📖 Documentation
### Initialization
```javascript
const fql = new FQL({
  url: string,   // Required: API endpoint
  token: string  // Required: FQL token
});
```

### Creating Forms
```javascript
// Basic form creation
await fql.createForm('employees')
  .addDataDefinition({name: 'name', type: 'text'})
  .addDataDefinition({name: 'salary', type: 'number'})
  .execute();

// Getting the FQL without executing
const formQuery = fql.createForm('employees')
  .addDataDefinition({name: 'name', type: 'text'})
  .getFQL();
// Result: "create form employees(name text, salary number)"
```

### Inserting Data
```javascript
// Single record insertion
await fql.createData('employees')
  .setValue('John Doe')
  .setValue(50000)
  .execute();

// Get FQL without executing
const dataQuery = fql.createData('employees')
  .setValue('Jane Smith')
  .setValue(60000)
  .getFQL();
// Result: "create employees('Jane Smith', 60000)"
```

### Showing Forms
```javascript
// All forms
const allForms = fql.showForms();

// Specific form
const specificForm = fql.showForms().setForm("People");

// List of forms
const formList = fql.showForms().setForm("People").setForm("Countries");
// Equivalent to fql.showForms().setForms(["People", "Countries"])

// Get FQL without executing
allForms.getFql(); // Result: "show forms"
specificForm.getFql(); // Result: "show forms People"
formList.getFql(); // Result: "show forms People Countries"

// Show all forms
await allForms.execute();

// Show a specific form
await specificForm.execute();

// Show list of forms
await formList.execute();
```

### Removing Forms
```javascript
// All forms
const allForms = fql.removeForms();

// Specific form
const specificForm = fql.removeForms().setForm("People");

// List of forms
const formList = fql.removeForms().setForm("People").setForm("Countries");
// Equivalent to fql.removeForms().setForms(["People", "Countries"])

// Get FQL without executing
allForms.getFql(); // Result: "show forms"
specificForm.getFql(); // Result: "show forms People"
formList.getFql(); // Result: "show forms People, Countries"

// Show all forms
await allForms.execute();

// Show a specific form
await specificForm.execute();

// Show list of forms
await formList.execute();
```

### Error Handling
```javascript
try {
  const result = await fql.createData('employees')
    .setValue('John Doe')
    .setValue('invalid_salary') // Wrong type
    .execute();
} catch (error) {
  if (error instanceof FQLError) {
    console.error('FQL Error:', error.message);
    console.error('Query:', error.query);
    console.error('Code:', error.code);
  }
}
```

## 🎯 Examples
### Complex Form Creation
```javascript
const form = await fql.createForm('products')
  .addDataDefinition({name: 'id', type: 'number'})
  .addDataDefinition({name: 'name', type: 'text'})
  .addDataDefinition({name: 'description', type: 'text'})
  .addDataDefinition({name: 'price', type: 'number'})
  .addDataDefinition({name: 'inStock', type: 'boolean'})
  .addDataDefinition({name: 'categories', type: 'array'})
  .addDataDefinition({name: 'created', type: 'date'})
  .execute();
```

### Batch Data Insertion
```javascript
const products = [
  ['Product A', 29.99, true],
  ['Product B', 49.99, false],
  ['Product C', 99.99, true]
];

for (const [name, price, inStock] of products) {
  await fql.createData('products')
    .setValue(name)
    .setValue(price)
    .setValue(inStock)
    .execute();
}
```

## 🔍 API Reference
### FQL Class
| Method	      | Description	                      | Parameters         | Returns                 |
|---------------|-----------------------------------|--------------------|-------------------------|
| `createForm`	| `Creates a FQLForm builder`       | `formName: string` | `FQLFormBuilder`        |
| `createNew`	  | `Creates a FQLData builder`       | `formName: string` | `FQLDataBuilder`        |
| `showForms`   | `Create a FQLShowForms builder`   | `None`             | `FQLShowFormsBuilder`   |
| `removeForms` | `Create a FQLRemoveForms builder` | `None`             | `FQLRemoveFormsBuilder` |
| `executeFQL`	| `Executes raw FQL`	              | `query: string`    | `Promise<any>`          |

### FQLFormBuilder Class
| Method	            | Description	                   | Parameters                                                                                                  | Returns          |
|---------------------|--------------------------------|-------------------------------------------------------------------------------------------------------------|------------------|
| `addDataDefinition`	| `Adds a data definition field` | `{name: string, type: string, notNull: boolean = false, unique: boolean: false}`	                           | `FQLFormBuilder` |
| `addDataReference`	| `Adds a data reference field`  | `{name: string, cardinality: list = [0, 1], path: list, totally: boolean = false, unique: boolean = false}` | `FQLFormBuilder` |
| `create`	          | `Executes the query`           | `None`	                                                                                                     | `Promise<any>`   |
| `getFQL`	          | `Gets the FQL string`	         | `query: string`                                                                                             | `string`         |

### FQLDataBuilder Class
| Method	      | Description	             | Parameters         | Returns          |
|---------------|--------------------------|--------------------|------------------|
| `setValue`	  | `Adds a value`           | `value: any`	      | `FQLDataBuilder` |
| `create`	    | `Executes the query`     | `None`	            | `Promise<any>`   |
| `getFQL`	    | `Gets the FQL string`	   | `query: string`    | `string`         |

### FQLShowFormsBuilder Class
| Method	      | Description	             | Parameters         | Returns               |
|---------------|--------------------------|--------------------|-----------------------|
| `setForm`	    | `Add a form`             | `value: string`	  | `FQLShowFormsBuilder` |
| `setForms`	  | `Add a form list`        | `value: [string]`	| `FQLShowFormsBuilder` |
| `create`	    | `Executes the query`     | `None`	            | `Promise<any>`        |
| `getFQL`	    | `Gets the FQL string`	   | `query: string`    | `string`              |

### FQLRemoveFormsBuilder Class
| Method	      | Description	             | Parameters         | Returns                 |
|---------------|--------------------------|--------------------|-------------------------|
| `setForm`	    | `Add a form`             | `value: string`	  | `FQLRemoveFormsBuilder` |
| `setForms`	  | `Add a form list`        | `value: [string]`	| `FQLRemoveFormsBuilder` |
| `create`	    | `Executes the query`     | `None`	            | `Promise<any>`          |
| `getFQL`	    | `Gets the FQL string`	   | `query: string`    | `string`                |
