Skip to content

Commit

Permalink
split up astro utils
Browse files Browse the repository at this point in the history
  • Loading branch information
kremalicious committed Sep 14, 2023
1 parent 23a76c2 commit 5c1b37c
Show file tree
Hide file tree
Showing 10 changed files with 189 additions and 166 deletions.
165 changes: 0 additions & 165 deletions src/lib/astro.ts

This file was deleted.

3 changes: 2 additions & 1 deletion src/lib/astro.test.ts → src/lib/astro/astro.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { test, expect } from 'vitest'
import { sortPosts, getPostsByTag, getAllTags } from './astro'
import { getPostsByTag, getAllTags } from '.'
import { sortPosts } from './sortPosts'

test('sortPosts sorts posts by date in descending order', () => {
const posts = [
Expand Down
14 changes: 14 additions & 0 deletions src/lib/astro/getAllPosts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { sortPosts } from './sortPosts'
import { loadAndFormatCollection } from './loadAndFormatCollection'
import type { CollectionEntry } from 'astro:content'

export async function getAllPosts(): Promise<
CollectionEntry<'articles' | 'links' | 'photos'>[]
> {
const articles = await loadAndFormatCollection('articles')
const links = await loadAndFormatCollection('links')
const photos = await loadAndFormatCollection('photos')

const allPosts = sortPosts([...articles, ...links, ...photos])
return allPosts
}
36 changes: 36 additions & 0 deletions src/lib/astro/getAllPostsForSearch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { type CollectionEntry } from 'astro:content'
import { getAllPosts } from '.'

// helps to reduce DOM size

export async function getAllPostsForSearch() {
const allPosts = await getAllPosts()

const cleaned = await Promise.all(
allPosts.map(async (post) => {
const imageSrc = (
post.data as CollectionEntry<'articles' | 'photos'>['data']
).image
// const image = imageSrc
// ? await getImage({
// src: imageSrc,
// width: 300,
// height: 100,
// format: 'png'
// })
// : null
return {
slug: post.slug,
data: {
title: post.data.title,
tags: post.data.tags,
collection: post.collection,
lead: post.body.substring(0, 200),
image: imageSrc
}
}
})
)

return cleaned
}
31 changes: 31 additions & 0 deletions src/lib/astro/getAllTags.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { type CollectionEntry } from 'astro:content'
import { slugifyAll } from '../slugify'

export type AllTags = {
name: string
count: number
}[]

export async function getAllTags(
posts: CollectionEntry<'articles' | 'links' | 'photos'>[]
): Promise<AllTags> {
const allTagsArray = posts
.filter((post) => post.data.tags)
.map((post) => post.data.tags)
.flat() as string[]
const allTagsArrayCleaned = slugifyAll(allTagsArray)

// Explicitly define the type of tagCounts
const tagCounts: Record<string, number> = {}

for (const tag of allTagsArrayCleaned) {
tagCounts[tag] = (tagCounts[tag] || 0) + 1
}

const allUniqueTags = Object.keys(tagCounts).map((tag) => ({
name: tag,
count: tagCounts[tag]
}))

return allUniqueTags
}
9 changes: 9 additions & 0 deletions src/lib/astro/getPostsByTag.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { type CollectionEntry } from 'astro:content'
import { slugifyAll } from '../slugify'

export function getPostsByTag(
posts: CollectionEntry<'articles' | 'links' | 'photos'>[],
tag: string
) {
return posts.filter((post) => slugifyAll(post.data.tags || []).includes(tag))
}
6 changes: 6 additions & 0 deletions src/lib/astro/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export { getAllPosts } from './getAllPosts'
export { getAllTags } from './getAllTags'
export { getPostsByTag } from './getPostsByTag'
export { loadAndFormatCollection } from './loadAndFormatCollection'
export { sortPosts } from './sortPosts'
export { getAllPostsForSearch } from './getAllPostsForSearch'
77 changes: 77 additions & 0 deletions src/lib/astro/loadAndFormatCollection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { getCollection, type CollectionEntry } from 'astro:content'
import { readOutExif } from '../exif'
import path from 'path'
import config from '@config/blog.config'
import { sortPosts } from './sortPosts'

//
// Main loader for all collections content.
// ---
// Astro's `getCollection()` is never called
// from components, but this helper method instead.
//

export async function loadAndFormatCollection(
name: 'articles' | 'links' | 'photos'
) {
let postsCollection = await getCollection(name)

// filter out drafts, but only in production
if (import.meta.env.PROD) {
postsCollection = postsCollection.filter(({ data }) => data.draft !== true)
}

for await (const post of postsCollection) {
// use date from frontmatter, or grab from folder path
const date = post.data.date
? post.data.date
: new Date(post.id.split('/')[0].substring(0, 10))

// remove date from slug
let slug = post.id.split('/')[0].substring(11) as CollectionEntry<
'articles' | 'photos' | 'links'
>['slug']

// links are not folders so remove .md from the end
if (post.collection === 'links') {
slug = slug.substring(
0,
slug.length - 3
) as CollectionEntry<'links'>['slug']
}

const githubLink = `${config.repoContentPath}/${post.collection}/${post.id}`

// extract exif & iptc data from photos
if (post.collection === 'photos') {
const isProd = import.meta.env.PROD

//
// Get the absolute image path from post.data.image
// to read exif from
//
// production image.src:
// `/_astro/filename.hash.jpg`
// development image.src:
// `/@fs/absolute/system/path/project/src/content/photos/postSlug/filename.jpg?origWidth=3873&origHeight=2796&origFormat=jpg`
//
const imagePath = isProd
? path.join(
'content',
'photos',
post.id.split('/')[0],
post.data.image.src.split('/')[2].split('.')[0].concat('.jpg')
)
: post.data.image.src.split('?')[0].split('/@fs')[1]
const exif = await readOutExif(imagePath)
post.data.exif = exif
}

post.slug = slug
post.data.date = date
post.data.githubLink = githubLink
}

const posts = sortPosts(postsCollection)
return posts
}
11 changes: 11 additions & 0 deletions src/lib/astro/sortPosts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { type CollectionEntry } from 'astro:content'

export function sortPosts(
posts: CollectionEntry<'articles' | 'links' | 'photos'>[]
): CollectionEntry<'articles' | 'links' | 'photos'>[] {
return posts.sort(
(a, b) =>
Math.floor(new Date(b.data.date as Date)?.getTime() / 1000) -
Math.floor(new Date(a.data.date as Date)?.getTime() / 1000)
)
}
3 changes: 3 additions & 0 deletions src/pages/tags/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,6 @@ const allTags = await getAllTags(allPosts)
}
</ul>
</LayoutBase>
@lib/astro/astro import {getAllPosts} from '@lib/astro/getAllPosts' import {
getAllTags
} from '@lib/astro/AllTags'

0 comments on commit 5c1b37c

Please sign in to comment.