@nehorai/credits-nextjs
v1.0.2
Published
Next.js adapter for the [`@nehorai/credits`](https://www.npmjs.com/package/@nehorai/credits) system. Provides NextAuth.js integration and a `withCredits` higher-order function for wrapping server actions with automatic credit handling.
Readme
@nehorai/credits-nextjs
Next.js adapter for the @nehorai/credits system. Provides NextAuth.js integration and a withCredits higher-order function for wrapping server actions with automatic credit handling.
Features
createWithCreditsHOF -- Wrap server actions with reserve-execute-commit credit flowNextAuthCreditsProvider-- Authenticate credit operations using NextAuth.js sessions- Deferred execution -- Background usage logging via Next.js
after()API - Preview mode support -- Skip credit checks in preview/draft mode
- Re-exports
@nehorai/credits-- All core types and utilities available from this package
Installation
pnpm add @nehorai/credits-nextjsPeer dependencies: next >= 14.0.0, next-auth >= 5.0.0-beta.0
Quick Start
1. Set up the auth provider
import { createNextAuthCreditsProvider } from "@nehorai/credits-nextjs";
import { getCurrentUser } from "@/lib/auth/session";
const authProvider = createNextAuthCreditsProvider({
getCurrentUser,
adminUsers: ["admin-user-id", "[email protected]"],
});2. Set up the deferred executor
import { createNextJsDeferredExecutor } from "@nehorai/credits-nextjs";
import { after } from "next/server";
const deferred = createNextJsDeferredExecutor(after);3. Create the withCredits wrapper
import { createWithCredits } from "@nehorai/credits-nextjs";
import { createFirestoreCreditRepository } from "@nehorai/credits-firestore";
import { getFirestore } from "firebase-admin/firestore";
const repository = createFirestoreCreditRepository(getFirestore());
const withCredits = createWithCredits({
repository,
authProvider,
deferred,
operationCosts: {
story_generation: 10,
image_generation: 10,
template_generation: 5,
},
});4. Wrap server actions
"use server";
export const generateStory = withCredits(
{ operationType: "story_generation" },
async (user, data, reservation) => {
const story = await generateStoryContent(data);
return { success: true, data: story };
}
);The wrapper automatically:
- Authenticates the user via NextAuth
- Reserves credits before execution
- On success: commits the reservation (deducts credits)
- On failure: releases the reservation (refunds credits)
- Logs usage in the background
API Reference
createWithCredits(config)
Creates a configured withCredits HOF.
const withCredits = createWithCredits({
repository: ICreditRepository, // Credit repository instance
authProvider: ICreditsAuthProvider, // Auth provider instance
deferred: DeferredExecutor, // Background task executor
operationCosts: Record<string, number>, // Cost per operation type
generateRequestId?: () => string, // Optional custom request ID generator
});withCredits(options, handler)
Wraps a server action with credit handling.
const action = withCredits<InputType, OutputType>(
{
operationType: "story_generation", // Matches key in operationCosts
customCost: 15, // Optional: override cost lookup
resourceId: "story-123", // Optional: for usage logging
resourceType: "story", // Optional: for usage logging
},
async (user, data, reservation) => {
// user: { id, email, name }
// data: InputType (passed by caller)
// reservation: PortableReservation (for reference)
return { success: true, data: result };
}
);createCreditsWrapperFactory(config)
Creates a factory for operation-specific wrappers with preset defaults:
const createWrapper = createCreditsWrapperFactory(config);
const withStoryCredits = createWrapper({ operationType: "story_generation" });
const withImageCredits = createWrapper({ operationType: "image_generation" });
// Usage
export const generateStory = withStoryCredits(async (user, data, reservation) => {
return { success: true, data: story };
});NextAuthCreditsProvider
Implements ICreditsAuthProvider for NextAuth.js:
import { NextAuthCreditsProvider } from "@nehorai/credits-nextjs";
const provider = new NextAuthCreditsProvider({
getCurrentUser: () => getServerSession().then(s => s?.user ?? null),
adminUsers: new Set(["admin-id"]), // Accepts Set<string> or string[]
});
const user = await provider.getCurrentUser();
const isAdmin = await provider.verifyAdminAccess(userId);createNextJsDeferredExecutor(afterFn)
Creates a DeferredExecutor using Next.js after():
import { after } from "next/server";
import { createNextJsDeferredExecutor } from "@nehorai/credits-nextjs";
const deferred = createNextJsDeferredExecutor(after);Related Packages
| Package | Description |
|---------|-------------|
| @nehorai/credits | Core credit system (types, service, in-memory repository) |
| @nehorai/credits-firestore | Firestore implementation of ICreditRepository |
Repository
https://github.com/NehoraiHadad/nehorai-plugins
License
MIT
