mirror of
https://codeberg.org/yeentown/barkey.git
synced 2025-07-07 20:44:34 +00:00
implement resolver.resolveCollectionItems
This commit is contained in:
parent
b506dd564b
commit
5f0bb5dcd7
3 changed files with 87 additions and 27 deletions
|
@ -19,11 +19,12 @@ import { ApLogService, calculateDurationSince, extractObjectContext } from '@/co
|
|||
import { ApUtilityService } from '@/core/activitypub/ApUtilityService.js';
|
||||
import { SystemAccountService } from '@/core/SystemAccountService.js';
|
||||
import { IdentifiableError } from '@/misc/identifiable-error.js';
|
||||
import { getApId, getNullableApId, IObjectWithId, isCollectionOrOrderedCollection } from './type.js';
|
||||
import { toArray } from '@/misc/prelude/array.js';
|
||||
import { AnyCollection, getApId, getNullableApId, IObjectWithId, isCollection, isCollectionOrOrderedCollection, isCollectionPage, isOrderedCollection, isOrderedCollectionPage } from './type.js';
|
||||
import { ApDbResolverService } from './ApDbResolverService.js';
|
||||
import { ApRendererService } from './ApRendererService.js';
|
||||
import { ApRequestService } from './ApRequestService.js';
|
||||
import type { IObject, ICollection, IOrderedCollection, ApObject } from './type.js';
|
||||
import type { IObject, ApObject } from './type.js';
|
||||
|
||||
export class Resolver {
|
||||
private history: Set<string>;
|
||||
|
@ -78,6 +79,65 @@ export class Resolver {
|
|||
}
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async resolveCollectionItems(value: string | IObject, limit?: number, allowAnonymousItems?: boolean): Promise<IObjectWithId[]> {
|
||||
const items: IObjectWithId[] = [];
|
||||
|
||||
const collection = await this.resolveCollection(value);
|
||||
await this.resolveCollectionItemsTo(collection, limit, allowAnonymousItems, collection.id, items);
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
private async resolveCollectionItemsTo(current: AnyCollection | null, limit: number | undefined, allowAnonymousItems: boolean | undefined, sourceUri: string | undefined, destination: IObjectWithId[]): Promise<void> {
|
||||
// This is pulled up to avoid code duplication below
|
||||
const iterate = async(items: ApObject): Promise<void> => {
|
||||
for (const item of toArray(items)) {
|
||||
// Stop when we reach the fetch limit
|
||||
if (this.history.size > this.recursionLimit) break;
|
||||
|
||||
// Stop when we reach the item limit
|
||||
if (limit != null && limit < 1) break;
|
||||
|
||||
// Use secureResolve whenever possible, to avoid re-fetching items that were included inline.
|
||||
const resolved = (sourceUri && !allowAnonymousItems)
|
||||
? await this.secureResolve(item, sourceUri)
|
||||
: await this.resolve(getApId(item), allowAnonymousItems);
|
||||
destination.push(resolved);
|
||||
|
||||
// Decrement the outer variable directly, because the code below checks it too
|
||||
if (limit != null) limit--;
|
||||
}
|
||||
};
|
||||
|
||||
while (current != null) {
|
||||
// Iterate all items in the current page
|
||||
if (current.items) {
|
||||
await iterate(current.items);
|
||||
}
|
||||
if (current.orderedItems) {
|
||||
await iterate(current.orderedItems);
|
||||
}
|
||||
|
||||
if (this.history.size >= this.recursionLimit) {
|
||||
// Stop when we reach the fetch limit
|
||||
current = null;
|
||||
} else if (limit != null && limit < 1) {
|
||||
// Stop when we reach the item limit
|
||||
current = null;
|
||||
} else if (isCollection(current) || isOrderedCollection(current)) {
|
||||
// Continue to first page
|
||||
current = current.first ? await this.resolveCollection(current.first, true) : null;
|
||||
} else if (isCollectionPage(current) || isOrderedCollectionPage(current)) {
|
||||
// Continue to next page
|
||||
current = current.next ? await this.resolveCollection(current.next, true) : null;
|
||||
} else {
|
||||
// Stop in all other conditions
|
||||
current = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Securely resolves an AP object or URL that has been sent from another instance.
|
||||
* An input object is trusted if and only if its ID matches the authority of sentFromUri.
|
||||
|
|
|
@ -125,48 +125,46 @@ export interface IActivity extends IObject {
|
|||
};
|
||||
}
|
||||
|
||||
export interface ICollection extends IObject {
|
||||
export interface CollectionBase extends IObject {
|
||||
totalItems?: number;
|
||||
first?: IObject | string;
|
||||
last?: IObject | string;
|
||||
current?: IObject | string;
|
||||
partOf?: IObject | string;
|
||||
next?: IObject | string;
|
||||
prev?: IObject | string;
|
||||
items?: ApObject;
|
||||
orderedItems?: ApObject;
|
||||
}
|
||||
|
||||
export interface ICollection extends CollectionBase {
|
||||
type: 'Collection';
|
||||
totalItems: number;
|
||||
first?: IObject | string;
|
||||
last?: IObject | string;
|
||||
current?: IObject | string;
|
||||
items?: ApObject;
|
||||
orderedItems?: undefined;
|
||||
}
|
||||
|
||||
export interface IOrderedCollection extends IObject {
|
||||
export interface IOrderedCollection extends CollectionBase {
|
||||
type: 'OrderedCollection';
|
||||
totalItems: number;
|
||||
first?: IObject | string;
|
||||
last?: IObject | string;
|
||||
current?: IObject | string;
|
||||
items?: undefined;
|
||||
orderedItems?: ApObject;
|
||||
}
|
||||
|
||||
export interface ICollectionPage extends IObject {
|
||||
export interface ICollectionPage extends CollectionBase {
|
||||
type: 'CollectionPage';
|
||||
totalItems: number;
|
||||
first?: IObject | string;
|
||||
last?: IObject | string;
|
||||
current?: IObject | string;
|
||||
partOf?: IObject | string;
|
||||
next?: IObject | string;
|
||||
prev?: IObject | string;
|
||||
items?: ApObject;
|
||||
orderedItems?: undefined;
|
||||
}
|
||||
|
||||
export interface IOrderedCollectionPage extends IObject {
|
||||
export interface IOrderedCollectionPage extends CollectionBase {
|
||||
type: 'OrderedCollectionPage';
|
||||
totalItems: number;
|
||||
first?: IObject | string;
|
||||
last?: IObject | string;
|
||||
current?: IObject | string;
|
||||
partOf?: IObject | string;
|
||||
next?: IObject | string;
|
||||
prev?: IObject | string;
|
||||
items?: undefined;
|
||||
orderedItems?: ApObject;
|
||||
}
|
||||
|
||||
export type AnyCollection = ICollection | IOrderedCollection | ICollectionPage | IOrderedCollectionPage;
|
||||
|
||||
export const validPost = ['Note', 'Question', 'Article', 'Audio', 'Document', 'Image', 'Page', 'Video', 'Event'];
|
||||
|
||||
export const isPost = (object: IObject): object is IPost => {
|
||||
|
@ -269,7 +267,7 @@ export const isCollectionPage = (object: IObject): object is ICollectionPage =>
|
|||
export const isOrderedCollectionPage = (object: IObject): object is IOrderedCollectionPage =>
|
||||
getApType(object) === 'OrderedCollectionPage';
|
||||
|
||||
export const isCollectionOrOrderedCollection = (object: IObject): object is ICollection | IOrderedCollection =>
|
||||
export const isCollectionOrOrderedCollection = (object: IObject): object is AnyCollection =>
|
||||
isCollection(object) || isOrderedCollection(object) || isCollectionPage(object) || isOrderedCollectionPage(object);
|
||||
|
||||
export interface IApPropertyValue extends IObject {
|
||||
|
|
|
@ -12918,6 +12918,8 @@ export type operations = {
|
|||
content: {
|
||||
'application/json': {
|
||||
uri: string;
|
||||
expandCollectionItems?: boolean;
|
||||
allowAnonymous?: boolean;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue