@maxnate/crm-core
v0.1.0
Published
Framework-agnostic CRM provider abstraction. Define adapters, register providers, sync contacts and deals — zero runtime dependencies.
Maintainers
Readme
@maxnate/crm-core
Zero-dependency TypeScript library for building CRM provider plugins. Define adapters, register providers, sync contacts — framework-agnostic, works in Node.js, Edge, Deno, and Bun.
npm install @maxnate/crm-coreWhy crm-core?
| Concern | crm-core handles | You handle |
|---|---|---|
| Provider interface | CrmProviderAdapter with lifecycle hooks | Implementing per provider |
| Registry | createCrmProviderRegistry() — register, configure, route | Wiring tenancy + persistence |
| Tenant isolation | Per-tenant config + idempotency | Providing ConfigStore + CrmIdempotencyStore |
| Idempotency | Pluggable store with TTL (CRM_IDEMPOTENCY_KEY_TTL_SECONDS) | Backing store (Redis/DB) |
| Errors | CrmProviderError, CrmIdempotencyKeyError | Catching + reporting |
Available Providers
| Package | Provider | Capabilities |
|---|---|---|
| @maxnate/provider-hubspot | HubSpot | Contact upsert, search, property mapping |
Additional providers (Salesforce, Pipedrive, Zoho, ActiveCampaign) can be added by implementing
CrmProviderAdapter.
Quick Start
import { createCrmProviderRegistry } from '@maxnate/crm-core'
import { HubSpotCrmProvider } from '@maxnate/provider-hubspot'
const registry = createCrmProviderRegistry({
configStore: myConfigStore,
secretsCodec: mySecretsCodec,
idempotencyStore: myIdempotencyStore // optional, in-memory by default
})
registry.register(new HubSpotCrmProvider())
await registry.configureProvider('tenant-1', {
id: 'hubspot', name: 'HubSpot', enabled: true,
credentials: { accessToken: process.env.HUBSPOT_TOKEN! },
propertyMap: { firstName: 'firstname', lastName: 'lastname' }
})
const result = await registry.upsertContact('tenant-1', 'hubspot', {
email: '[email protected]',
firstName: 'Jane',
lastName: 'Doe',
attributes: { lead_source: 'web' }
})Architecture
@maxnate/crm-core ← This package (interface + registry + errors)
@maxnate/provider-hubspot ← Adapter implementing CrmProviderAdapter
@maxnate/provider-* ← Community adaptersKey Concepts
CrmProviderAdapter
interface CrmProviderAdapter {
providerId: string
providerName: string
initialize(config: CrmProviderConfig): void | Promise<void>
upsertContact(contact: Contact): Promise<UpsertContactResult>
findContacts(query: ContactSearchQuery): Promise<ContactSearchResult>
supportsFeature?(feature: keyof CrmProviderFeature): boolean
}Registry (tenant-scoped)
registry.register(provider) // Add a provider class
registry.unregister(providerId) // Remove
registry.get(providerId) // Get adapter
registry.getAll() // All registered adapters
registry.getEnabled(tenantId) // Enabled for a tenant
registry.getConfig(tenantId, providerId) // Read config
registry.configureProvider(tenantId, config) // Persist + initialize
registry.upsertContact(tenantId, providerId, contact) // Push contact
registry.findContacts(tenantId, providerId, query) // Query contactsCreating a Provider
import {
BaseCrmProvider, Contact, UpsertContactResult,
ContactSearchQuery, ContactSearchResult
} from '@maxnate/crm-core'
export class MyProvider extends BaseCrmProvider {
providerId = 'my-provider'
providerName = 'My Provider'
async upsertContact(contact: Contact): Promise<UpsertContactResult> {
// ... implement
}
async findContacts(query: ContactSearchQuery): Promise<ContactSearchResult> {
// ... implement
}
}BaseCrmProvider provides default initialize and capability flags.
Plugin Integration
For Maxnate-platform users, install @maxnate/plugin-crm which exposes the crmModule capability via ctx.extend('crmModule', module) and ships an /admin/crm UI.
Webhooks
CRM webhook handling is provider-specific (HubSpot, Salesforce, and Pipedrive each use different signature schemes). crm-core does not currently provide a unified webhook handler — providers expose their own verification + parsing in their package documentation.
Requirements
- Node.js >= 18 (or any runtime with Web Crypto API)
- TypeScript 5.x recommended
- Zero runtime dependencies
License
MIT
