From 3d2331d20b4f7ec07872dfc3d9c52b1d50285bc3 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Fri, 10 Mar 2023 13:36:00 -0600 Subject: [PATCH] Make useGroups hooks use zod parser, update group types --- .../__tests__/group-action-button.test.tsx | 8 +++--- app/soapbox/hooks/useGroups.ts | 26 ++++++++++++------- app/soapbox/normalizers/group.ts | 7 ++--- app/soapbox/normalizers/index.ts | 2 +- app/soapbox/schemas/index.ts | 3 +++ app/soapbox/types/entities.ts | 11 ++++---- 6 files changed, 34 insertions(+), 23 deletions(-) create mode 100644 app/soapbox/schemas/index.ts diff --git a/app/soapbox/features/group/components/__tests__/group-action-button.test.tsx b/app/soapbox/features/group/components/__tests__/group-action-button.test.tsx index eb2cf670b..e622c7247 100644 --- a/app/soapbox/features/group/components/__tests__/group-action-button.test.tsx +++ b/app/soapbox/features/group/components/__tests__/group-action-button.test.tsx @@ -18,7 +18,7 @@ describe('', () => { describe('with a private group', () => { beforeEach(() => { - group = group.set('locked', true); + group = { ...group, locked: true }; }); it('should render the Request Access button', () => { @@ -30,7 +30,7 @@ describe('', () => { describe('with a public group', () => { beforeEach(() => { - group = group.set('locked', false); + group = { ...group, locked: false }; }); it('should render the Join Group button', () => { @@ -52,7 +52,7 @@ describe('', () => { describe('with a private group', () => { beforeEach(() => { - group = group.set('locked', true); + group = { ...group, locked: true }; }); it('should render the Request Access button', () => { @@ -64,7 +64,7 @@ describe('', () => { describe('with a public group', () => { beforeEach(() => { - group = group.set('locked', false); + group = { ...group, locked: false }; }); it('should render the Join Group button', () => { diff --git a/app/soapbox/hooks/useGroups.ts b/app/soapbox/hooks/useGroups.ts index 1c48e1e38..65437675b 100644 --- a/app/soapbox/hooks/useGroups.ts +++ b/app/soapbox/hooks/useGroups.ts @@ -1,13 +1,12 @@ import { useEntities, useEntity } from 'soapbox/entity-store/hooks'; -import { normalizeGroup, normalizeGroupRelationship } from 'soapbox/normalizers'; - -import type { Group, GroupRelationship } from 'soapbox/types/entities'; +import { groupSchema, Group } from 'soapbox/schemas/group'; +import { groupRelationshipSchema, GroupRelationship } from 'soapbox/schemas/group-relationship'; function useGroups() { const { entities, ...result } = useEntities(['Group', ''], '/api/v1/groups', { parser: parseGroup }); const { relationships } = useGroupRelationships(entities.map(entity => entity.id)); - const groups = entities.map((group) => group.set('relationship', relationships[group.id] || null)); + const groups = entities.map((group) => ({ ...group, relationship: relationships[group.id] || null })); return { ...result, @@ -21,7 +20,7 @@ function useGroup(groupId: string, refetch = true) { return { ...result, - group: group?.set('relationship', relationship || null), + group: group ? { ...group, relationship: relationship || null } : undefined, }; } @@ -45,9 +44,18 @@ function useGroupRelationships(groupIds: string[]) { }; } -// HACK: normalizers currently don't have the desired API. -// TODO: rewrite normalizers as Zod parsers. -const parseGroup = (entity: unknown) => entity ? normalizeGroup(entity as Record) : undefined; -const parseGroupRelationship = (entity: unknown) => entity ? normalizeGroupRelationship(entity as Record) : undefined; +const parseGroup = (entity: unknown) => { + const result = groupSchema.safeParse(entity); + if (result.success) { + return result.data; + } +}; + +const parseGroupRelationship = (entity: unknown) => { + const result = groupRelationshipSchema.safeParse(entity); + if (result.success) { + return result.data; + } +}; export { useGroup, useGroups }; \ No newline at end of file diff --git a/app/soapbox/normalizers/group.ts b/app/soapbox/normalizers/group.ts index e4bf1df6b..e50cc9af3 100644 --- a/app/soapbox/normalizers/group.ts +++ b/app/soapbox/normalizers/group.ts @@ -23,13 +23,14 @@ export const GroupRecord = ImmutableRecord({ created_at: '', display_name: '', domain: '', - emojis: ImmutableList(), + emojis: [] as Emoji[], + group_visibility: '', header: '', header_static: '', id: '', locked: false, membership_required: false, - members_count: undefined as number | undefined, + members_count: 0, note: '', statuses_visibility: 'public', uri: '', @@ -69,7 +70,7 @@ const normalizeHeader = (group: ImmutableMap) => { /** Normalize emojis */ const normalizeEmojis = (entity: ImmutableMap) => { const emojis = entity.get('emojis', ImmutableList()).map(normalizeEmoji); - return entity.set('emojis', emojis); + return entity.set('emojis', emojis.toArray()); }; /** Set display name from username, if applicable */ diff --git a/app/soapbox/normalizers/index.ts b/app/soapbox/normalizers/index.ts index 66daaae27..004049988 100644 --- a/app/soapbox/normalizers/index.ts +++ b/app/soapbox/normalizers/index.ts @@ -12,7 +12,7 @@ export { EmojiReactionRecord } from './emoji-reaction'; export { FilterRecord, normalizeFilter } from './filter'; export { FilterKeywordRecord, normalizeFilterKeyword } from './filter-keyword'; export { FilterStatusRecord, normalizeFilterStatus } from './filter-status'; -export { GroupRecord, normalizeGroup } from './group'; +export { normalizeGroup } from './group'; export { GroupRelationshipRecord, normalizeGroupRelationship } from './group-relationship'; export { HistoryRecord, normalizeHistory } from './history'; export { InstanceRecord, normalizeInstance } from './instance'; diff --git a/app/soapbox/schemas/index.ts b/app/soapbox/schemas/index.ts new file mode 100644 index 000000000..e05df212a --- /dev/null +++ b/app/soapbox/schemas/index.ts @@ -0,0 +1,3 @@ +export { customEmojiSchema, CustomEmoji } from './custom-emoji'; +export { groupSchema, Group } from './group'; +export { groupRelationshipSchema, GroupRelationship } from './group-relationship'; \ No newline at end of file diff --git a/app/soapbox/types/entities.ts b/app/soapbox/types/entities.ts index bf717e805..61691a54a 100644 --- a/app/soapbox/types/entities.ts +++ b/app/soapbox/types/entities.ts @@ -14,8 +14,6 @@ import { FilterRecord, FilterKeywordRecord, FilterStatusRecord, - GroupRecord, - GroupRelationshipRecord, HistoryRecord, InstanceRecord, ListRecord, @@ -48,8 +46,6 @@ type Field = ReturnType; type Filter = ReturnType; type FilterKeyword = ReturnType; type FilterStatus = ReturnType; -type Group = ReturnType; -type GroupRelationship = ReturnType; type History = ReturnType; type Instance = ReturnType; type List = ReturnType; @@ -95,8 +91,6 @@ export { Filter, FilterKeyword, FilterStatus, - Group, - GroupRelationship, History, Instance, List, @@ -114,3 +108,8 @@ export { APIEntity, EmbeddedEntity, }; + +export type { + Group, + GroupRelationship, +} from 'soapbox/schemas'; \ No newline at end of file