Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 39 additions & 14 deletions packages/hypergraph/src/space/find-many-public.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const spaceFields = `
type
page {
name
relationsList(filter: {
avatarRelations: relationsList(filter: {
typeId: { is: "${ContentIds.AVATAR_PROPERTY}"}
}) {
toEntity {
Expand All @@ -22,6 +22,18 @@ const spaceFields = `
}
}
}
coverRelations: relationsList(filter: {
typeId: { is: "${SystemIds.COVER_PROPERTY}"}
}) {
toEntity {
valuesList(filter: {
propertyId: { is: "${SystemIds.IMAGE_URL_PROPERTY}"}
}) {
propertyId
text
}
}
}
}
editorsList {
memberSpaceId
Expand All @@ -40,26 +52,30 @@ export const PublicSpaceSchema = EffectSchema.Struct({
type: SpaceTypeSchema,
name: EffectSchema.String,
avatar: EffectSchema.optional(EffectSchema.String),
cover: EffectSchema.optional(EffectSchema.String),
editorIds: EffectSchema.Array(EffectSchema.String),
memberIds: EffectSchema.Array(EffectSchema.String),
});

export type PublicSpace = typeof PublicSpaceSchema.Type;

type RelationEntry = {
toEntity?: {
valuesList?: {
propertyId: string;
text: string | null;
}[];
} | null;
};

type SpacesQueryResult = {
spaces?: {
id: string;
type: 'PERSONAL' | 'DAO';
page: {
name?: string | null;
relationsList?: {
toEntity?: {
valuesList?: {
propertyId: string;
text: string | null;
}[];
} | null;
}[];
avatarRelations?: RelationEntry[];
coverRelations?: RelationEntry[];
} | null;
editorsList?: {
memberSpaceId: string;
Expand All @@ -74,16 +90,24 @@ type SpaceQueryEntry = NonNullable<SpacesQueryResult['spaces']>[number];

const decodeSpace = EffectSchema.decodeUnknownEither(PublicSpaceSchema);

const getAvatarFromSpace = (space: SpaceQueryEntry) => {
const firstRelation = space.page?.relationsList?.[0];
const getImageFromRelations = (relations?: RelationEntry[]) => {
const firstRelation = relations?.[0];
const firstValue = firstRelation?.toEntity?.valuesList?.[0];
const avatar = firstValue?.text;
if (typeof avatar === 'string') {
return avatar;
const url = firstValue?.text;
if (typeof url === 'string') {
return url;
}
return undefined;
};

const getAvatarFromSpace = (space: SpaceQueryEntry) => {
return getImageFromRelations(space.page?.avatarRelations);
};

const getCoverFromSpace = (space: SpaceQueryEntry) => {
return getImageFromRelations(space.page?.coverRelations);
};

const getEditorIdsFromSpace = (space: SpaceQueryEntry): string[] => {
return (space.editorsList ?? []).map((e) => e.memberSpaceId).filter((id): id is string => typeof id === 'string');
};
Expand All @@ -103,6 +127,7 @@ export const parseSpacesQueryResult = (queryResult: SpacesQueryResult) => {
type: space.type,
name: space.page?.name ?? undefined,
avatar: getAvatarFromSpace(space),
cover: getCoverFromSpace(space),
editorIds: getEditorIdsFromSpace(space),
memberIds: getMemberIdsFromSpace(space),
};
Expand Down
73 changes: 55 additions & 18 deletions packages/hypergraph/test/space/find-many-public.test.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,36 @@
import { describe, expect, it } from 'vitest';
import { buildFilterString, buildSpacesQuery, parseSpacesQueryResult } from '../../src/space/find-many-public.js';

const buildImageRelation = (url: string | null) => [
{
toEntity: {
valuesList:
url === null
? []
: [
{
propertyId: '8a743832c0944a62b6650c3cc2f9c7bc',
text: url,
},
],
},
},
];

const buildQuerySpace = ({
id = 'space-id',
type = 'PERSONAL',
name = 'Space name',
avatar,
cover,
editorsList = [],
membersList = [],
}: {
id?: string;
type?: 'PERSONAL' | 'DAO';
name?: string | null;
avatar?: string | null;
cover?: string | null;
editorsList?: { memberSpaceId: string }[];
membersList?: { memberSpaceId: string }[];
} = {}) => {
Expand All @@ -21,24 +39,8 @@ const buildQuerySpace = ({
type,
page: {
name,
relationsList:
avatar === undefined
? []
: [
{
toEntity: {
valuesList:
avatar === null
? []
: [
{
propertyId: '8a743832c0944a62b6650c3cc2f9c7bc',
text: avatar,
},
],
},
},
],
avatarRelations: avatar === undefined ? [] : buildImageRelation(avatar),
coverRelations: cover === undefined ? [] : buildImageRelation(cover),
},
editorsList,
membersList,
Expand All @@ -64,6 +66,39 @@ describe('parseSpacesQueryResult', () => {
expect(invalidSpaces).toHaveLength(0);
});

it('parses cover image', () => {
const { data } = parseSpacesQueryResult({
spaces: [
buildQuerySpace({
id: 'space-cover',
name: 'Space with cover',
avatar: 'https://example.com/avatar.png',
cover: 'https://example.com/cover.png',
}),
],
});

expect(data).toEqual([
{
id: 'space-cover',
type: 'PERSONAL',
name: 'Space with cover',
avatar: 'https://example.com/avatar.png',
cover: 'https://example.com/cover.png',
editorIds: [],
memberIds: [],
},
]);
});

it('omits cover when not provided', () => {
const { data } = parseSpacesQueryResult({
spaces: [buildQuerySpace({ id: 'space-no-cover', name: 'No cover' })],
});

expect(data[0]?.cover).toBeUndefined();
});

it('omits avatar when not provided', () => {
const { data } = parseSpacesQueryResult({
spaces: [buildQuerySpace({ id: 'space-2', name: 'Space 2', avatar: undefined })],
Expand Down Expand Up @@ -243,6 +278,8 @@ describe('buildSpacesQuery', () => {
expect(query).toContain('id');
expect(query).toContain('type');
expect(query).toContain('page {');
expect(query).toContain('avatarRelations:');
expect(query).toContain('coverRelations:');
expect(query).toContain('editorsList {');
expect(query).toContain('membersList {');
});
Expand Down
Loading