diff --git a/web/server/api/backgrounds.ts b/web/server/api/backgrounds.ts index be9f6aa..7bee5e8 100644 --- a/web/server/api/backgrounds.ts +++ b/web/server/api/backgrounds.ts @@ -1,6 +1,6 @@ import {type ShortBackgroundData} from '#shared/types/backgroundTypes' import {makeSlugLink} from '~~/shared/utils/links' -import {getItemsCount} from '../utils/getCount' +import {fetchAllPaginated} from '../utils/fetchAllPaginated' type DirectusBackground = { id: number @@ -14,44 +14,17 @@ type DirectusBackground = { } | null } -export default defineEventHandler(async (): Promise => { - const {staticToken, backendAddress} = useRuntimeConfig() - const itemsCount = await getItemsCount(`${backendAddress}/items/backgrounds`) - - const itemsPerPage = 100 - let totalItems: ShortBackgroundData[] = [] - for (let page = 0; page < itemsCount / itemsPerPage; page += 1) { - const {data: backgrounds} = await $fetch<{data: DirectusBackground[]}>( - `${backendAddress}/items/backgrounds`, - { - headers: { - Authorization: `Bearer ${staticToken}`, - }, - query: { - fields: [ - 'id', - 'title', - 'original_title', - 'abilities', - 'skills', - 'source.title', - 'source.description', - ].join(','), - sort: 'title', - offset: itemsPerPage * page, - }, - } - ) - totalItems = totalItems.concat( - backgrounds.map( - (f) => - ({ - ...f, - slug: `${makeSlugLink({id: f.id, originalTitle: f.original_title})}`, - }) satisfies ShortBackgroundData - ) - ) - } - - return totalItems -}) +export default defineEventHandler(() => + fetchAllPaginated('backgrounds', [ + 'id', + 'title', + 'original_title', + 'abilities', + 'skills', + 'source.title', + 'source.description', + ], (b) => ({ + ...b, + slug: makeSlugLink({id: b.id, originalTitle: b.original_title}), + })) +) diff --git a/web/server/api/facilities.ts b/web/server/api/facilities.ts index e514708..7a15073 100644 --- a/web/server/api/facilities.ts +++ b/web/server/api/facilities.ts @@ -1,6 +1,6 @@ import {type ShortFacilityData} from '#shared/types/facilityTypes' import {makeSlugLink} from '~~/shared/utils/links' -import {getItemsCount} from '../utils/getCount' +import {fetchAllPaginated} from '../utils/fetchAllPaginated' type DirectusFacility = { id: number @@ -15,45 +15,18 @@ type DirectusFacility = { size: string } -export default defineEventHandler(async (): Promise => { - const {staticToken, backendAddress} = useRuntimeConfig() - const itemsCount = await getItemsCount(`${backendAddress}/items/facilities`) - - const itemsPerPage = 100 - let totalItems: ShortFacilityData[] = [] - for (let page = 0; page < itemsCount / itemsPerPage; page += 1) { - const {data: items} = await $fetch<{data: DirectusFacility[]}>( - `${backendAddress}/items/facilities`, - { - headers: { - Authorization: `Bearer ${staticToken}`, - }, - query: { - fields: [ - 'id', - 'title', - 'original_title', - 'source.title', - 'source.description', - 'level', - 'order', - 'size', - ].join(','), - sort: 'title', - offset: itemsPerPage * page, - }, - } - ) - totalItems = totalItems.concat( - items.map( - (f) => - ({ - ...f, - slug: `${makeSlugLink({id: f.id, originalTitle: f.original_title})}`, - }) satisfies ShortFacilityData - ) - ) - } - - return totalItems -}) +export default defineEventHandler(() => + fetchAllPaginated('facilities', [ + 'id', + 'title', + 'original_title', + 'source.title', + 'source.description', + 'level', + 'order', + 'size', + ], (f) => ({ + ...f, + slug: makeSlugLink({id: f.id, originalTitle: f.original_title}), + })) +) diff --git a/web/server/api/feats.ts b/web/server/api/feats.ts index 195639a..38aea28 100644 --- a/web/server/api/feats.ts +++ b/web/server/api/feats.ts @@ -1,6 +1,6 @@ import {type ShortFeatData} from '#shared/types/featTypes' import {makeSlugLink} from '~~/shared/utils/links' -import {getItemsCount} from '../utils/getCount' +import {fetchAllPaginated} from '../utils/fetchAllPaginated' type DirectusFeat = { id: number @@ -13,43 +13,16 @@ type DirectusFeat = { } | null } -export default defineEventHandler(async (): Promise => { - const {staticToken, backendAddress} = useRuntimeConfig() - const itemsCount = await getItemsCount(`${backendAddress}/items/feats`) - - const itemsPerPage = 100 - let totalItems: ShortFeatData[] = [] - for (let page = 0; page < itemsCount / itemsPerPage; page += 1) { - const {data: feats} = await $fetch<{data: DirectusFeat[]}>( - `${backendAddress}/items/feats`, - { - headers: { - Authorization: `Bearer ${staticToken}`, - }, - query: { - fields: [ - 'id', - 'title', - 'original_title', - 'source.title', - 'source.description', - 'category', - ].join(','), - sort: 'title', - offset: itemsPerPage * page, - }, - } - ) - totalItems = totalItems.concat( - feats.map( - (f) => - ({ - ...f, - slug: `${makeSlugLink({id: f.id, originalTitle: f.original_title})}`, - }) satisfies ShortFeatData - ) - ) - } - - return totalItems -}) +export default defineEventHandler(() => + fetchAllPaginated('feats', [ + 'id', + 'title', + 'original_title', + 'source.title', + 'source.description', + 'category', + ], (f) => ({ + ...f, + slug: makeSlugLink({id: f.id, originalTitle: f.original_title}), + })) +) diff --git a/web/server/api/magic-items.ts b/web/server/api/magic-items.ts index b3e7b56..2e86e8d 100644 --- a/web/server/api/magic-items.ts +++ b/web/server/api/magic-items.ts @@ -3,6 +3,8 @@ import { type ItemRarity, type ShortMagicItemData, } from '#shared/types/magicItemTypes' +import {makeSlugLink} from '~~/shared/utils/links' +import {fetchAllPaginated} from '../utils/fetchAllPaginated' type DirectusMagicItem = { id: number @@ -17,51 +19,24 @@ type DirectusMagicItem = { } | null } -export default defineEventHandler(async (): Promise => { - const {staticToken, backendAddress} = useRuntimeConfig() - const itemsCount = await getItemsCount(`${backendAddress}/items/magic_items`) - - const itemsPerPage = 100 - let totalItems: ShortMagicItemData[] = [] - for (let page = 0; page < itemsCount / itemsPerPage; page += 1) { - const {data: items} = await $fetch<{data: DirectusMagicItem[]}>( - `${backendAddress}/items/magic_items`, - { - headers: { - Authorization: `Bearer ${staticToken}`, - }, - query: { - fields: [ - 'id', - 'title', - 'original_title', - 'category', - 'rarity', - 'attunement', - 'source.title', - 'source.description', - ].join(','), - sort: 'title', - offset: itemsPerPage * page, - }, - } - ) - totalItems = totalItems.concat( - items.map( - (f) => - ({ - id: f.id, - title: f.title, - originalTitle: f.original_title, - category: f.category, - rarity: f.rarity, - attunement: f.attunement, - source: f.source, - slug: `${makeSlugLink({id: f.id, originalTitle: f.original_title})}`, - }) satisfies ShortMagicItemData - ) - ) - } - - return totalItems -}) +export default defineEventHandler(() => + fetchAllPaginated('magic_items', [ + 'id', + 'title', + 'original_title', + 'category', + 'rarity', + 'attunement', + 'source.title', + 'source.description', + ], (f) => ({ + id: f.id, + title: f.title, + originalTitle: f.original_title, + category: f.category, + rarity: f.rarity, + attunement: f.attunement, + source: f.source, + slug: makeSlugLink({id: f.id, originalTitle: f.original_title}), + })) +) diff --git a/web/server/api/spell-cards.ts b/web/server/api/spell-cards.ts index 6526397..ec7b3ef 100644 --- a/web/server/api/spell-cards.ts +++ b/web/server/api/spell-cards.ts @@ -4,7 +4,7 @@ import {createDirectives, presetDirectiveConfigs} from 'marked-directive' import {type SpellData} from '#shared/types/spellTypes' import {createSbHeaderDirective, sbStatsDirective} from '#shared/utils/markdown' -import {getItemsCount} from '../utils/getCount' +import {fetchAllPaginated} from '../utils/fetchAllPaginated' type DirectusSpell = { id: number @@ -30,41 +30,25 @@ type DirectusSpell = { export default defineCachedEventHandler( async (): Promise => { - const {staticToken, backendAddress} = useRuntimeConfig() - const itemsCount = await getItemsCount(`${backendAddress}/items/spells`) - - const itemsPerPage = 100 - let totalItems: DirectusSpell[] = [] - for (let page = 0; page < itemsCount / itemsPerPage; page += 1) { - const {data: spells} = await $fetch<{data: DirectusSpell[]}>( - `${backendAddress}/items/spells`, - { - headers: { - Authorization: `Bearer ${staticToken}`, - }, - query: { - fields: [ - 'id', - 'title', - 'original_title', - 'level', - 'school', - 'casting_time', - 'range', - 'components', - 'duration', - 'description', - 'classes.classes_id.title', - 'source.title', - 'source.description', - ].join(','), - sort: 'title', - offset: itemsPerPage * page, - }, - } - ) - totalItems = totalItems.concat(spells) - } + const spells = await fetchAllPaginated( + 'spells', + [ + 'id', + 'title', + 'original_title', + 'level', + 'school', + 'casting_time', + 'range', + 'components', + 'duration', + 'description', + 'classes.classes_id.title', + 'source.title', + 'source.description', + ], + (s) => s, + ) const marked = new Marked( createDirectives([ @@ -99,7 +83,7 @@ export default defineCachedEventHandler( }) return Promise.all( - totalItems.map( + spells.map( async (s): Promise => ({ id: s.id, title: s.title, diff --git a/web/server/api/spells.ts b/web/server/api/spells.ts index 2c30331..1252ed2 100644 --- a/web/server/api/spells.ts +++ b/web/server/api/spells.ts @@ -1,5 +1,6 @@ import {type ShortSpellData} from '#shared/types/spellTypes' -import {getItemsCount} from '../utils/getCount' +import {makeSlugLink} from '~~/shared/utils/links' +import {fetchAllPaginated} from '../utils/fetchAllPaginated' type DirectusSpell = { id: number @@ -18,39 +19,17 @@ type DirectusSpell = { } | null } -export default defineEventHandler(async (): Promise => { - const {staticToken, backendAddress} = useRuntimeConfig() - const itemsCount = await getItemsCount(`${backendAddress}/items/spells`) - - const itemsPerPage = 100 - let totalItems: DirectusSpell[] = [] - for (let page = 0; page < itemsCount / itemsPerPage; page += 1) { - const {data: spells} = await $fetch<{data: DirectusSpell[]}>( - `${backendAddress}/items/spells`, - { - headers: { - Authorization: `Bearer ${staticToken}`, - }, - query: { - fields: [ - 'id', - 'title', - 'original_title', - 'level', - 'school', - 'classes.classes_id.title', - 'source.title', - 'source.description', - ].join(','), - sort: 'title', - offset: itemsPerPage * page, - }, - } - ) - totalItems = totalItems.concat(spells) - } - - return totalItems.map((s) => ({ +export default defineEventHandler(() => + fetchAllPaginated('spells', [ + 'id', + 'title', + 'original_title', + 'level', + 'school', + 'classes.classes_id.title', + 'source.title', + 'source.description', + ], (s) => ({ id: s.id, title: s.title, original_title: s.original_title, @@ -60,4 +39,4 @@ export default defineEventHandler(async (): Promise => { source: s.source, slug: makeSlugLink({id: s.id, originalTitle: s.original_title}), })) -}) +) diff --git a/web/server/utils/fetchAllPaginated.ts b/web/server/utils/fetchAllPaginated.ts new file mode 100644 index 0000000..3c1f51a --- /dev/null +++ b/web/server/utils/fetchAllPaginated.ts @@ -0,0 +1,30 @@ +import {getItemsCount} from './getCount' + +export async function fetchAllPaginated( + endpoint: string, + fields: string[], + mapper: (item: DirectusT) => ApiT, + sort = 'title', +): Promise { + const {staticToken, backendAddress} = useRuntimeConfig() + const url = `${backendAddress}/items/${endpoint}` + const count = await getItemsCount(url) + + const itemsPerPage = 100 + const pages = Math.ceil(count / itemsPerPage) + + const results = await Promise.all( + Array.from({length: pages}, (_, page) => + $fetch<{data: DirectusT[]}>(url, { + headers: {Authorization: `Bearer ${staticToken}`}, + query: { + fields: fields.join(','), + sort, + offset: page * itemsPerPage, + }, + }) + ) + ) + + return results.flatMap((r) => r.data.map(mapper)) +}