Skip to content

Commit 5f33206

Browse files
authored
fix: improve schemas for item_packed.thumbnails and search hits (#1869)
* fix: improve schemas for item_packed.thumbnails and search hits * fix: update sdk * fix: use uri format for thumbnails url
1 parent f57b2e4 commit 5f33206

11 files changed

Lines changed: 73 additions & 53 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
"@fastify/type-provider-typebox": "5.1.0",
6363
"@fastify/websocket": "11.0.2",
6464
"@graasp/etherpad-api": "2.1.1",
65-
"@graasp/sdk": "5.13.0",
65+
"@graasp/sdk": "5.13.2",
6666
"@graasp/translations": "1.44.0",
6767
"@rapideditor/country-coder": "5.4.0",
6868
"@sentry/node": "7.119.2",

src/services/item/item.schemas.packed.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export const packedItemSchemaRef = registerSchemaAsRef(
2020
id: customType.UUID(),
2121
name: Type.String(),
2222
description: Type.Optional(customType.Nullable(Type.String())),
23-
type: Type.String(),
23+
type: customType.EnumString(Object.values(ItemType)),
2424
path: Type.String(),
2525
lang: Type.String(),
2626
extra: Type.Object({}, { additionalProperties: true }),
@@ -31,7 +31,15 @@ export const packedItemSchemaRef = registerSchemaAsRef(
3131
permission: customType.Nullable(customType.EnumString(Object.values(PermissionLevel))),
3232
hidden: Type.Optional(itemVisibilitySchemaRef),
3333
public: Type.Optional(itemVisibilitySchemaRef),
34-
thumbnails: Type.Optional(Type.Object({}, { additionalProperties: true })),
34+
thumbnails: Type.Optional(
35+
customType.StrictObject(
36+
{
37+
small: Type.String({ format: 'uri' }),
38+
medium: Type.String({ format: 'uri' }),
39+
},
40+
{ additionalProperties: true },
41+
),
42+
),
3543
},
3644
{
3745
description: 'Item with additional information',

src/services/item/plugins/importExport/test/index.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,7 @@ describe('ZIP routes tests', () => {
477477

478478
// Check that all the item properties have been assigned for the file type
479479
const fileItemProperties = fileItem.extra[ItemType.FILE] as FileItemProperties;
480+
480481
expect(fileItemProperties).toBeDefined();
481482
expect(fileItemProperties.name).toEqual(pdfName);
482483
expect(fileItemProperties.path).toBeDefined();

src/services/item/plugins/publication/published/plugins/search/meilisearch.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,14 @@ import {
1010
} from 'meilisearch';
1111
import { singleton } from 'tsyringe';
1212

13-
import { IndexItem, ItemType, ItemVisibilityType, MimeTypes, TagCategory } from '@graasp/sdk';
13+
import {
14+
IndexItem,
15+
ItemType,
16+
ItemVisibilityType,
17+
MimeTypes,
18+
TagCategory,
19+
TagCategoryType,
20+
} from '@graasp/sdk';
1421

1522
import { DBConnection, db } from '../../../../../../../drizzle/db';
1623
import { items } from '../../../../../../../drizzle/schema';
@@ -199,7 +206,7 @@ export class MeiliSearchWrapper {
199206
Object.values(TagCategory).map((c) => {
200207
return [c, tags.filter(({ category }) => category === c).map(({ name }) => name)];
201208
}),
202-
) as { [key in TagCategory]: string[] };
209+
) as { [key in TagCategoryType]: string[] };
203210

204211
return {
205212
id: item.id,

src/services/item/plugins/publication/published/plugins/search/search.schemas.ts

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,37 @@ import { FastifySchema } from 'fastify';
55

66
import { ItemType, TagCategory } from '@graasp/sdk';
77

8-
import { customType } from '../../../../../../../plugins/typebox';
8+
import { customType, registerSchemaAsRef } from '../../../../../../../plugins/typebox';
99
import { errorSchemaRef } from '../../../../../../../schemas/global';
1010
import {
1111
GET_MOST_LIKED_ITEMS_MAXIMUM,
1212
GET_MOST_RECENT_ITEMS_MAXIMUM,
1313
} from '../../../../../../../utils/config';
1414

15-
const meilisearchSearchResponseSchema = customType.StrictObject({
16-
totalHits: Type.Optional(Type.Number()),
17-
estimatedTotalHits: Type.Optional(Type.Number()),
18-
processingTimeMs: Type.Number(),
19-
query: Type.String(),
20-
hits: Type.Array(
21-
customType.StrictObject({
15+
const meilisearchHitRef = registerSchemaAsRef(
16+
'searchHit',
17+
'Search Hit',
18+
customType.StrictObject({
19+
name: Type.String(),
20+
description: Type.String(),
21+
content: Type.String(),
22+
creator: customType.StrictObject({
23+
id: customType.UUID(),
24+
name: Type.String(),
25+
}),
26+
level: Type.Array(Type.String()),
27+
discipline: Type.Array(Type.String()),
28+
'resource-type': Type.Array(Type.String()),
29+
id: customType.UUID(),
30+
type: Type.Enum(ItemType),
31+
isPublishedRoot: Type.Boolean(),
32+
isHidden: Type.Boolean(),
33+
createdAt: customType.DateTime(),
34+
updatedAt: customType.DateTime(),
35+
publicationUpdatedAt: customType.DateTime(),
36+
lang: Type.String(),
37+
likes: Type.Number(),
38+
_formatted: customType.StrictObject({
2239
name: Type.String(),
2340
description: Type.String(),
2441
content: Type.String(),
@@ -30,37 +47,24 @@ const meilisearchSearchResponseSchema = customType.StrictObject({
3047
discipline: Type.Array(Type.String()),
3148
'resource-type': Type.Array(Type.String()),
3249
id: customType.UUID(),
33-
type: Type.Enum(ItemType),
50+
type: Type.String(),
3451
isPublishedRoot: Type.Boolean(),
52+
publicationUpdatedAt: customType.DateTime(),
3553
isHidden: Type.Boolean(),
3654
createdAt: customType.DateTime(),
3755
updatedAt: customType.DateTime(),
38-
publicationUpdatedAt: customType.DateTime(),
3956
lang: Type.String(),
4057
likes: Type.Number(),
41-
_formatted: customType.StrictObject({
42-
name: Type.String(),
43-
description: Type.String(),
44-
content: Type.String(),
45-
creator: customType.StrictObject({
46-
id: customType.UUID(),
47-
name: Type.String(),
48-
}),
49-
level: Type.Array(Type.String()),
50-
discipline: Type.Array(Type.String()),
51-
'resource-type': Type.Array(Type.String()),
52-
id: customType.UUID(),
53-
type: Type.String(),
54-
isPublishedRoot: Type.Boolean(),
55-
publicationUpdatedAt: customType.DateTime(),
56-
isHidden: Type.Boolean(),
57-
createdAt: customType.DateTime(),
58-
updatedAt: customType.DateTime(),
59-
lang: Type.String(),
60-
likes: Type.Number(),
61-
}),
6258
}),
63-
),
59+
}),
60+
);
61+
62+
const meilisearchSearchResponseSchema = customType.StrictObject({
63+
totalHits: Type.Optional(Type.Number()),
64+
estimatedTotalHits: Type.Optional(Type.Number()),
65+
processingTimeMs: Type.Number(),
66+
query: Type.String(),
67+
hits: Type.Array(meilisearchHitRef),
6468
});
6569

6670
export const search = {

src/services/item/plugins/publication/published/plugins/search/search.service.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { MultiSearchQuery } from 'meilisearch';
22
import { singleton } from 'tsyringe';
33

4-
import { TagCategory, UUID } from '@graasp/sdk';
4+
import { TagCategory, TagCategoryType, UUID } from '@graasp/sdk';
55

66
import { TagRaw } from '../../../../../../../drizzle/types';
77
import { BaseLogger } from '../../../../../../../logger';
@@ -15,7 +15,7 @@ import { MeiliSearchWrapper } from './meilisearch';
1515

1616
type SearchFilters = Partial<{
1717
query?: string;
18-
tags: Partial<{ [key in TagCategory]: TagRaw['name'][] }>;
18+
tags: Partial<{ [key in TagCategoryType]: TagRaw['name'][] }>;
1919
langs: string[];
2020
isPublishedRoot: boolean;
2121
creatorId?: UUID;

src/services/item/plugins/tag/ItemTag.repository.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { and, eq } from 'drizzle-orm/sql';
22
import { v4 } from 'uuid';
33

4-
import { FolderItemFactory, TagCategory } from '@graasp/sdk';
4+
import { FolderItemFactory, TagCategory, TagCategoryType } from '@graasp/sdk';
55

66
import { seedFromJson } from '../../../../../test/mocks/seed';
77
import { db } from '../../../../drizzle/db';
@@ -18,7 +18,7 @@ jest.retryTimes(3, { logErrorsBeforeRetry: true });
1818

1919
const repository = new ItemTagRepository();
2020

21-
async function saveTag(t: { name?: string; category: TagCategory }) {
21+
async function saveTag(t: { name?: string; category: TagCategoryType }) {
2222
const {
2323
tags: [tag],
2424
} = await seedFromJson({ actor: null, tags: [t] });

src/services/item/plugins/tag/itemTag.service.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { singleton } from 'tsyringe';
22

3-
import { PermissionLevel, TagCategory, UUID } from '@graasp/sdk';
3+
import { PermissionLevel, TagCategoryType, UUID } from '@graasp/sdk';
44

55
import { type DBConnection } from '../../../../drizzle/db';
66
import { AuthenticatedUser, MaybeUser } from '../../../../types';
@@ -36,7 +36,7 @@ export class ItemTagService {
3636
dbConnection: DBConnection,
3737
authenticatedUser: AuthenticatedUser,
3838
itemId: UUID,
39-
tagInfo: { name: string; category: TagCategory },
39+
tagInfo: { name: string; category: TagCategoryType },
4040
) {
4141
// Get item and check permission
4242
const item = await this.basicItemService.get(

src/services/tag/tag.repository.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { and, eq } from 'drizzle-orm/sql';
22
import { v4 } from 'uuid';
33

4-
import { TagCategory, TagFactory } from '@graasp/sdk';
4+
import { TagCategory, TagCategoryType, TagFactory } from '@graasp/sdk';
55

66
import { seedFromJson } from '../../../test/mocks/seed';
77
import { db } from '../../drizzle/db';
@@ -92,7 +92,7 @@ describe('Tag Repository', () => {
9292

9393
const result = await repository.addOneIfDoesNotExist(db, {
9494
name: tag.name,
95-
category: tag.category as TagCategory,
95+
category: tag.category as TagCategoryType,
9696
});
9797

9898
expect(result.id).toEqual(tag.id);

src/services/tag/tag.repository.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { and, eq } from 'drizzle-orm/sql';
22
import { singleton } from 'tsyringe';
33

4-
import { TagCategory } from '@graasp/sdk';
4+
import { TagCategoryType } from '@graasp/sdk';
55

66
import { DBConnection } from '../../drizzle/db';
77
import { tagsTable } from '../../drizzle/schema';
@@ -25,7 +25,7 @@ export class TagRepository {
2525

2626
async addOne(
2727
dbConnection: DBConnection,
28-
tag: { name: string; category: TagCategory },
28+
tag: { name: string; category: TagCategoryType },
2929
): Promise<TagRaw> {
3030
const createdTag = await dbConnection
3131
.insert(tagsTable)
@@ -39,7 +39,7 @@ export class TagRepository {
3939

4040
async addOneIfDoesNotExist(
4141
dbConnection: DBConnection,
42-
tagInfo: { name: string; category: TagCategory },
42+
tagInfo: { name: string; category: TagCategoryType },
4343
): Promise<TagRaw> {
4444
const tag = await dbConnection.query.tagsTable.findFirst({
4545
where: and(

0 commit comments

Comments
 (0)