文件
mynode/packages/lib/services/rest/utils/collectionToPaginatedResults.ts
chen 301194963b
一些检查失败了
automerge / automerge (push) Has been cancelled
react-native-android-build-apk / AssembleRelease (push) Has been cancelled
Build macOS M1 / Main (push) Has been cancelled
Joplin Continuous Integration / Main (macos-15-intel) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-11-vs2026-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-2025) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04-arm) (push) Has been cancelled
Joplin UI tests / Main (ubuntu-22.04) (push) Has been cancelled
Joplin UI tests / Main (windows-2025) (push) Has been cancelled
Joplin UI tests / Mobile (push) Has been cancelled
Close stale issues / ProcessStaleIssues (push) Has been cancelled
feat: Initial clean release of CHM
2026-11-04 11:29:39 +08:00

67 行
2.2 KiB
TypeScript

import { ModelType } from '../../../BaseModel';
import { ModelFeedPage } from '../../../models/utils/paginatedFeed';
import { PaginationOrderDir } from '../../../models/utils/types';
import { Request } from '../Api';
import requestPaginationOptions from '../utils/requestPaginationOptions';
import requestFields from './requestFields';
export interface Options {
sort?: boolean;
}
// Note that this is inefficient pagination as it requires all the items to
// have been loaded first, even if not all of them are returned.
//
// It's however convenient for smaller lists as it reduces the need for
// building complex SQL queries.
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Callers pass entity types (NoteEntity, FolderEntity, etc.) which lack index signatures
export default function(itemType: ModelType, items: any[], request: Request, options: Options = null): ModelFeedPage {
options = {
sort: true,
...options,
};
const fields = requestFields(request, itemType);
const pagination = requestPaginationOptions(request);
const startIndex = (pagination.page - 1) * pagination.limit;
const itemCount = Math.min(items.length - startIndex, pagination.limit);
const hasMore = itemCount >= pagination.limit;
const sortBy = pagination.order[0].by;
const sortDir = pagination.order[0].dir;
const caseInsensitive = pagination.order[0].caseInsensitive;
const sortedItems = items.slice().map(item => {
if (!fields.length) return item;
const newItem: Record<string, unknown> = {};
for (const k of Object.keys(item)) {
if (!fields.includes(k)) continue;
newItem[k] = item[k];
}
return newItem;
});
if (options.sort) {
sortedItems.sort((a, b) => {
let v1: unknown = a && (sortBy in a) ? a[sortBy] : '';
let v2: unknown = b && (sortBy in b) ? b[sortBy] : '';
if (caseInsensitive && typeof v1 === 'string') v1 = v1.toLowerCase();
if (caseInsensitive && typeof v2 === 'string') v2 = v2.toLowerCase();
if (sortDir === PaginationOrderDir.ASC) {
if (v1 < v2) return -1;
if (v2 > v1) return +1;
} else {
if (v1 > v2) return -1;
if (v2 < v1) return +1;
}
return 0;
});
}
return {
items: sortedItems.slice(startIndex, startIndex + itemCount),
has_more: hasMore,
};
}