mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-20 22:42:53 -05:00
Refactored collection retrieval in admin-x-activitypub (#21491)
no refs Refactored collection retrieval to reduce code duplication and complexity
This commit is contained in:
parent
4c79887b79
commit
b90e16219d
2 changed files with 48 additions and 137 deletions
|
@ -183,7 +183,7 @@ describe('ActivityPubAPI', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getOutbox', function () {
|
describe('getOutbox', function () {
|
||||||
test('It passes the token to the outbox endpoint', async function () {
|
test('It passes the token to the outbox collection endpoint', async function () {
|
||||||
const fakeFetch = Fetch({
|
const fakeFetch = Fetch({
|
||||||
'https://auth.api/': {
|
'https://auth.api/': {
|
||||||
response: JSONResponse({
|
response: JSONResponse({
|
||||||
|
@ -213,7 +213,7 @@ describe('ActivityPubAPI', function () {
|
||||||
await api.getOutbox();
|
await api.getOutbox();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Returns an empty array when the outbox is empty', async function () {
|
test('Returns an empty array when the outbox collection is empty', async function () {
|
||||||
const fakeFetch = Fetch({
|
const fakeFetch = Fetch({
|
||||||
'https://auth.api/': {
|
'https://auth.api/': {
|
||||||
response: JSONResponse({
|
response: JSONResponse({
|
||||||
|
@ -247,7 +247,7 @@ describe('ActivityPubAPI', function () {
|
||||||
expect(actual).toEqual(expected);
|
expect(actual).toEqual(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Recursively retrieves all items and returns them when the outbox is not empty', async function () {
|
test('Recursively retrieves all items and returns them when the outbox collection is not empty', async function () {
|
||||||
const fakeFetch = Fetch({
|
const fakeFetch = Fetch({
|
||||||
'https://auth.api/': {
|
'https://auth.api/': {
|
||||||
response: JSONResponse({
|
response: JSONResponse({
|
||||||
|
@ -316,7 +316,7 @@ describe('ActivityPubAPI', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getFollowing', function () {
|
describe('getFollowing', function () {
|
||||||
test('It passes the token to the following endpoint', async function () {
|
test('It passes the token to the following collection endpoint', async function () {
|
||||||
const fakeFetch = Fetch({
|
const fakeFetch = Fetch({
|
||||||
'https://auth.api/': {
|
'https://auth.api/': {
|
||||||
response: JSONResponse({
|
response: JSONResponse({
|
||||||
|
@ -346,7 +346,7 @@ describe('ActivityPubAPI', function () {
|
||||||
await api.getFollowing();
|
await api.getFollowing();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Returns an empty array when the following is empty', async function () {
|
test('Returns an empty array when the following collection is empty', async function () {
|
||||||
const fakeFetch = Fetch({
|
const fakeFetch = Fetch({
|
||||||
'https://auth.api/': {
|
'https://auth.api/': {
|
||||||
response: JSONResponse({
|
response: JSONResponse({
|
||||||
|
@ -380,7 +380,7 @@ describe('ActivityPubAPI', function () {
|
||||||
expect(actual).toEqual(expected);
|
expect(actual).toEqual(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Recursively retrieves all items and returns them when the following is not empty', async function () {
|
test('Recursively retrieves all items and returns them when the following collection is not empty', async function () {
|
||||||
const fakeFetch = Fetch({
|
const fakeFetch = Fetch({
|
||||||
'https://auth.api/': {
|
'https://auth.api/': {
|
||||||
response: JSONResponse({
|
response: JSONResponse({
|
||||||
|
@ -437,7 +437,7 @@ describe('ActivityPubAPI', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getFollowers', function () {
|
describe('getFollowers', function () {
|
||||||
test('It passes the token to the following endpoint', async function () {
|
test('It passes the token to the followers collection endpoint', async function () {
|
||||||
const fakeFetch = Fetch({
|
const fakeFetch = Fetch({
|
||||||
'https://auth.api/': {
|
'https://auth.api/': {
|
||||||
response: JSONResponse({
|
response: JSONResponse({
|
||||||
|
@ -467,7 +467,7 @@ describe('ActivityPubAPI', function () {
|
||||||
await api.getFollowers();
|
await api.getFollowers();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Returns an empty array when the followers is empty', async function () {
|
test('Returns an empty array when the followers collection is empty', async function () {
|
||||||
const fakeFetch = Fetch({
|
const fakeFetch = Fetch({
|
||||||
'https://auth.api/': {
|
'https://auth.api/': {
|
||||||
response: JSONResponse({
|
response: JSONResponse({
|
||||||
|
@ -501,7 +501,7 @@ describe('ActivityPubAPI', function () {
|
||||||
expect(actual).toEqual(expected);
|
expect(actual).toEqual(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Recursively retrieves all items and returns them when the followers is not empty', async function () {
|
test('Recursively retrieves all items and returns them when the followers collection is not empty', async function () {
|
||||||
const fakeFetch = Fetch({
|
const fakeFetch = Fetch({
|
||||||
'https://auth.api/': {
|
'https://auth.api/': {
|
||||||
response: JSONResponse({
|
response: JSONResponse({
|
||||||
|
|
|
@ -73,6 +73,41 @@ export class ActivityPubAPI {
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async getActivityPubCollection<T>(collectionUrl: URL): Promise<T[]> {
|
||||||
|
const fetchPage = async (pageUrl: URL): Promise<T[]> => {
|
||||||
|
const json = await this.fetchJSON(pageUrl);
|
||||||
|
|
||||||
|
if (json === null) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
let items: T[] = [];
|
||||||
|
|
||||||
|
if ('orderedItems' in json) {
|
||||||
|
items = Array.isArray(json.orderedItems) ? json.orderedItems : [json.orderedItems];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('next' in json && typeof json.next === 'string') {
|
||||||
|
const nextPageUrl = new URL(json.next);
|
||||||
|
const nextPageItems = await fetchPage(nextPageUrl);
|
||||||
|
|
||||||
|
items = items.concat(nextPageItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
return items;
|
||||||
|
};
|
||||||
|
|
||||||
|
const initialJson = await this.fetchJSON(collectionUrl);
|
||||||
|
|
||||||
|
if (initialJson === null || !('first' in initialJson) || typeof initialJson.first !== 'string') {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const firstPageUrl = new URL(initialJson.first);
|
||||||
|
|
||||||
|
return fetchPage(firstPageUrl);
|
||||||
|
}
|
||||||
|
|
||||||
get inboxApiUrl() {
|
get inboxApiUrl() {
|
||||||
return new URL(`.ghost/activitypub/inbox/${this.handle}`, this.apiUrl);
|
return new URL(`.ghost/activitypub/inbox/${this.handle}`, this.apiUrl);
|
||||||
}
|
}
|
||||||
|
@ -96,38 +131,7 @@ export class ActivityPubAPI {
|
||||||
}
|
}
|
||||||
|
|
||||||
async getOutbox(): Promise<Activity[]> {
|
async getOutbox(): Promise<Activity[]> {
|
||||||
const fetchOutboxPage = async (url: URL): Promise<Activity[]> => {
|
return this.getActivityPubCollection<Activity>(this.outboxApiUrl);
|
||||||
const json = await this.fetchJSON(url);
|
|
||||||
|
|
||||||
if (json === null) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
let items: Activity[] = [];
|
|
||||||
|
|
||||||
if ('orderedItems' in json) {
|
|
||||||
items = Array.isArray(json.orderedItems) ? json.orderedItems : [json.orderedItems];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('next' in json && typeof json.next === 'string') {
|
|
||||||
const nextUrl = new URL(json.next);
|
|
||||||
const nextItems = await fetchOutboxPage(nextUrl);
|
|
||||||
|
|
||||||
items = items.concat(nextItems);
|
|
||||||
}
|
|
||||||
|
|
||||||
return items;
|
|
||||||
};
|
|
||||||
|
|
||||||
const initialJson = await this.fetchJSON(this.outboxApiUrl);
|
|
||||||
|
|
||||||
if (initialJson === null || !('first' in initialJson) || typeof initialJson.first !== 'string') {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const firstPageUrl = new URL(initialJson.first);
|
|
||||||
|
|
||||||
return fetchOutboxPage(firstPageUrl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get followingApiUrl() {
|
get followingApiUrl() {
|
||||||
|
@ -135,38 +139,7 @@ export class ActivityPubAPI {
|
||||||
}
|
}
|
||||||
|
|
||||||
async getFollowing(): Promise<Actor[]> {
|
async getFollowing(): Promise<Actor[]> {
|
||||||
const fetchFollowingPage = async (url: URL): Promise<Actor[]> => {
|
return this.getActivityPubCollection<Actor>(this.followingApiUrl);
|
||||||
const json = await this.fetchJSON(url);
|
|
||||||
|
|
||||||
if (json === null) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
let items: Actor[] = [];
|
|
||||||
|
|
||||||
if ('orderedItems' in json) {
|
|
||||||
items = Array.isArray(json.orderedItems) ? json.orderedItems : [json.orderedItems];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('next' in json && typeof json.next === 'string') {
|
|
||||||
const nextUrl = new URL(json.next);
|
|
||||||
const nextItems = await fetchFollowingPage(nextUrl);
|
|
||||||
|
|
||||||
items = items.concat(nextItems);
|
|
||||||
}
|
|
||||||
|
|
||||||
return items;
|
|
||||||
};
|
|
||||||
|
|
||||||
const initialJson = await this.fetchJSON(this.followingApiUrl);
|
|
||||||
|
|
||||||
if (initialJson === null || !('first' in initialJson) || typeof initialJson.first !== 'string') {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const firstPageUrl = new URL(initialJson.first);
|
|
||||||
|
|
||||||
return fetchFollowingPage(firstPageUrl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getFollowingCount(): Promise<number> {
|
async getFollowingCount(): Promise<number> {
|
||||||
|
@ -185,38 +158,7 @@ export class ActivityPubAPI {
|
||||||
}
|
}
|
||||||
|
|
||||||
async getFollowers(): Promise<Actor[]> {
|
async getFollowers(): Promise<Actor[]> {
|
||||||
const fetchFollowersPage = async (url: URL): Promise<Actor[]> => {
|
return this.getActivityPubCollection<Actor>(this.followersApiUrl);
|
||||||
const json = await this.fetchJSON(url);
|
|
||||||
|
|
||||||
if (json === null) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
let items: Actor[] = [];
|
|
||||||
|
|
||||||
if ('orderedItems' in json) {
|
|
||||||
items = Array.isArray(json.orderedItems) ? json.orderedItems : [json.orderedItems];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('next' in json && typeof json.next === 'string') {
|
|
||||||
const nextUrl = new URL(json.next);
|
|
||||||
const nextItems = await fetchFollowersPage(nextUrl);
|
|
||||||
|
|
||||||
items = items.concat(nextItems);
|
|
||||||
}
|
|
||||||
|
|
||||||
return items;
|
|
||||||
};
|
|
||||||
|
|
||||||
const initialJson = await this.fetchJSON(this.followersApiUrl);
|
|
||||||
|
|
||||||
if (initialJson === null || !('first' in initialJson) || typeof initialJson.first !== 'string') {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const firstPageUrl = new URL(initialJson.first);
|
|
||||||
|
|
||||||
return fetchFollowersPage(firstPageUrl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getFollowersCount(): Promise<number> {
|
async getFollowersCount(): Promise<number> {
|
||||||
|
@ -307,38 +249,7 @@ export class ActivityPubAPI {
|
||||||
}
|
}
|
||||||
|
|
||||||
async getLiked() {
|
async getLiked() {
|
||||||
const fetchLikedPage = async (url: URL): Promise<Activity[]> => {
|
return this.getActivityPubCollection<Activity>(this.likedApiUrl);
|
||||||
const json = await this.fetchJSON(url);
|
|
||||||
|
|
||||||
if (json === null) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
let items: Activity[] = [];
|
|
||||||
|
|
||||||
if ('orderedItems' in json) {
|
|
||||||
items = Array.isArray(json.orderedItems) ? json.orderedItems : [json.orderedItems];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('next' in json && typeof json.next === 'string') {
|
|
||||||
const nextUrl = new URL(json.next);
|
|
||||||
const nextItems = await fetchLikedPage(nextUrl);
|
|
||||||
|
|
||||||
items = items.concat(nextItems);
|
|
||||||
}
|
|
||||||
|
|
||||||
return items;
|
|
||||||
};
|
|
||||||
|
|
||||||
const initialJson = await this.fetchJSON(this.likedApiUrl);
|
|
||||||
|
|
||||||
if (initialJson === null || !('first' in initialJson) || typeof initialJson.first !== 'string') {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const firstPageUrl = new URL(initialJson.first);
|
|
||||||
|
|
||||||
return fetchLikedPage(firstPageUrl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async like(id: string): Promise<void> {
|
async like(id: string): Promise<void> {
|
||||||
|
|
Loading…
Add table
Reference in a new issue