crovver-node 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +111 -0
- package/LICENSE +21 -0
- package/README.md +271 -0
- package/dist/cjs/constants.js +5 -0
- package/dist/cjs/constants.js.map +1 -0
- package/dist/cjs/index.js +479 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/esm/constants.js +2 -0
- package/dist/esm/constants.js.map +1 -0
- package/dist/esm/index.js +471 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/types/constants.d.ts +2 -0
- package/dist/types/constants.d.ts.map +1 -0
- package/dist/types/index.d.ts +582 -0
- package/dist/types/index.d.ts.map +1 -0
- package/package.json +95 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [1.0.0] - 2026-03-29
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Core Client**
|
|
13
|
+
- `baseUrl` config option to override the API base URL (useful for local development and testing)
|
|
14
|
+
- `CrovverClient` class with full TypeScript support
|
|
15
|
+
- Automatic retry with exponential backoff for transient failures (5xx, 429, timeouts)
|
|
16
|
+
- Debug logging support with custom logger option
|
|
17
|
+
|
|
18
|
+
- **Tenant Management** (B2B)
|
|
19
|
+
- `createTenant()` - Create a new tenant/workspace
|
|
20
|
+
- `getTenant()` - Get tenant information by external ID
|
|
21
|
+
|
|
22
|
+
- **Plans**
|
|
23
|
+
- `getPlans()` - Fetch all available subscription plans
|
|
24
|
+
|
|
25
|
+
- **Subscriptions**
|
|
26
|
+
- `getSubscriptions()` - Get active subscriptions for a tenant/user
|
|
27
|
+
|
|
28
|
+
- **Checkout**
|
|
29
|
+
- `createCheckoutSession()` - Create payment checkout session
|
|
30
|
+
- Support for B2B and D2C checkout flows
|
|
31
|
+
- Support for Stripe, Paddle, and LemonSqueezy providers
|
|
32
|
+
|
|
33
|
+
- **Entitlements**
|
|
34
|
+
- `canAccess()` - Check feature access for tenant/user
|
|
35
|
+
- `recordUsage()` - Record metered usage
|
|
36
|
+
- `checkUsageLimit()` - Check usage against limits
|
|
37
|
+
|
|
38
|
+
- **Seat-Based Billing**
|
|
39
|
+
- `getActiveCapacity()` - Get current seat utilization
|
|
40
|
+
- `recordSeatAllocation()` - Record seat assignment with proration calculation
|
|
41
|
+
- `removeSeat()` - Remove seat allocation
|
|
42
|
+
- `createProrationCheckout()` - Create payment session for seat upgrades
|
|
43
|
+
|
|
44
|
+
- **Payment Providers**
|
|
45
|
+
- `getSupportedProviders()` - List available payment providers
|
|
46
|
+
|
|
47
|
+
- **Error Handling**
|
|
48
|
+
- `CrovverError` class with status codes and error codes
|
|
49
|
+
- Automatic classification of retryable vs non-retryable errors
|
|
50
|
+
|
|
51
|
+
- **TypeScript**
|
|
52
|
+
- Full type definitions for all requests and responses
|
|
53
|
+
- Strict TypeScript configuration
|
|
54
|
+
- ESM and CommonJS dual build support
|
|
55
|
+
|
|
56
|
+
### Security
|
|
57
|
+
|
|
58
|
+
- API key passed via Authorization header (not in URL)
|
|
59
|
+
- No credentials logged in debug mode
|
|
60
|
+
|
|
61
|
+
## [0.1.0] - 2026-01-15
|
|
62
|
+
|
|
63
|
+
### Added
|
|
64
|
+
|
|
65
|
+
- Initial beta release
|
|
66
|
+
- Basic client implementation
|
|
67
|
+
- Core API methods
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Migration Guide
|
|
72
|
+
|
|
73
|
+
### From 0.x to 1.0.0
|
|
74
|
+
|
|
75
|
+
1. **Import Changes**
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
// Old
|
|
79
|
+
import CrovverClient from "@crovver/sdk";
|
|
80
|
+
|
|
81
|
+
// New (recommended)
|
|
82
|
+
import { CrovverClient } from "@crovver/sdk";
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
2. **Configuration**
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
// New options available
|
|
89
|
+
const client = new CrovverClient({
|
|
90
|
+
apiKey: "your-key",
|
|
91
|
+
maxRetries: 3, // New: Configure retries (default: 3)
|
|
92
|
+
debug: true, // New: Enable debug logging
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
3. **New Methods**
|
|
97
|
+
- `recordSeatAllocation()` - Use for seat-based billing
|
|
98
|
+
- `removeSeat()` - Use for seat removal
|
|
99
|
+
- `getSupportedProviders()` - List payment providers
|
|
100
|
+
|
|
101
|
+
4. **Error Handling**
|
|
102
|
+
```typescript
|
|
103
|
+
// CrovverError now includes more context
|
|
104
|
+
catch (error) {
|
|
105
|
+
if (error instanceof CrovverError) {
|
|
106
|
+
console.log(error.isRetryable); // New: Check if error is retryable
|
|
107
|
+
console.log(error.statusCode);
|
|
108
|
+
console.log(error.code);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Crovver
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
# crovver-node
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/crovver-node)
|
|
4
|
+
[](https://www.typescriptlang.org/)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
|
|
7
|
+
Official Node.js/TypeScript SDK for integrating [Crovver](https://crovver.com) subscription management into your backend.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **Complete API Coverage** — tenants, plans, subscriptions, checkout, entitlements, invoices, proration
|
|
12
|
+
- **TypeScript Support** — full type definitions included
|
|
13
|
+
- **B2B & D2C Support** — works with both organization types
|
|
14
|
+
- **Error Handling** — `CrovverError` class with status codes and retryability flags
|
|
15
|
+
- **Automatic Retries** — exponential backoff with jitter for transient failures
|
|
16
|
+
- **No Checkout Retry** — payment-creating endpoints are never retried to prevent duplicate charges
|
|
17
|
+
- **ESM & CommonJS** — dual module support
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install crovver-node
|
|
23
|
+
# or
|
|
24
|
+
yarn add crovver-node
|
|
25
|
+
# or
|
|
26
|
+
pnpm add crovver-node
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Quick Start
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { CrovverClient } from "crovver-node";
|
|
33
|
+
|
|
34
|
+
const crovver = new CrovverClient({
|
|
35
|
+
apiKey: "sk_live_your_api_key",
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const canAccess = await crovver.canAccess("company-123", "advanced-analytics");
|
|
39
|
+
if (canAccess) {
|
|
40
|
+
console.log("Access granted!");
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Configuration
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
interface CrovverConfig {
|
|
48
|
+
apiKey: string; // Bearer API key — starts with sk_live_ or sk_test_
|
|
49
|
+
timeout?: number; // ms, default 30 000
|
|
50
|
+
maxRetries?: number; // default 3
|
|
51
|
+
debug?: boolean; // default false
|
|
52
|
+
logger?: (message: string, data?: unknown) => void;
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Error Handling
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
import { CrovverClient, CrovverError } from "crovver-node";
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
await crovver.canAccess("company-123", "premium-feature");
|
|
63
|
+
} catch (error) {
|
|
64
|
+
if (error instanceof CrovverError) {
|
|
65
|
+
console.error(error.message);
|
|
66
|
+
console.error("HTTP status:", error.statusCode);
|
|
67
|
+
console.error("Retryable:", error.isRetryable);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Automatic retries apply to 5xx, 429, 408, and network errors. 4xx errors are **not** retried.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## API Reference
|
|
77
|
+
|
|
78
|
+
### Tenant Management (B2B Only)
|
|
79
|
+
|
|
80
|
+
#### `createTenant`
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
const result = await crovver.createTenant({
|
|
84
|
+
externalTenantId: "company-123",
|
|
85
|
+
name: "Acme Corporation",
|
|
86
|
+
ownerExternalUserId: "user-456",
|
|
87
|
+
ownerEmail: "admin@acme.com",
|
|
88
|
+
ownerName: "John Doe",
|
|
89
|
+
});
|
|
90
|
+
console.log("Tenant ID:", result.tenant.id);
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
#### `getTenant`
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
const { tenant, members } = await crovver.getTenant("company-123");
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
### Plans
|
|
102
|
+
|
|
103
|
+
#### `getPlans`
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
const { plans } = await crovver.getPlans();
|
|
107
|
+
plans.forEach((plan) => {
|
|
108
|
+
console.log(`${plan.name}: ${plan.pricing.currency} ${plan.pricing.amount}/${plan.pricing.interval}`);
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
### Subscriptions
|
|
115
|
+
|
|
116
|
+
#### `getSubscriptions`
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
const { subscriptions } = await crovver.getSubscriptions("company-123");
|
|
120
|
+
subscriptions.forEach((sub) => {
|
|
121
|
+
console.log(`${sub.plan.name} — ${sub.status}`);
|
|
122
|
+
});
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
#### `cancelSubscription`
|
|
126
|
+
|
|
127
|
+
Cancels at period end (no immediate termination).
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
const result = await crovver.cancelSubscription(
|
|
131
|
+
"sub-uuid",
|
|
132
|
+
"too_expensive",
|
|
133
|
+
"Pricing is a bit high for our team size"
|
|
134
|
+
);
|
|
135
|
+
console.log(`Ends at: ${result.willEndAt}`);
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
### Checkout
|
|
141
|
+
|
|
142
|
+
#### `createCheckoutSession`
|
|
143
|
+
|
|
144
|
+
**B2B:**
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
const checkout = await crovver.createCheckoutSession({
|
|
148
|
+
requestingUserId: "user-456",
|
|
149
|
+
requestingTenantId: "company-123",
|
|
150
|
+
planId: "plan-uuid",
|
|
151
|
+
provider: "stripe",
|
|
152
|
+
successUrl: "https://myapp.com/success",
|
|
153
|
+
cancelUrl: "https://myapp.com/cancel",
|
|
154
|
+
});
|
|
155
|
+
window.location.href = checkout.checkoutUrl;
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**D2C (tenant auto-created):**
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
const checkout = await crovver.createCheckoutSession({
|
|
162
|
+
requestingUserId: "user-789",
|
|
163
|
+
userEmail: "john@example.com",
|
|
164
|
+
userName: "John Doe",
|
|
165
|
+
planId: "plan-uuid",
|
|
166
|
+
provider: "stripe",
|
|
167
|
+
successUrl: "https://myapp.com/success",
|
|
168
|
+
cancelUrl: "https://myapp.com/cancel",
|
|
169
|
+
});
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
### Entitlements
|
|
175
|
+
|
|
176
|
+
#### `canAccess`
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
const canAccess = await crovver.canAccess("company-123", "advanced-analytics");
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
#### `recordUsage`
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
await crovver.recordUsage("company-123", "api-calls", 1, {
|
|
186
|
+
endpoint: "/api/v1/users",
|
|
187
|
+
});
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
#### `checkUsageLimit`
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
const usage = await crovver.checkUsageLimit("company-123", "api-calls");
|
|
194
|
+
console.log(`${usage.current} / ${usage.limit} — allowed: ${usage.allowed}`);
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
### Proration (Seat-Based Plans)
|
|
200
|
+
|
|
201
|
+
#### `createProrationCheckout`
|
|
202
|
+
|
|
203
|
+
Creates a one-time payment session for a mid-cycle seat capacity upgrade.
|
|
204
|
+
The proration amount is calculated server-side.
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
const checkout = await crovver.createProrationCheckout({
|
|
208
|
+
requestingEntityId: "company-123",
|
|
209
|
+
newCapacity: 15,
|
|
210
|
+
planId: "plan-uuid", // optional
|
|
211
|
+
successUrl: "https://myapp.com/success",
|
|
212
|
+
cancelUrl: "https://myapp.com/cancel",
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
if (checkout.checkoutUrl) {
|
|
216
|
+
window.location.href = checkout.checkoutUrl;
|
|
217
|
+
}
|
|
218
|
+
console.log(`Prorated amount: ${checkout.prorationAmount} ${checkout.prorationDetails.currency}`);
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
### Billing
|
|
224
|
+
|
|
225
|
+
#### `getInvoices`
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
const { invoices } = await crovver.getInvoices("company-123");
|
|
229
|
+
invoices.forEach((inv) => {
|
|
230
|
+
console.log(`${inv.invoice_number}: ${inv.total_amount} ${inv.currency} — ${inv.status}`);
|
|
231
|
+
});
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
### Payment Providers
|
|
237
|
+
|
|
238
|
+
#### `getSupportedProviders`
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
const { providers } = await crovver.getSupportedProviders();
|
|
242
|
+
providers.forEach((p) => console.log(`${p.name}: ${p.code}`));
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## TypeScript Exports
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
import {
|
|
251
|
+
CrovverClient,
|
|
252
|
+
CrovverError,
|
|
253
|
+
CrovverConfig,
|
|
254
|
+
Plan,
|
|
255
|
+
Subscription,
|
|
256
|
+
Tenant,
|
|
257
|
+
CreateTenantRequest,
|
|
258
|
+
CreateCheckoutSessionRequest,
|
|
259
|
+
CreateProrationCheckoutRequest,
|
|
260
|
+
CreateProrationCheckoutResponse,
|
|
261
|
+
CancelSubscriptionResponse,
|
|
262
|
+
GetInvoicesResponse,
|
|
263
|
+
CheckUsageLimitResponse,
|
|
264
|
+
} from "crovver-node";
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## License
|
|
270
|
+
|
|
271
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,gBAAgB,GAAG,yBAAyB,CAAC"}
|