===== ISTEM =====
Solve the following programming task.

TASK: Custom JSON.stringify

Write a function 'jsonStringify(value)' that converts objects, arrays, strings, numbers and booleans into JSON text without using the native JSON.stringify.

STARTER CODE (javascript):
function jsonStringify(value) {
  // Write your code here
}

module.exports = { jsonStringify };


RULES:
- Keep the function name and signature EXACTLY as given.
- Return working code only. No explanations.
- Put the code in a single ``` block.
- Try to solve it first. If you genuinely cannot, write only this single
  line instead of producing faulty code: CANNOT_SOLVE

===== HAM YANIT =====
```javascript
function jsonStringify(value) {
  function escapeString(str) {
    return '"' + str.replace(/["\\\u0000-\u001f]/g, (match) => {
      switch (match) {
        case '"': return '\\"';
        case '\\': return '\\\\';
        case '\b': return '\\b';
        case '\f': return '\\f';
        case '\n': return '\\n';
        case '\r': return '\\r';
        case '\t': return '\\t';
        default:
          return '\\u' + match.charCodeAt(0).toString(16).padStart(4, '0');
      }
    }) + '"';
  }

  if (value === undefined || typeof value === 'function' || typeof value === 'symbol') {
    return undefined;
  }

  function serialize(val) {
    if (val && typeof val.toJSON === 'function') {
      val = val.toJSON();
    }

    if (val === null) {
      return 'null';
    }

    const type = typeof val;

    if (type === 'number') {
      return Number.isFinite(val) ? String(val) : 'null';
    }
    if (type === 'boolean') {
      return val ? 'true' : 'false';
    }
    if (type === 'string') {
      return escapeString(val);
    }
    if (type === 'undefined' || type === 'function' || type === 'symbol') {
      return 'null';
    }
    if (Array.isArray(val)) {
      const items = val.map((item) => {
        if (item === undefined || typeof item === 'function' || typeof item === 'symbol') {
          return 'null';
        }
        return serialize(item);
      });
      return '[' + items.join(',') + ']';
    }
    if (type === 'object') {
      const entries = [];
      for (const key of Object.keys(val)) {
        const propVal = val[key];
        if (propVal === undefined || typeof propVal === 'function' || typeof propVal === 'symbol') {
          continue;
        }
        entries.push(escapeString(key) + ':' + serialize(propVal));
      }
      return '{' + entries.join(',') + '}';
    }

    return undefined;
  }

  return serialize(value);
}

module.exports = { jsonStringify };
```