Repository: directus/directus
File: sdk/src/rest/utils/query-to-params.ts (TypeScript)

Code before:
 *
 * @param query The nested query object
 *
 * @returns Flat query parameters
 */
export const queryToParams = <Schema = any, Item = Record<string, unknown>>(
	query: ExtendedQuery<Schema, Item>,
): Record<string, string> => {
	const params: Record<string, string> = {};

	if (query.fields) {
		if (Array.isArray(query.fields) && query.fields.length > 0) {
			params['fields'] = formatFields(query.fields).join(',');
		}

		// backwards JS compatibility for `fields: "id,name"`
		if (typeof query.fields === 'string') {
			params['fields'] = query.fields;
		}
	}

	if (query.filter && typeof query.filter === 'object' && Object.keys(query.filter).length > 0) {
		params['filter'] = JSON.stringify(query.filter);
	}

	if (query.search && typeof query.search === 'string' && query.search.length > 0) {
		params['search'] = query.search;
	}

	if (query.sort) {
		if (Array.isArray(query.sort) && query.sort.length > 0) {
			params['sort'] = query.sort.join(',');
		}

		if (typeof query.sort === 'string' && query.sort.length > 0) {
			params['sort'] = query.sort;
		}
	}

	if ('limit' in query) {
		if (typeof query.limit === 'number' && query.limit >= -1) {
			params['limit'] = String(query.limit);
		}

		// backwards JS compatibility for string limits
		if (typeof query.limit === 'string' && Number(query.limit) >= -1) {
			params['limit'] = query.limit;
		}
	}

	if ('offset' in query) {

Review comment (suggestion):
```suggestion
	if (query.search && typeof query.search === 'string') {
```

Code after:
];

/**
 * Local utility functions
 */
const isBoolean = (value: unknown): value is boolean => typeof value === 'boolean';
const isString = (value: unknown): value is string => typeof value === 'string' && Boolean(value);
const isNumber = (value: unknown): value is number => typeof value === 'number';
const isArray = (value: unknown): value is unknown[] => Array.isArray(value) && value.length > 0;

const isObject = (value: unknown): value is Record<string, unknown> =>
	typeof value === 'object' && value !== null && !isArray(value) && Object.keys(value).length > 0;

/**
 * Transform nested query object to an url compatible format
 *
 * @param query The nested query object
 *
 * @returns Flat query parameters
 */
export const queryToParams = <Schema = any, Item = Record<string, unknown>>(
	query: ExtendedQuery<Schema, Item>,
): Record<string, string> => {
	const params: Record<string, string> = {};

	if (query.fields) {
		if (isArray(query.fields)) params['fields'] = formatFields(query.fields).join(',');
		// backwards JS compatibility for `fields: "id,name"`
		if (isString(query.fields)) params['fields'] = query.fields;
	}

	if (isObject(query.filter)) params['filter'] = JSON.stringify(query.filter);

	if (isString(query.search)) params['search'] = query.search;

	if (query.sort) {
		if (isArray(query.sort)) params['sort'] = query.sort.join(',');
		if (isString(query.sort)) params['sort'] = query.sort;
	}

	if ('limit' in query) {
		if (isNumber(query.limit) && query.limit >= -1) params['limit'] = String(query.limit);
		// backwards JS compatibility for string limits
		if (isString(query.limit)) params['limit'] = query.limit;
	}

	if ('offset' in query) {
		if (isNumber(query.offset) && query.offset >= 0) params['offset'] = String(query.offset);
		// backwards JS compatibility for string offsets
		if (isString(query.offset)) params['offset'] = query.offset;
	}