Migrate to typescript
This commit is contained in:
@ -1,3 +1,4 @@
|
||||
dist
|
||||
node_modules
|
||||
.github
|
||||
.github
|
||||
types.generated.d.ts
|
@ -3,7 +3,7 @@
|
||||
<img src="lighthouse-score.png" align="right"
|
||||
alt="AstroWind Lighthouse Score" width="100" height="358">
|
||||
|
||||
**AstroWind** is a free and open-source template to make your website using **[Astro](https://astro.build/) + [Tailwind CSS](https://tailwindcss.com/)**. Ready to start a new project and designed taking into account best practices. 🌟 **Most *starred* & *forked* Astro theme in 2022**.
|
||||
**AstroWind** is a free and open-source template to make your website using **[Astro](https://astro.build/) + [Tailwind CSS](https://tailwindcss.com/)**. Ready to start a new project and designed taking into account best practices. 🌟 **Most _starred_ & _forked_ Astro theme in 2022**.
|
||||
|
||||
## Features
|
||||
|
||||
@ -88,7 +88,7 @@ Inside AstroWind template, you'll see the following folders and files:
|
||||
│ | | ├── post-slug-1.md
|
||||
│ | | ├── post-slug-2.mdx
|
||||
│ | | └── ...
|
||||
│ | └-- config.js
|
||||
│ | └-- config.ts
|
||||
│ ├── layouts/
|
||||
│ | |── BaseLayout.astro
|
||||
│ | └── ...
|
||||
@ -104,7 +104,7 @@ Inside AstroWind template, you'll see the following folders and files:
|
||||
| | | └── [...page].astro
|
||||
│ | ├── index.astro
|
||||
| | ├── 404.astro
|
||||
| | └-- rss.xml.js
|
||||
| | └-- rss.xml.ts
|
||||
│ ├── utils/
|
||||
│ └── config.mjs
|
||||
├── package.json
|
||||
|
@ -17,10 +17,9 @@
|
||||
}
|
||||
|
||||
.dropdown:hover .dropdown-menu {
|
||||
display: block;
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
[astro-icon].icon-light > * {
|
||||
stroke-width: 1.2;
|
||||
}
|
||||
@ -34,4 +33,4 @@
|
||||
|
||||
[data-aw-toggle-menu].expanded g > path:last-child {
|
||||
@apply rotate-45 translate-y-[-8px] translate-x-[14px];
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,14 @@
|
||||
---
|
||||
import { Icon } from 'astro-icon';
|
||||
import { getRelativeLink } from '~/utils/permalinks';
|
||||
|
||||
export interface Props {
|
||||
prevUrl: string;
|
||||
nextUrl: string;
|
||||
prevText?: string;
|
||||
nextText?: string;
|
||||
}
|
||||
|
||||
const { prevUrl, nextUrl, prevText = 'Newer posts', nextText = 'Older posts' } = Astro.props;
|
||||
---
|
||||
|
||||
@ -18,12 +26,7 @@ const { prevUrl, nextUrl, prevText = 'Newer posts', nextText = 'Older posts' } =
|
||||
<p class="ml-2">{prevText}</p>
|
||||
</div>
|
||||
</a>
|
||||
<a
|
||||
href={getRelativeLink(nextUrl)}
|
||||
class={`btn btn-ghost px-3 ${
|
||||
!nextUrl ? 'invisible' : ''
|
||||
}`}
|
||||
>
|
||||
<a href={getRelativeLink(nextUrl)} class={`btn btn-ghost px-3 ${!nextUrl ? 'invisible' : ''}`}>
|
||||
<div class="flex flex-row align-middle">
|
||||
<span class="mr-2">{nextText}</span>
|
||||
<Icon name="tabler:arrow-right" class="w-6 h-6" />
|
||||
|
@ -1,5 +1,12 @@
|
||||
---
|
||||
import { Icon } from 'astro-icon';
|
||||
|
||||
export interface Props {
|
||||
text: string;
|
||||
url: string;
|
||||
class?: string;
|
||||
}
|
||||
|
||||
const { text, url, class: className = 'inline-block' } = Astro.props;
|
||||
---
|
||||
|
||||
|
@ -1,6 +1,13 @@
|
||||
---
|
||||
import { getPermalink } from '~/utils/permalinks';
|
||||
|
||||
import type { Post } from '~/utils/posts';
|
||||
|
||||
export interface Props {
|
||||
tags: Post['tags'];
|
||||
class?: string;
|
||||
}
|
||||
|
||||
const { tags, class: className = 'text-sm' } = Astro.props;
|
||||
---
|
||||
|
||||
|
@ -1,5 +1,10 @@
|
||||
---
|
||||
import Item from '~/components/blog/GridItem.astro';
|
||||
import type { Post } from '~/utils/posts';
|
||||
|
||||
export interface Props {
|
||||
posts: Array<Post>;
|
||||
}
|
||||
|
||||
const { posts } = Astro.props;
|
||||
---
|
||||
|
@ -1,11 +1,16 @@
|
||||
---
|
||||
import { Picture } from '@astrojs/image/components'
|
||||
import { Picture } from '@astrojs/image/components';
|
||||
|
||||
import { findImage } from '~/utils/images';
|
||||
import { getPermalink } from '~/utils/permalinks';
|
||||
|
||||
const { post } = Astro.props;
|
||||
import type { Post } from '~/utils/posts';
|
||||
|
||||
export interface Props {
|
||||
post: Post;
|
||||
}
|
||||
|
||||
const { post } = Astro.props;
|
||||
const image = await findImage(post.image);
|
||||
---
|
||||
|
||||
|
@ -1,5 +1,10 @@
|
||||
---
|
||||
import Item from '~/components/blog/ListItem.astro';
|
||||
import type { Post } from '~/utils/posts';
|
||||
|
||||
export interface Props {
|
||||
posts: Array<Post>;
|
||||
}
|
||||
|
||||
const { posts } = Astro.props;
|
||||
---
|
||||
|
@ -6,8 +6,13 @@ import { getPermalink } from '~/utils/permalinks';
|
||||
import { findImage } from '~/utils/images';
|
||||
import { getFormattedDate } from '~/utils/utils';
|
||||
|
||||
const { post } = Astro.props;
|
||||
import type { Post } from '~/utils/posts';
|
||||
|
||||
export interface Props {
|
||||
post: Post;
|
||||
}
|
||||
|
||||
const { post } = Astro.props;
|
||||
const image = await findImage(post.image);
|
||||
---
|
||||
|
||||
@ -47,7 +52,7 @@ const image = await findImage(post.image);
|
||||
<footer class="mt-4">
|
||||
<div>
|
||||
<span class="text-gray-500 dark:text-slate-400">
|
||||
<time datetime={post.publishDate}>{getFormattedDate(post.publishDate)}</time> ~
|
||||
<time datetime={String(post.publishDate)}>{getFormattedDate(post.publishDate)}</time> ~
|
||||
{Math.ceil(post.readingTime)} min read
|
||||
</span>
|
||||
</div>
|
||||
|
@ -1,10 +1,17 @@
|
||||
---
|
||||
import { Picture } from '@astrojs/image/components'
|
||||
import { Picture } from '@astrojs/image/components';
|
||||
import PostTags from '~/components/atoms/Tags.astro';
|
||||
import SocialShare from '~/components/atoms/SocialShare.astro';
|
||||
|
||||
import { getFormattedDate } from '~/utils/utils';
|
||||
|
||||
import type { Post } from '~/utils/posts';
|
||||
|
||||
export interface Props {
|
||||
post: Post;
|
||||
url: string;
|
||||
}
|
||||
|
||||
const { post, url } = Astro.props;
|
||||
---
|
||||
|
||||
@ -12,8 +19,9 @@ const { post, url } = Astro.props;
|
||||
<article>
|
||||
<header class={post.image ? 'text-center' : ''}>
|
||||
<p class="px-4 sm:px-6 max-w-3xl mx-auto">
|
||||
<time datetime={post.publishDate}>{getFormattedDate(post.publishDate)}</time> ~ {Math.ceil(post.readingTime)} min
|
||||
read
|
||||
<time datetime={String(post.publishDate)}>{getFormattedDate(post.publishDate)}</time> ~ {
|
||||
Math.ceil(post.readingTime)
|
||||
} min read
|
||||
</p>
|
||||
<h1
|
||||
class="px-4 sm:px-6 max-w-3xl mx-auto text-4xl md:text-5xl font-bold leading-tighter tracking-tighter mb-8 font-heading"
|
||||
@ -27,9 +35,9 @@ const { post, url } = Astro.props;
|
||||
class="max-w-full lg:max-w-6xl mx-auto mt-4 mb-6 sm:rounded-md bg-gray-400 dark:bg-slate-700"
|
||||
widths={[400, 900]}
|
||||
sizes="(max-width: 900px) 400px, 900px"
|
||||
alt={post.description}
|
||||
alt={post.description || ''}
|
||||
loading="eager"
|
||||
aspectRatio={16/9}
|
||||
aspectRatio={16 / 9}
|
||||
width={900}
|
||||
height={506}
|
||||
/>
|
||||
@ -43,15 +51,20 @@ const { post, url } = Astro.props;
|
||||
<div
|
||||
class="container mx-auto px-6 sm:px-6 max-w-3xl prose prose-lg lg:prose-xl dark:prose-invert dark:prose-headings:text-slate-300 prose-md prose-headings:font-heading prose-headings:leading-tighter prose-headings:tracking-tighter prose-headings:font-bold prose-a:text-primary-600 dark:prose-a:text-primary-400 prose-img:rounded-md prose-img:shadow-lg mt-8"
|
||||
>
|
||||
{post.Content ? <post.Content /> : <Fragment set:html={post.body} />}
|
||||
{
|
||||
post.Content ? (
|
||||
<>
|
||||
{/* @ts-ignore */}
|
||||
<post.Content />
|
||||
</>
|
||||
) : (
|
||||
<Fragment set:html={post.content} />
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<div class="container mx-auto px-6 sm:px-6 max-w-3xl mt-8 flex justify-between flex-col sm:flex-row">
|
||||
<PostTags tags={post.tags} class="mr-5" />
|
||||
<SocialShare
|
||||
url={url}
|
||||
text={post.title}
|
||||
class="mt-5 sm:mt-1 align-middle text-gray-500 dark:text-slate-600"
|
||||
/>
|
||||
<SocialShare url={url} text={post.title} class="mt-5 sm:mt-1 align-middle text-gray-500 dark:text-slate-600" />
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
|
@ -1,6 +1,13 @@
|
||||
---
|
||||
import { Icon } from 'astro-icon';
|
||||
|
||||
export interface Props {
|
||||
label?: string;
|
||||
class?: string;
|
||||
iconClass?: string;
|
||||
iconName?: string;
|
||||
}
|
||||
|
||||
const {
|
||||
label = 'Toggle Menu',
|
||||
class:
|
||||
|
@ -1,6 +1,13 @@
|
||||
---
|
||||
import { Icon } from 'astro-icon';
|
||||
|
||||
export interface Props {
|
||||
label?: string;
|
||||
class?: string;
|
||||
iconClass?: string;
|
||||
iconName?: string;
|
||||
}
|
||||
|
||||
const {
|
||||
label = 'Toggle between Dark and Light mode',
|
||||
class:
|
||||
|
@ -13,12 +13,7 @@ import { getHomePermalink } from '~/utils/permalinks';
|
||||
<p class="mt-4 mb-8 text-lg text-gray-600 dark:text-slate-400">
|
||||
But dont worry, you can find plenty of other things on our homepage.
|
||||
</p>
|
||||
<a
|
||||
rel="noopener noreferrer"
|
||||
href={getHomePermalink()}
|
||||
class="btn ml-4"
|
||||
>Back to homepage</a
|
||||
>
|
||||
<a rel="noopener noreferrer" href={getHomePermalink()} class="btn ml-4">Back to homepage</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
@ -37,16 +37,19 @@ import { getHomePermalink, getBlogPermalink, getPermalink, getRelativeLink } fro
|
||||
<li class="">
|
||||
<a
|
||||
class="rounded-t md:hover:bg-gray-100 dark:hover:bg-gray-700 py-2 px-4 block whitespace-no-wrap"
|
||||
href="#">Features</a>
|
||||
href="#">Features</a
|
||||
>
|
||||
</li>
|
||||
<li class="">
|
||||
<a class="md:hover:bg-gray-100 dark:hover:bg-gray-700 py-2 px-4 block whitespace-no-wrap" href="#"
|
||||
>Profile</a>
|
||||
>Profile</a
|
||||
>
|
||||
</li>
|
||||
<li class="">
|
||||
<a
|
||||
class="rounded-b md:hover:bg-gray-100 dark:hover:bg-gray-700 py-2 px-4 block whitespace-no-wrap"
|
||||
href="#">Pricing</a>
|
||||
href="#">Pricing</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
import { Icon } from 'astro-icon';
|
||||
import { Picture } from '@astrojs/image/components'
|
||||
import { Picture } from '@astrojs/image/components';
|
||||
---
|
||||
|
||||
<section>
|
||||
@ -10,16 +10,15 @@ import { Picture } from '@astrojs/image/components'
|
||||
<h1 class="text-5xl md:text-[3.50rem] font-bold leading-tighter tracking-tighter mb-4 font-heading">
|
||||
Your website with
|
||||
<span>Astro</span> +
|
||||
<span
|
||||
class="sm:whitespace-nowrap"
|
||||
>Tailwind CSS</span
|
||||
>
|
||||
<span class="sm:whitespace-nowrap">Tailwind CSS</span>
|
||||
</h1>
|
||||
<div class="max-w-3xl mx-auto">
|
||||
<p class="text-xl text-gray-600 mb-8 dark:text-slate-400">
|
||||
<span class="font-semibold underline decoration-wavy decoration-1 decoration-primary-600 underline-offset-2">AstroWind</span> is a production ready template to start your new website using <em>Astro</em> + <em>Tailwind CSS</em>. It has been
|
||||
designed following Best Practices, SEO, Accessibility, <span class="inline sm:hidden">...</span><span
|
||||
class="hidden sm:inline"
|
||||
<span class="font-semibold underline decoration-wavy decoration-1 decoration-primary-600 underline-offset-2"
|
||||
>AstroWind</span
|
||||
> is a production ready template to start your new website using <em>Astro</em> + <em>Tailwind CSS</em>. It
|
||||
has been designed following Best Practices, SEO, Accessibility, <span class="inline sm:hidden">...</span
|
||||
><span class="hidden sm:inline"
|
||||
>Dark Mode, Great Page Speed, image optimization, sitemap generation and more.</span
|
||||
>
|
||||
</p>
|
||||
@ -35,10 +34,7 @@ import { Picture } from '@astrojs/image/components'
|
||||
</a>
|
||||
</div>
|
||||
<div class="flex w-full sm:w-auto">
|
||||
<a
|
||||
class="btn w-full"
|
||||
href="#features">Learn more</a
|
||||
>
|
||||
<a class="btn w-full" href="#features">Learn more</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -51,7 +47,7 @@ import { Picture } from '@astrojs/image/components'
|
||||
widths={[400, 768, 1480]}
|
||||
sizes="(max-width: 767px) 400px, (max-width: 1479px) 768px, 1480px"
|
||||
alt="Hero Image"
|
||||
aspectRatio={1480/833}
|
||||
aspectRatio={1480 / 833}
|
||||
loading="eager"
|
||||
width={1480}
|
||||
height={833}
|
||||
|
@ -4,7 +4,8 @@ import { Icon } from 'astro-icon';
|
||||
|
||||
<section class="bg-primary-100 dark:bg-slate-800">
|
||||
<div class="max-w-6xl mx-auto px-4 sm:px-6 py-4 text-md text-center font-medium">
|
||||
<span class="font-bold"> <Icon name="tabler:info-square" class="w-5 h-5 inline-block align-text-bottom" /> Philosophy:</span> Simplicity, Best
|
||||
Practices and High Performance
|
||||
<span class="font-bold">
|
||||
<Icon name="tabler:info-square" class="w-5 h-5 inline-block align-text-bottom" /> Philosophy:</span
|
||||
> Simplicity, Best Practices and High Performance
|
||||
</div>
|
||||
</section>
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
import { Icon } from 'astro-icon';
|
||||
import { Picture } from '@astrojs/image/components'
|
||||
import { Picture } from '@astrojs/image/components';
|
||||
---
|
||||
|
||||
<section class="px-4 py-16 sm:px-6 mx-auto lg:px-8 lg:py-20 max-w-6xl">
|
||||
@ -64,7 +64,9 @@ import { Picture } from '@astrojs/image/components'
|
||||
<div class="flex">
|
||||
<div class="flex flex-col items-center mr-4">
|
||||
<div>
|
||||
<div class="flex items-center justify-center w-10 h-10 rounded-full border-primary-600 border-2 bg-primary-600">
|
||||
<div
|
||||
class="flex items-center justify-center w-10 h-10 rounded-full border-primary-600 border-2 bg-primary-600"
|
||||
>
|
||||
<Icon name="tabler:check" class="w-6 h-6 text-white dark:text-slate-200" />
|
||||
</div>
|
||||
</div>
|
||||
|
1
src/env.d.ts
vendored
Normal file
1
src/env.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
/// <reference types="astro/client" />
|
@ -18,7 +18,7 @@ export async function getStaticPaths({ paginate }) {
|
||||
typeof post.category === 'string' && categories.add(post.category.toLowerCase());
|
||||
});
|
||||
|
||||
return Array.from(categories).map((category) =>
|
||||
return Array.from(categories).map((category: string) =>
|
||||
paginate(
|
||||
posts.filter((post) => typeof post.category === 'string' && category === post.category.toLowerCase()),
|
||||
{
|
||||
|
@ -18,7 +18,7 @@ export async function getStaticPaths({ paginate }) {
|
||||
Array.isArray(post.tags) && post.tags.map((tag) => tags.add(tag.toLowerCase()));
|
||||
});
|
||||
|
||||
return Array.from(tags).map((tag) =>
|
||||
return Array.from(tags).map((tag: string) =>
|
||||
paginate(
|
||||
posts.filter((post) => Array.isArray(post.tags) && post.tags.find((elem) => elem.toLowerCase() === tag)),
|
||||
{
|
||||
|
@ -4,7 +4,7 @@ import { fileURLToPath } from 'url';
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
/** */
|
||||
export const getProjectRootDir = () => {
|
||||
export const getProjectRootDir = (): string => {
|
||||
const mode = import.meta.env.MODE;
|
||||
|
||||
return mode === 'production' ? path.join(__dirname, '../') : path.join(__dirname, '../../');
|
||||
@ -13,10 +13,6 @@ export const getProjectRootDir = () => {
|
||||
const __srcFolder = path.join(getProjectRootDir(), '/src');
|
||||
|
||||
/** */
|
||||
export const getRelativeUrlByFilePath = (filepath) => {
|
||||
if (filepath) {
|
||||
return filepath.replace(__srcFolder, '');
|
||||
}
|
||||
|
||||
return null;
|
||||
export const getRelativeUrlByFilePath = (filepath: string): string | URL => {
|
||||
return filepath.replace(__srcFolder, '');
|
||||
};
|
@ -1,5 +1,5 @@
|
||||
const load = async function () {
|
||||
let images = [];
|
||||
let images: Record<string, () => Promise<unknown>> | undefined = undefined;
|
||||
try {
|
||||
images = import.meta.glob('~/assets/images/**');
|
||||
} catch (e) {
|
||||
@ -17,7 +17,7 @@ export const fetchLocalImages = async () => {
|
||||
};
|
||||
|
||||
/** */
|
||||
export const findImage = async (imagePath) => {
|
||||
export const findImage = async (imagePath?: string) => {
|
||||
if (typeof imagePath !== 'string') {
|
||||
return null;
|
||||
}
|
@ -2,7 +2,7 @@ import slugify from 'limax';
|
||||
|
||||
import { SITE, BLOG } from '~/config.mjs';
|
||||
|
||||
const trim = (str = "", ch) => {
|
||||
const trim = (str = '', ch?: string) => {
|
||||
let start = 0,
|
||||
end = str.length || 0;
|
||||
while (start < end && str[start] === ch) ++start;
|
||||
@ -18,7 +18,7 @@ const createPath = (...params) => {
|
||||
|
||||
const basePathname = trimSlash(SITE.basePathname);
|
||||
|
||||
export const cleanSlug = (text) => slugify(trimSlash(text));
|
||||
export const cleanSlug = (text: string) => slugify(trimSlash(text));
|
||||
|
||||
export const BLOG_BASE = cleanSlug(BLOG?.blog?.pathname);
|
||||
export const POST_BASE = cleanSlug(BLOG?.post?.pathname);
|
||||
@ -29,7 +29,7 @@ export const TAG_BASE = cleanSlug(BLOG?.tag?.pathname);
|
||||
export const getCanonical = (path = '') => new URL(path, SITE.origin);
|
||||
|
||||
/** */
|
||||
export const getPermalink = (slug = '', type = 'page') => {
|
||||
export const getPermalink = (slug = '', type = 'page'): string => {
|
||||
const _slug = cleanSlug(slug);
|
||||
|
||||
switch (type) {
|
||||
@ -49,15 +49,15 @@ export const getPermalink = (slug = '', type = 'page') => {
|
||||
};
|
||||
|
||||
/** */
|
||||
export const getHomePermalink = () => {
|
||||
export const getHomePermalink = (): string => {
|
||||
const permalink = getPermalink();
|
||||
return permalink !== '/' ? permalink + '/' : permalink;
|
||||
};
|
||||
|
||||
/** */
|
||||
export const getRelativeLink = (link = "") => {
|
||||
export const getRelativeLink = (link = ''): string => {
|
||||
return createPath(basePathname, trimSlash(link));
|
||||
}
|
||||
};
|
||||
|
||||
/** */
|
||||
export const getBlogPermalink = () => getPermalink(BLOG_BASE);
|
||||
export const getBlogPermalink = (): string => getPermalink(BLOG_BASE);
|
@ -1,6 +1,32 @@
|
||||
import { getCollection, getEntry } from 'astro:content';
|
||||
import type { CollectionEntry } from 'astro:content';
|
||||
|
||||
const getNormalizedPost = async (post) => {
|
||||
export interface Post {
|
||||
id: string;
|
||||
slug: string;
|
||||
|
||||
publishDate: Date;
|
||||
title: string;
|
||||
description?: string;
|
||||
|
||||
image?: string;
|
||||
|
||||
canonical?: string;
|
||||
permalink?: string;
|
||||
|
||||
draft?: boolean;
|
||||
|
||||
excerpt?: string;
|
||||
category?: string;
|
||||
tags?: Array<string>;
|
||||
authors?: Array<string>;
|
||||
|
||||
Content: unknown;
|
||||
content?: string;
|
||||
readingTime: number;
|
||||
}
|
||||
|
||||
const getNormalizedPost = async (post: CollectionEntry<'blog'>): Promise<Post> => {
|
||||
const { id, slug, data } = post;
|
||||
const { Content, injectedFrontmatter } = await post.render();
|
||||
|
||||
@ -16,7 +42,7 @@ const getNormalizedPost = async (post) => {
|
||||
};
|
||||
};
|
||||
|
||||
const load = async function () {
|
||||
const load = async function (): Promise<Array<Post>> {
|
||||
const posts = await getCollection('blog');
|
||||
const normalizedPosts = posts.map(async (post) => await getNormalizedPost(post));
|
||||
|
||||
@ -27,23 +53,25 @@ const load = async function () {
|
||||
return results;
|
||||
};
|
||||
|
||||
let _posts;
|
||||
let _posts: Array<Post>;
|
||||
|
||||
/** */
|
||||
export const fetchPosts = async () => {
|
||||
_posts = _posts || load();
|
||||
export const fetchPosts = async (): Promise<Array<Post>> => {
|
||||
if (!_posts) {
|
||||
_posts = await load();
|
||||
}
|
||||
|
||||
return await _posts;
|
||||
return _posts;
|
||||
};
|
||||
|
||||
/** */
|
||||
export const findPostsBySlugs = async (slugs) => {
|
||||
export const findPostsBySlugs = async (slugs: Array<string>): Promise<Array<Post>> => {
|
||||
if (!Array.isArray(slugs)) return [];
|
||||
|
||||
const posts = await fetchPosts();
|
||||
|
||||
return slugs.reduce(function (r, slug) {
|
||||
posts.some(function (post) {
|
||||
return slugs.reduce(function (r: Array<Post>, slug: string) {
|
||||
posts.some(function (post: Post) {
|
||||
return slug === post.slug && r.push(post);
|
||||
});
|
||||
return r;
|
||||
@ -51,11 +79,11 @@ export const findPostsBySlugs = async (slugs) => {
|
||||
};
|
||||
|
||||
/** */
|
||||
export const findPostsByIds = async (ids) => {
|
||||
export const findPostsByIds = async (ids: Array<string>): Promise<Array<Post>> => {
|
||||
if (!Array.isArray(ids)) return [];
|
||||
|
||||
return await Promise.all(
|
||||
ids.map(async (id) => {
|
||||
ids.map(async (id: never) => {
|
||||
const post = await getEntry('blog', id);
|
||||
return await getNormalizedPost(post);
|
||||
})
|
||||
@ -63,7 +91,7 @@ export const findPostsByIds = async (ids) => {
|
||||
};
|
||||
|
||||
/** */
|
||||
export const findLatestPosts = async ({ count }) => {
|
||||
export const findLatestPosts = async ({ count }: { count?: number }): Promise<Array<Post>> => {
|
||||
const _count = count || 4;
|
||||
const posts = await fetchPosts();
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* eslint-disable no-mixed-spaces-and-tabs */
|
||||
/** */
|
||||
export const getFormattedDate = (date) =>
|
||||
date
|
||||
@ -6,4 +7,4 @@ export const getFormattedDate = (date) =>
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
})
|
||||
: '';
|
||||
: '';
|
Reference in New Issue
Block a user