astro-loader-hashnode
Version:
Astro content loader for seamlessly integrating Hashnode blog posts into your Astro website using the Content Layer API
167 lines (166 loc) • 4.04 kB
TypeScript
/**
* Hashnode API Client - Clean wrapper around Hashnode GraphQL API
*/
import type { HashnodePost, HashnodeSeries, HashnodePublication } from '../types/hashnode.js';
export interface HashnodeClientOptions {
/**
* Hashnode publication host (e.g., 'blog.example.com')
*/
publicationHost: string;
/**
* Optional API token for private content access
*/
token?: string;
/**
* Custom GraphQL endpoint (defaults to Hashnode's public API)
*/
endpoint?: string;
/**
* Request timeout in milliseconds
*/
timeout?: number;
/**
* Enable request caching
*/
cache?: boolean;
/**
* Custom cache TTL in seconds
*/
cacheTTL?: number;
}
export interface GraphQLResponse<T = unknown> {
data?: T;
errors?: Array<{
message: string;
locations?: Array<{
line: number;
column: number;
}>;
path?: Array<string | number>;
}>;
}
export interface PaginationInfo {
hasNextPage: boolean;
endCursor?: string;
}
export interface PostsResponse {
publication: {
id: string;
title: string;
url: string;
posts: {
pageInfo: PaginationInfo;
edges: Array<{
node: HashnodePost;
cursor?: string;
}>;
};
};
}
export interface SeriesResponse {
publication: {
id: string;
series: {
pageInfo: PaginationInfo;
edges: Array<{
node: HashnodeSeries;
}>;
};
};
}
export interface SearchResponse {
searchPostsOfPublication: {
edges: Array<{
cursor: string;
node: HashnodePost;
}>;
pageInfo: PaginationInfo;
};
}
/**
* Hashnode API Client
*
* Provides a clean, typed wrapper around the Hashnode GraphQL API
*/
export declare class HashnodeClient {
private readonly endpoint;
private readonly publicationHost;
private readonly token?;
private readonly timeout;
private readonly cache?;
private readonly cacheTTL;
constructor(options: HashnodeClientOptions);
/**
* Execute a GraphQL query
*/
query<T = unknown>(query: string, variables?: Record<string, unknown>): Promise<T>;
/**
* Get posts from the publication
*/
getPosts(options?: {
first?: number;
after?: string;
includeComments?: boolean;
includeCoAuthors?: boolean;
includeTableOfContents?: boolean;
}): Promise<PostsResponse>;
/**
* Get a single post by slug
*/
getPost(slug: string, options?: {
includeComments?: boolean;
includeCoAuthors?: boolean;
}): Promise<HashnodePost | null>;
/**
* Search posts in the publication
*/
searchPosts(searchTerm: string, options?: {
first?: number;
after?: string;
}): Promise<SearchResponse>;
/**
* Get publication information
*/
getPublication(): Promise<HashnodePublication>;
/**
* Get posts by tag
*/
getPostsByTag(tagSlug: string, options?: {
first?: number;
after?: string;
}): Promise<PostsResponse>;
/**
* Get draft posts (requires authentication)
*/
getDrafts(options?: {
first?: number;
}): Promise<{
me: {
drafts: {
edges: Array<{
node: HashnodePost;
}>;
};
};
}>;
/**
* Get a specific draft by ID (requires authentication)
*/
getDraft(id: string): Promise<HashnodePost | null>;
/**
* Clear the request cache
*/
clearCache(): void;
/**
* Generate cache key for request
*/
private getCacheKey;
/**
* Simple hash function for cache keys
*/
private simpleHash;
}
/**
* Create a new Hashnode API client
*/
export declare function createHashnodeClient(options: HashnodeClientOptions): HashnodeClient;