# json

JSON utilities for parsing, validation, conversion, and sanitization.

## Functions

| Function | Description | Example |
|----------|-------------|---------|
| `counter` | Count occurrences of key-value in JSON | `dphelper.json.counter(data, 'status', 'active')` |
| `toCsv` | Convert JSON array to CSV string | `dphelper.json.toCsv(users)` |
| `saveCsvAs` | Download JSON as CSV file | `dphelper.json.saveCsvAs(csvData, 'export')` |
| `is` | Check if string is valid JSON | `dphelper.json.is('{"key": "value"}')` |
| `parse` | Parse JSON string safely | `dphelper.json.parse('{"key": "value"}')` |
| `sanitize` | Sanitize malformed JSON string | `dphelper.json.sanitize(input)` |
| `sanitizeJsonValue` | Sanitize individual JSON values | `dphelper.json.sanitizeJsonValue('hello')` |

## Description

Complete JSON manipulation toolkit:
- **Validation** - Check if strings are valid JSON
- **Parsing** - Safe JSON parsing with error handling
- **Conversion** - JSON to CSV export
- **Sanitization** - Clean JSON strings, prevent injection

## Usage Examples

### JSON Validation

```javascript
// Check if string is valid JSON
console.log(dphelper.json.is('{"name": "John", "age": 30}')); // true
console.log(dphelper.json.is('[1, 2, 3]'));                   // true
console.log(dphelper.json.is('not valid json'));              // false
console.log(dphelper.json.is(''));                            // false

// Use for API response validation
function handleResponse(response) {
  const text = await response.text();
  if (!dphelper.json.is(text)) {
    throw new Error('Invalid JSON response');
  }
  return JSON.parse(text);
}
```

### JSON Parsing

```javascript
// Parse JSON safely
const obj = dphelper.json.parse('{"name": "John", "age": 30}');
console.log(obj); // { name: "John", age: 30 }

// Handles parsing errors gracefully
const bad = dphelper.json.parse('not json');
console.log(bad); // "Json not parsable"

// Use for user input
function parseUserInput(input) {
  try {
    return dphelper.json.parse(input);
  } catch {
    return null;
  }
}
```

### Counting JSON Properties

```javascript
const data = {
  items: [
    { id: 1, status: 'active' },
    { id: 2, status: 'active' },
    { id: 3, status: 'inactive' },
    { id: 4, status: 'active' }
  ]
};

// Count items with specific status
console.log(dphelper.json.counter(data, 'status', 'active')); // 3
console.log(dphelper.json.counter(data, 'status', 'inactive')); // 1

// Count total keys
console.log(dphelper.json.counter(data)); // 1 (the 'items' key)

// Works with nested arrays
const users = {
  users: [
    { role: 'admin', active: true },
    { role: 'user', active: true },
    { role: 'user', active: false }
  ]
};
console.log(dphelper.json.counter(users, 'role', 'user')); // 2
```

### JSON to CSV Conversion

```javascript
// Convert array of objects to CSV
const users = [
  { name: 'John', age: 30, city: 'NYC' },
  { name: 'Jane', age: 25, city: 'LA' },
  { name: 'Bob', age: 35, city: 'Chicago' }
];

const csv = dphelper.json.toCsv(users);
console.log(csv);
/*
name,age,city
John,30,NYC
Jane,25,LA
Bob,35,Chicago
*/

// Export API response to CSV
async function exportToCsv() {
  const response = await fetch('/api/users');
  const users = await response.json();

  const csv = dphelper.json.toCsv(users);
  dphelper.json.saveCsvAs(csv, 'users-export');
}
```

### Save CSV as File

```javascript
// Download CSV data as file
const data = [
  { product: 'Apple', price: 1.99, quantity: 100 },
  { product: 'Banana', price: 0.59, quantity: 200 }
];

const csv = dphelper.json.toCsv(data);
dphelper.json.saveCsvAs(csv, 'products');

// Filename will include timestamp: "products_20260302120000.csv"
```

### JSON Sanitization

```javascript
// Sanitize malformed JSON
const dirty = '{ "name": "John", "age": 30 }';
console.log(dphelper.json.sanitize(dirty));
// '{ "name":"John","age":30}'

// Clean up spacing issues
const messy = '{ "key" : "value" }';
console.log(dphelper.json.sanitize(messy));
// '{"key":"value"}'

// Handles various data types
const mixed = '{ "string": "hello", "number": 42, "bool": true, "null": null }';
console.log(dphelper.json.sanitize(mixed));
// '{"string":"hello","number":42,"bool":true,"null":""}'
```

### Value Sanitization

```javascript
// Sanitize individual JSON values
console.log(dphelper.json.sanitizeJsonValue('hello'));      // '"hello"'
console.log(dphelper.json.sanitizeJsonValue('hello world')); // '"hello world"'
console.log(dphelper.json.sanitizeJsonValue('test"quote')); // '"test"quote"'
console.log(dphelper.json.sanitizeJsonValue('line1\nline2')); // '"line1\nline2"'
console.log(dphelper.json.sanitizeJsonValue('tab\there'));    // '"tab here"'

// Use for building JSON manually
function safeJsonString(key, value) {
  const safeValue = dphelper.json.sanitizeJsonValue(value);
  return `"${key}":${safeValue}`;
}
```

## Advanced Usage

### Complete Data Export

```javascript
class DataExporter {
  constructor() {}

  exportToCsv(data, filename) {
    if (!Array.isArray(data) || data.length === 0) {
      console.error('Data must be a non-empty array');
      return;
    }

    const csv = dphelper.json.toCsv(data);
    dphelper.json.saveCsvAs(csv, filename);
  }

  exportTableToCsv(tableId, filename) {
    const rows = document.querySelectorAll(`#${tableId} tr`);
    const data = Array.from(rows).map(row => {
      return Array.from(row.querySelectorAll('td')).map(td => td.textContent);
    });

    this.exportToCsv(data, filename);
  }
}

// Usage
const exporter = new DataExporter();
exporter.exportToCsv(userList, 'users');
```

### JSON Validation Middleware

```javascript
function validateJsonMiddleware(req, res, next) {
  let body = '';

  req.on('data', chunk => {
    body += chunk.toString();
  });

  req.on('end', () => {
    if (!dphelper.json.is(body)) {
      return res.status(400).json({ error: 'Invalid JSON' });
    }

    try {
      req.body = dphelper.json.parse(body);
      next();
    } catch (err) {
      return res.status(400).json({ error: 'JSON parse error' });
    }
  });
}
```

### API Response Handler

```javascript
async function fetchJson(url) {
  const response = await fetch(url);

  if (!response.ok) {
    throw new Error(`HTTP ${response.status}`);
  }

  const text = await response.text();

  if (!dphelper.json.is(text)) {
    throw new Error('Response is not valid JSON');
  }

  return dphelper.json.parse(text);
}

// Usage
const data = await fetchJson('/api/users');
console.log(data);
```

## Details

- **Author:** Dario Passariello
- **Version:** 0.0.2
- **Creation Date:** 20210101
- **Last Modified:** 20260220
- **Environment:** Works in both client and server environments

---

*Automatically generated document*
