JSPM

@el_saintt/adapter-nextjs

1.0.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 6
  • Score
    100M100P100Q104886F
  • License MIT

Next.js adapter for @el_saintt/core - App Router and Pages Router support

Package Exports

  • @el_saintt/adapter-nextjs
  • @el_saintt/adapter-nextjs/app
  • @el_saintt/adapter-nextjs/pages

Readme

@el_saintt/adapter-nextjs

Next.js adapter for Portfolio API - Supports both App Router (Next.js 13+) and Pages Router.

Installation

npm install @el_saintt/adapter-nextjs @el_saintt/core next

Quick Start

App Router (Next.js 13+)

Create a catch-all route handler in app/api/portfolio/[[...slug]]/route.ts:

import { PortfolioClient } from '@el_saintt/core';
import { githubPlugin } from '@el_saintt/plugin-github';
import { createPortfolioHandlers } from '@el_saintt/adapter-nextjs/app';
import { NextRequest } from 'next/server';

// Initialize client
const client = new PortfolioClient({
  cache: {
    provider: 'memory',
    defaultTTL: 3600,
  },
  services: {
    github: {
      enabled: true,
      credentials: {
        username: process.env.GITHUB_USERNAME!,
      },
    },
  },
});

// Register plugins
client.use(githubPlugin);

// Create handlers
const handlers = createPortfolioHandlers({
  client,
  enableCors: true,
});

// Export route handlers
export async function GET(
  request: NextRequest,
  context: { params: { slug?: string[] } }
) {
  const slug = context.params.slug || [];

  // Route to appropriate handler
  if (slug[0] === 'services') {
    if (!slug[1]) {
      return handlers.getServices(request);
    } else if (slug[2] === 'health') {
      return handlers.getServiceHealth(request, { params: { service: slug[1] } });
    } else {
      return handlers.getService(request, { params: { service: slug[1] } });
    }
  } else if (slug[0] === 'content') {
    if (!slug[1]) {
      return handlers.getAllContent(request);
    } else {
      return handlers.getServiceContent(request, { params: { service: slug[1] } });
    }
  } else if (slug[0] === 'health') {
    return handlers.getHealth(request);
  } else if (slug[0] === 'validate') {
    return handlers.validateConfig(request);
  }

  return new Response(JSON.stringify({ error: 'Not found' }), {
    status: 404,
    headers: { 'Content-Type': 'application/json' },
  });
}

// Handle OPTIONS for CORS
export async function OPTIONS(request: NextRequest) {
  return new Response(null, {
    status: 204,
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
      'Access-Control-Allow-Headers': 'Content-Type, Authorization',
    },
  });
}

Pages Router

Create a catch-all API route in pages/api/portfolio/[[...slug]].ts:

import { PortfolioClient } from '@el_saintt/core';
import { githubPlugin } from '@el_saintt/plugin-github';
import { createPortfolioApiRoute } from '@el_saintt/adapter-nextjs/pages';

// Initialize client
const client = new PortfolioClient({
  cache: {
    provider: 'memory',
    defaultTTL: 3600,
  },
  services: {
    github: {
      enabled: true,
      credentials: {
        username: process.env.GITHUB_USERNAME!,
      },
    },
  },
});

// Register plugins
client.use(githubPlugin);

// Create and export handler
export default createPortfolioApiRoute({
  client,
  enableCors: true,
});

API Endpoints

Both routers create the same REST API endpoints:

Services

GET /api/portfolio/services

  • List all configured services
  • Response: { success: true, data: { services: [...] } }

GET /api/portfolio/services/:service

  • Get information about a specific service
  • Example: /api/portfolio/services/github

GET /api/portfolio/services/:service/health

  • Check health of a specific service
  • Example: /api/portfolio/services/github/health

Content

GET /api/portfolio/content

  • Get all content from all services
  • Query params: limit, offset, since, until, skipCache

GET /api/portfolio/content/:service

  • Get content from a specific service
  • Example: /api/portfolio/content/github?limit=5

Health & Validation

GET /api/portfolio/health

  • Check health of all services

GET /api/portfolio/validate

  • Validate configuration

Advanced Usage

Enable CORS

// App Router
const handlers = createPortfolioHandlers({
  client,
  enableCors: true,
  corsOrigins: ['https://example.com'], // Or ['*'] for all origins
});

// Pages Router
export default createPortfolioApiRoute({
  client,
  enableCors: true,
  corsOrigins: ['https://example.com'],
});

Server-Side Data Fetching

App Router (Server Components)

import { PortfolioClient } from '@el_saintt/core';
import { githubPlugin } from '@el_saintt/plugin-github';

// In a Server Component
export default async function Page() {
  const client = new PortfolioClient({ /* config */ });
  client.use(githubPlugin);

  const content = await client.fetch('github', { limit: 5 });

  return (
    <div>
      {content.map(item => (
        <div key={item.id}>{item.title}</div>
      ))}
    </div>
  );
}

Pages Router (getServerSideProps)

import { GetServerSideProps } from 'next';
import { PortfolioClient } from '@el_saintt/core';
import { githubPlugin } from '@el_saintt/plugin-github';

export const getServerSideProps: GetServerSideProps = async () => {
  const client = new PortfolioClient({ /* config */ });
  client.use(githubPlugin);

  const content = await client.fetch('github', { limit: 5 });

  return {
    props: {
      content,
    },
  };
};

Pages Router (getStaticProps)

import { GetStaticProps } from 'next';
import { PortfolioClient } from '@el_saintt/core';
import { githubPlugin } from '@el_saintt/plugin-github';

export const getStaticProps: GetStaticProps = async () => {
  const client = new PortfolioClient({ /* config */ });
  client.use(githubPlugin);

  const content = await client.fetch('github', { limit: 5 });

  return {
    props: {
      content,
    },
    revalidate: 3600, // ISR: revalidate every hour
  };
};

Response Format

All responses follow a consistent format:

Success Response

{
  "success": true,
  "data": { ... },
  "meta": {
    "timestamp": "2024-10-10T12:00:00.000Z",
    "count": 10,
    "service": "github"
  }
}

Error Response

{
  "success": false,
  "error": {
    "message": "Service not found",
    "code": "SERVICE_NOT_FOUND",
    "details": { ... }
  },
  "meta": {
    "timestamp": "2024-10-10T12:00:00.000Z"
  }
}

TypeScript Support

Full TypeScript support with proper types:

import {
  PortfolioResponse,
  PortfolioAPIOptions,
  createPortfolioHandlers,
} from '@el_saintt/adapter-nextjs';

// All exports are fully typed

Environment Variables

# Example .env.local
GITHUB_USERNAME=your-username
GITHUB_TOKEN=ghp_your_token_here

MEDIUM_USERNAME=@your-username

YOUTUBE_API_KEY=AIza_your_api_key
YOUTUBE_CHANNEL_ID=UC_your_channel_id

Examples

License

MIT