"use strict";
/* Socket Lib - Built with rolldown */
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const require_primordials_buffer = require('../primordials/buffer.js');
const require_primordials_error = require('../primordials/error.js');
const require_primordials_map_set = require('../primordials/map-set.js');
const require_schema_validate = require('../schema/validate.js');
const require_strings_transform = require('../strings/transform.js');
const require_primordials_json = require('../primordials/json.js');

//#region src/json/parse.ts
/**
* @file JSON parsing utilities with Buffer detection and BOM stripping.
*   Provides safe JSON parsing with automatic encoding handling, plus
*   `parseJsonSafe` for untrusted input (prototype-pollution protection + size
*   limits + optional schema validation).
*/
/**
* Check if a value is a Buffer instance. Uses duck-typing to detect Buffer
* without requiring Node.js Buffer in type system.
*
* @example
*   ;```ts
*   isBuffer(Buffer.from('hello')) // => true
*   isBuffer('hello') // => false
*   isBuffer({ length: 5 }) // => false
*   ```
*
* @param x - Value to check.
*
* @returns `true` if value is a Buffer, `false` otherwise
*/
/*@__NO_SIDE_EFFECTS__*/
function isBuffer(x) {
	if (!x || typeof x !== "object") return false;
	const obj = x;
	if (typeof obj["length"] !== "number") return false;
	if (typeof obj["copy"] !== "function" || typeof obj["slice"] !== "function") return false;
	if (typeof obj["length"] === "number" && obj["length"] > 0 && typeof obj[0] !== "number") return false;
	const Ctor = x.constructor;
	return !!(typeof Ctor?.isBuffer === "function" && Ctor.isBuffer(x));
}
/**
* Check if a value is a JSON primitive type. JSON primitives are: `null`,
* `boolean`, `number`, or `string`.
*
* @example
*   ;```ts
*   isJsonPrimitive(null) // => true
*   isJsonPrimitive(true) // => true
*   isJsonPrimitive(42) // => true
*   isJsonPrimitive('hello') // => true
*   isJsonPrimitive({}) // => false
*   isJsonPrimitive([]) // => false
*   isJsonPrimitive(undefined) // => false
*   ```
*
* @param value - Value to check.
*
* @returns `true` if value is a JSON primitive, `false` otherwise
*/
/*@__NO_SIDE_EFFECTS__*/
function isJsonPrimitive(value) {
	return value === null || typeof value === "boolean" || typeof value === "number" || typeof value === "string";
}
/**
* Parse JSON content with automatic Buffer handling and BOM stripping. Provides
* safer JSON parsing with helpful error messages and optional error
* suppression.
*
* Features: - Automatic UTF-8 Buffer conversion - BOM (Byte Order Mark)
* stripping for cross-platform compatibility - Enhanced error messages with
* filepath context - Optional error suppression (returns `undefined` instead of
* throwing) - Optional reviver for transforming parsed values.
*
* @example
*   ;```ts
*   // Basic usage
*   const data = parseJson('{"name":"example"}')
*   console.log(data.name) // => 'example'
*
*   // Parse Buffer with UTF-8 BOM
*   const buffer = Buffer.from('\uFEFF{"value":42}')
*   const data = parseJson(buffer)
*   console.log(data.value) // => 42
*
*   // Enhanced error messages with filepath
*   try {
*     parseJson('invalid', { filepath: 'config.json' })
*   } catch (e) {
*     console.error(e.message)
*     // => "config.json: Unexpected token i in JSON at position 0"
*   }
*
*   // Suppress errors
*   const result = parseJson('invalid', { throws: false })
*   console.log(result) // => undefined
*
*   // Transform values with reviver
*   const json = '{"created":"2024-01-15T10:30:00Z"}'
*   const data = parseJson(json, {
*     reviver: (key, value) => {
*       if (key === 'created' && typeof value === 'string') {
*         return new Date(value)
*       }
*       return value
*     },
*   })
*   console.log(data.created instanceof Date) // => true
*   ```
*
* @param content - JSON string or Buffer to parse.
* @param options - Optional parsing configuration.
*
* @returns Parsed JSON value, or `undefined` if parsing fails and `throws` is
*   `false`
*
* @throws {SyntaxError} When JSON is invalid and `throws` is `true` (default)
*/
/*@__NO_SIDE_EFFECTS__*/
function parseJson(content, options) {
	const { filepath, reviver, throws } = {
		__proto__: null,
		...options
	};
	const shouldThrow = throws === void 0 || !!throws;
	const jsonStr = /* @__PURE__ */ isBuffer(content) ? content.toString("utf8") : content;
	try {
		return require_primordials_json.JSONParse(/* @__PURE__ */ require_strings_transform.stripBom(jsonStr), reviver);
	} catch (e) {
		if (shouldThrow) {
			const error = e;
			if (error && typeof filepath === "string") error.message = `${filepath}: ${error.message}`;
			throw error;
		}
	}
}
const DANGEROUS_KEYS = new require_primordials_map_set.SetCtor([
	"__proto__",
	"constructor",
	"prototype"
]);
const DEFAULT_MAX_SIZE = 10 * 1024 * 1024;
/**
* Safely parse JSON with optional schema validation and security controls.
* Throws on parse failure, validation failure, or security violation.
*
* Recommended for parsing untrusted JSON (user input, network payloads,
* anything beyond a trust boundary). Layers:
*
* 1. Size cap (default 10 MB) prevents memory exhaustion.
* 2. Prototype-pollution reviver rejects `__proto__` / `constructor` / `prototype`
*    keys at any depth (unless `allowPrototype: true`).
* 3. Optional Zod-shaped schema validation via
*    `@socketsecurity/lib/schema/validate`.
*
* For trusted-source reads (package.json, local config files), prefer
* `parseJson()` — it offers Buffer/BOM handling and filepath-aware error
* messages, without the untrusted-input overhead.
*
* @example
*   ;```ts
*   // Basic parsing with type inference.
*   const data = parseJsonSafe<User>('{"name":"Alice","age":30}')
*
*   // With schema validation.
*   import { z } from 'zod'
*   const userSchema = z.object({ name: z.string(), age: z.number() })
*   const user = parseJsonSafe('{"name":"Alice","age":30}', userSchema)
*
*   // With size limit.
*   const data = parseJsonSafe(jsonString, undefined, { maxSize: 1024 })
*
*   // Allow prototype keys (DANGEROUS — only for trusted sources).
*   const data = parseJsonSafe('{"__proto__":{}}', undefined, {
*     allowPrototype: true,
*   })
*   ```
*
* @throws {Error} When `jsonString` exceeds `maxSize`.
* @throws {Error} When JSON parsing fails.
* @throws {Error} When prototype-pollution keys are detected (and
*   `allowPrototype` is not `true`).
* @throws {Error} When schema validation fails.
*/
/*@__NO_SIDE_EFFECTS__*/
function parseJsonSafe(jsonString, schema, options = {}) {
	const { allowPrototype = false, maxSize = DEFAULT_MAX_SIZE } = options;
	if (require_primordials_buffer.BufferByteLength(jsonString, "utf8") > maxSize) throw new require_primordials_error.ErrorCtor(`JSON string exceeds maximum size limit${maxSize !== DEFAULT_MAX_SIZE ? ` of ${maxSize} bytes` : ""}`);
	let parsed;
	try {
		parsed = allowPrototype ? require_primordials_json.JSONParse(jsonString) : require_primordials_json.JSONParse(jsonString, prototypePollutionReviver);
	} catch (e) {
		throw new require_primordials_error.ErrorCtor(`Failed to parse JSON: ${e}`);
	}
	if (schema) {
		const result = require_schema_validate.validateSchema(schema, parsed);
		if (!result.ok) throw new require_primordials_error.ErrorCtor(`Validation failed: ${result.errors.map((e) => `${e.path.join(".") || "(root)"}: ${e.message}`).join(", ")}`);
		return result.value;
	}
	return parsed;
}
/**
* JSON.parse reviver that rejects prototype pollution keys at any depth.
*
* @internal
*/
function prototypePollutionReviver(key, value) {
	if (DANGEROUS_KEYS.has(key)) throw new require_primordials_error.ErrorCtor("JSON contains potentially malicious prototype pollution keys");
	return value;
}

//#endregion
exports.isBuffer = isBuffer;
exports.isJsonPrimitive = isJsonPrimitive;
exports.parseJson = parseJson;
exports.parseJsonSafe = parseJsonSafe;
exports.prototypePollutionReviver = prototypePollutionReviver;