@habeetat/sdk-node
v0.4.6
Published
Habeetat Platform SDK for Node.js backend applications
Readme
@habeetat/sdk-node
Habeetat Platform SDK for Node.js backend applications.
Installation
npm install @habeetat/sdk-node
# or
pnpm add @habeetat/sdk-nodeQuick Start
import { HabeetatClient } from '@habeetat/sdk-node';
const sdk = new HabeetatClient({
platformUrl: 'https://api.habeetat.io',
auth: {
logtoEndpoint: 'https://logto.habeetat.io',
clientId: process.env.HABEETAT_CLIENT_ID!,
clientSecret: process.env.HABEETAT_CLIENT_SECRET!,
},
});
// Check feature flag
const isEnabled = await sdk.features.isEnabled('crm.deals.enabled', {
tenantId: 'acme-corp',
});
// Get subscription limits
const limits = await sdk.subscription.getLimits('acme-corp');
// Send notification
await sdk.notifications.send({
tenantId: 'acme-corp',
userId: 'user_123',
template: 'welcome',
data: { name: 'John' },
});Express Middleware
import express from 'express';
import {
createHabeetatMiddleware,
requirePermission,
requireFeature,
} from '@habeetat/sdk-node/middleware';
const app = express();
// Initialize middleware
app.use(createHabeetatMiddleware({
config: {
platformUrl: 'https://api.habeetat.io',
auth: {
logtoEndpoint: 'https://logto.habeetat.io',
clientId: process.env.HABEETAT_CLIENT_ID!,
clientSecret: process.env.HABEETAT_CLIENT_SECRET!,
},
},
fetchPermissions: true,
}));
// Use permission guard
app.get('/contacts',
requirePermission('contacts:read'),
(req, res) => {
// Access SDK client via req.habeetat.client
res.json({ contacts: [] });
}
);
// Use feature guard
app.get('/deals',
requireFeature('crm.deals.enabled'),
(req, res) => {
res.json({ deals: [] });
}
);NestJS Integration
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import {
HabeetatModule,
InjectHabeetat,
RequirePermission,
HabeetatPermissionGuard,
} from '@habeetat/sdk-node/nestjs';
import { HabeetatClient } from '@habeetat/sdk-node';
@Module({
imports: [
HabeetatModule.forRootAsync({
imports: [ConfigModule],
useFactory: (config: ConfigService) => ({
platformUrl: config.get('HABEETAT_URL'),
auth: {
logtoEndpoint: config.get('LOGTO_ENDPOINT'),
clientId: config.get('HABEETAT_CLIENT_ID'),
clientSecret: config.get('HABEETAT_CLIENT_SECRET'),
},
}),
inject: [ConfigService],
}),
],
})
export class AppModule {}
// In a service
@Injectable()
export class ContactsService {
constructor(@InjectHabeetat() private readonly sdk: HabeetatClient) {}
async checkFeature(tenantId: string) {
return this.sdk.features.isEnabled('contacts.export', { tenantId });
}
}
// In a controller
@Controller('contacts')
@UseGuards(HabeetatPermissionGuard)
export class ContactsController {
@Get()
@RequirePermission('contacts:read')
findAll() {
return [];
}
}API Reference
HabeetatClient
Main SDK client class.
Constructor Options
| Option | Type | Required | Description |
|--------|------|----------|-------------|
| platformUrl | string | Yes | Platform API base URL |
| auth.logtoEndpoint | string | Yes | Logto endpoint URL |
| auth.clientId | string | Yes | M2M application client ID |
| auth.clientSecret | string | Yes | M2M application client secret |
| auth.resource | string | No | API resource (default: https://api.habeetat.io/sdk) |
| auth.scopes | string[] | No | Scopes to request (default: ['sdk:read']) |
| timeout | number | No | Request timeout in ms (default: 30000) |
| debug | boolean | No | Enable debug logging |
| retry.maxRetries | number | No | Max retry attempts (default: 3) |
Features API
// Get all features
const features = await sdk.features.getAll(tenantId);
// Check if feature is enabled
const isEnabled = await sdk.features.isEnabled('feature.key', { tenantId });
// Get feature value
const value = await sdk.features.getValue('feature.key', tenantId, defaultValue);Subscription API (Tenant scope — B2B)
// Get subscription
const subscription = await sdk.subscription.get({ tenantId });
// Get limits
const limits = await sdk.subscription.getLimits(tenantId);
// Check limit
const result = await sdk.subscription.checkLimit({
tenantId,
limitKey: 'maxContacts',
increment: 1,
});
// Check if allowed (boolean)
const allowed = await sdk.subscription.isAllowed({
tenantId,
limitKey: 'maxContacts',
});User Subscription API (User scope — B2C)
For B2C applications where each individual user has their own subscription (e.g. billingScope: USER).
// Get a user's subscription
const sub = await sdk.userSubscription.get(userId, appId);
// Get user plan limits
const limits = await sdk.userSubscription.getLimits(userId, appId);
// { maxProjects: 10, maxStorage: 5000 }
// Check a limit (returns { allowed, current, limit, limitKey })
const result = await sdk.userSubscription.checkLimit({
userId,
limitKey: 'maxProjects',
increment: 1,
appId,
});
// Boolean shorthand
const allowed = await sdk.userSubscription.isAllowed({
userId,
limitKey: 'maxProjects',
});
// Get available plans for a B2C app
const plans = await sdk.userSubscription.getAvailablePlans(appId);
// Start Stripe checkout for a user
const { checkoutUrl } = await sdk.userSubscription.startCheckout({
userId,
appId,
planId: 'plan_xxx',
billingOptionId: 'opt_xxx',
trial: false,
successUrl: 'https://myapp.com/billing?success=1',
cancelUrl: 'https://myapp.com/billing?cancelled=1',
});
// Cancel a user subscription
await sdk.userSubscription.cancel(userId, appId, { cancelAtPeriodEnd: true });
// Open Stripe billing portal for a user
const { portalUrl } = await sdk.userSubscription.openBillingPortal(
userId,
'https://myapp.com/settings/billing',
);Tip: Use
BillingScopefrom@habeetat/sdk-nodeto detect which model an app uses:import { BillingScope } from '@habeetat/sdk-node'; // BillingScope.TENANT | BillingScope.USER
Notifications API
// Send notification
await sdk.notifications.send({
tenantId: 'acme-corp',
userId: 'user_123',
template: 'welcome',
data: { name: 'John' },
channel: 'email',
});Logs API
// Send log
await sdk.logs.log({
level: 'info',
message: 'User logged in',
tenantId: 'acme-corp',
context: { userId: 'user_123' },
});
// Convenience methods
await sdk.logs.debug('Debug message');
await sdk.logs.info('Info message');
await sdk.logs.warn('Warning message');
await sdk.logs.error('Error message');Audit API
// Track audit event
await sdk.audit.track({
action: 'contact.created',
tenantId: 'acme-corp',
actorId: 'user_123',
resourceType: 'contact',
resourceId: 'contact_456',
data: { name: 'John Doe' },
});License
MIT
