
//#region ../@intlayer/chokidar/dist/esm/api/dist/esm/fetcher.mjs
/**
* Default options for the fetcher function.
* Sets the default method to 'GET', the 'Content-Type' header to 'application/json',
* and includes credentials in the request.
*/
const fetcherOptions = {
	method: "GET",
	headers: { "Content-Type": "application/json" },
	credentials: "include"
};
/**
* Utility function to remove properties with undefined values from an object.
* This helps prevent sending undefined values in the request options.
*
* @param obj - The object to clean.
* @returns The cleaned object without undefined values.
*/
const removeUndefined = (obj) => {
	Object.keys(obj).forEach((key) => {
		if (obj[key] === void 0) delete obj[key];
	});
	return obj;
};
/**
* Deeply merges an array of objects into a single object.
* Later objects in the array overwrite properties of earlier ones.
*
* @template T - The type of objects being merged.
* @param objects - An array of objects to merge.
* @returns The merged object.
*/
const deepMerge = (objects) => objects.reduce((acc, obj) => {
	const acc1 = acc ?? {};
	const obj1 = removeUndefined(obj ?? {});
	if (typeof acc1 === "object" && typeof obj1 === "object") return {
		...acc1,
		...obj1
	};
	return obj1 ?? acc1;
}, {});
/**
* Fetcher function to make HTTP requests.
* It merges default options with user-provided options,
* handles query parameters and request body,
* and returns the parsed JSON response.
*
* @template T - The expected type of the response data.
* @param url - The endpoint URL.
* @param options - Additional options to customize the request.
* @returns A promise that resolves with the response data of type T.
*
* @example
* ```typescript
* // Making a GET request with query parameters
* const data = await fetcher<MyResponseType>('https://api.example.com/data', {
*   params: { search: 'query' },
* });
*
* // Making a POST request with a JSON body
* const result = await fetcher<AnotherResponseType>('https://api.example.com/submit', {
*   method: 'POST',
*   body: { key: 'value' },
* });
*
* // Merge body, headers, and params
* const result = await fetcher<AnotherResponseType>('https://api.example.com/submit', {
*   method: 'POST',
*   body: { key: 'value' },
*   headers: { 'Content-Type': 'application/json' },
*   params: { search: 'query' },
* },
* {
*   headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
*   params: { page: 1 },
* });
* ```
*
* Result:
* ```typescript
* {
*   method: 'POST',
*   headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
*   params: { page: 1, search: 'query' },
*   body: { key: 'value' },
* }
* ```
*/
const fetcher = async (url, ...options) => {
	const { signal } = new AbortController();
	let paramsString = "";
	let bodyString;
	const mergedOptions = deepMerge([fetcherOptions, ...options.map(({ body, params: params$1, headers,...otherOptions }) => otherOptions)]);
	const mergedHeaders = deepMerge([fetcherOptions.headers, ...options.map((option) => option.headers)]);
	const params = deepMerge(options.map((option) => option.params));
	const method = mergedOptions.method;
	if (method !== "GET" && method !== "HEAD") {
		const body = deepMerge(options.map((option) => option.body));
		if (mergedHeaders?.["Content-Type"] === "application/x-www-form-urlencoded") bodyString = new URLSearchParams(body).toString();
		else bodyString = JSON.stringify(body);
	}
	if (Object.entries(params).length > 0) paramsString = `?${new URLSearchParams(params).toString()}`;
	const formattedOptions = {
		...mergedOptions,
		headers: mergedHeaders,
		body: bodyString,
		signal
	};
	const urlResult = `${url}${paramsString}`;
	const response = await fetch(urlResult, formattedOptions);
	if (!response.ok) {
		const result = await response.json();
		throw new Error(JSON.stringify(result.error) ?? "An error occurred");
	}
	return await response.json();
};

//#endregion
exports.fetcher = fetcher;
//# sourceMappingURL=fetcher.cjs.map