@chatarmin/os 0.1.1
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/README.md +167 -0
- package/dist/index.d.ts +348 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +194 -0
- package/package.json +63 -0
package/README.md
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# @chatarmin/os-sdk
|
|
2
|
+
|
|
3
|
+
Type-safe SDK for ChatarminOS - Customer & Subscription Management.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
> **Note**: This is a private npm package. You need authentication to install it.
|
|
8
|
+
|
|
9
|
+
### 1. Configure npm Authentication
|
|
10
|
+
|
|
11
|
+
Create a `.npmrc` file in your project root:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# .npmrc
|
|
15
|
+
@chatarmin:registry=https://registry.npmjs.org/
|
|
16
|
+
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Set your npm token as an environment variable:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# .env (for local development)
|
|
23
|
+
NPM_TOKEN=npm_yourtokenhere
|
|
24
|
+
|
|
25
|
+
# Or export it in your shell
|
|
26
|
+
export NPM_TOKEN=npm_yourtokenhere
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**For CI/CD**: Add `NPM_TOKEN` as a secret in your deployment platform (GitHub Actions, Vercel, etc.)
|
|
30
|
+
|
|
31
|
+
### 2. Install the Package
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm install @chatarmin/os-sdk
|
|
35
|
+
# or
|
|
36
|
+
pnpm add @chatarmin/os-sdk
|
|
37
|
+
# or
|
|
38
|
+
yarn add @chatarmin/os-sdk
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
> See [PUBLISHING.md](./PUBLISHING.md) for detailed setup instructions.
|
|
42
|
+
|
|
43
|
+
## Quick Start
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import { ChatarminOS } from "@chatarmin/os-sdk"
|
|
47
|
+
|
|
48
|
+
const os = new ChatarminOS({
|
|
49
|
+
apiKey: process.env.CHATARMIN_OS_API_KEY!,
|
|
50
|
+
// Optional: custom base URL for self-hosted
|
|
51
|
+
// baseUrl: 'https://your-os.example.com/api/v1'
|
|
52
|
+
})
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Usage
|
|
56
|
+
|
|
57
|
+
### Companies
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
// Find company by your external org ID
|
|
61
|
+
const company = await os.companies.getByProductLink({
|
|
62
|
+
externalOrgId: "org_123",
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
// Create a new company and link to your product
|
|
66
|
+
const newCompany = await os.companies.create({
|
|
67
|
+
name: "Acme Inc",
|
|
68
|
+
domain: "acme.com",
|
|
69
|
+
externalOrgId: "org_456",
|
|
70
|
+
contactEmail: "billing@acme.com",
|
|
71
|
+
contactName: "John Doe",
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
// Smart link - find existing company by hints
|
|
75
|
+
const linked = await os.companies.smartLink({
|
|
76
|
+
externalOrgId: "org_789",
|
|
77
|
+
hints: {
|
|
78
|
+
companyName: "Acme",
|
|
79
|
+
domain: "acme.com",
|
|
80
|
+
emails: ["john@acme.com", "jane@acme.com"],
|
|
81
|
+
},
|
|
82
|
+
minConfidence: 0.8,
|
|
83
|
+
})
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Subscriptions & Tiers
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
// Apply a subscription tier to a company
|
|
90
|
+
await os.subscriptions.create("pro", {
|
|
91
|
+
companyId: company.id,
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
// With feature overrides
|
|
95
|
+
await os.subscriptions.create("enterprise", {
|
|
96
|
+
companyId: company.id,
|
|
97
|
+
features: {
|
|
98
|
+
ai_credits: { included_quantity: 1000 },
|
|
99
|
+
},
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
// List available tiers
|
|
103
|
+
const tiers = await os.tiers.list()
|
|
104
|
+
|
|
105
|
+
// Get tier details
|
|
106
|
+
const proTier = await os.tiers.get("pro")
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Feature Access
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
// Check if company has access to a feature
|
|
113
|
+
const access = await os.features.check({
|
|
114
|
+
companyId: company.id,
|
|
115
|
+
featureCode: "whatsapp_messages",
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
if (access.hasAccess) {
|
|
119
|
+
console.log(`Limit: ${access.limit}, Used: ${access.currentUsage}`)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// List all feature access for a company
|
|
123
|
+
const allAccess = await os.features.listAccess(company.id)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Billing & Usage Tracking
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
// Track usage for a feature
|
|
130
|
+
await os.billing.trackUsage({
|
|
131
|
+
companyId: company.id,
|
|
132
|
+
featureCode: "ai_credits",
|
|
133
|
+
quantity: 5,
|
|
134
|
+
idempotencyKey: "unique-request-id", // Optional, for deduplication
|
|
135
|
+
metadata: { model: "gpt-4" }, // Optional
|
|
136
|
+
})
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Manual Linking
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
// Link an external org ID to an existing company
|
|
143
|
+
await os.links.create({
|
|
144
|
+
companyId: company.id,
|
|
145
|
+
externalOrgId: "org_new_123",
|
|
146
|
+
externalUserId: "user_456", // Optional
|
|
147
|
+
})
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Configuration
|
|
151
|
+
|
|
152
|
+
| Option | Type | Required | Default | Description |
|
|
153
|
+
| --------- | -------- | -------- | --------------------------------- | ------------------------------ |
|
|
154
|
+
| `apiKey` | `string` | ✅ | - | API key from ChatarminOS admin |
|
|
155
|
+
| `baseUrl` | `string` | - | `https://os.chatarmin.com/api/v1` | API endpoint |
|
|
156
|
+
|
|
157
|
+
## TypeScript Support
|
|
158
|
+
|
|
159
|
+
The SDK is fully typed. All methods return properly typed responses based on the ChatarminOS API schema.
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
import type { AppRouter } from "@chatarmin/os-sdk"
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## License
|
|
166
|
+
|
|
167
|
+
MIT © Chatarmin GmbH
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
import type { AppRouter } from "@chatarmin/api";
|
|
2
|
+
export interface ChatarminOSConfig {
|
|
3
|
+
/** API key generated in the OS admin for your product */
|
|
4
|
+
apiKey: string;
|
|
5
|
+
/** Base URL of the OS API (default: https://os.chatarmin.com/api/v1) */
|
|
6
|
+
baseUrl?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* ChatarminOS SDK Client
|
|
10
|
+
*
|
|
11
|
+
* Type-safe client for interacting with ChatarminOS from your product.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { ChatarminOS } from '@chatarmin/os-sdk'
|
|
16
|
+
*
|
|
17
|
+
* const os = new ChatarminOS({ apiKey: process.env.OS_API_KEY! })
|
|
18
|
+
*
|
|
19
|
+
* // Resolve company by your org ID
|
|
20
|
+
* const company = await os.companies.getByProductLink({ externalOrgId: 'org_123' })
|
|
21
|
+
*
|
|
22
|
+
* // Track usage
|
|
23
|
+
* await os.billing.trackUsage({
|
|
24
|
+
* companyId: company.id,
|
|
25
|
+
* featureCode: 'ai_credit',
|
|
26
|
+
* quantity: 1
|
|
27
|
+
* })
|
|
28
|
+
*
|
|
29
|
+
* // Check feature access
|
|
30
|
+
* const access = await os.features.check({
|
|
31
|
+
* companyId: company.id,
|
|
32
|
+
* featureCode: 'whatsapp_messages'
|
|
33
|
+
* })
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare class ChatarminOS {
|
|
37
|
+
private client;
|
|
38
|
+
constructor(config: ChatarminOSConfig);
|
|
39
|
+
/**
|
|
40
|
+
* Company operations
|
|
41
|
+
*/
|
|
42
|
+
get companies(): {
|
|
43
|
+
/**
|
|
44
|
+
* Get company by their external org ID in your product
|
|
45
|
+
*/
|
|
46
|
+
getByProductLink: (input: {
|
|
47
|
+
externalOrgId: string;
|
|
48
|
+
}) => Promise<{
|
|
49
|
+
name: string;
|
|
50
|
+
id: string;
|
|
51
|
+
domain: string | null;
|
|
52
|
+
external_org_id: string;
|
|
53
|
+
external_user_id: string | null;
|
|
54
|
+
} | null>;
|
|
55
|
+
/**
|
|
56
|
+
* Create a new company and link to your product
|
|
57
|
+
*/
|
|
58
|
+
create: (input: {
|
|
59
|
+
name: string;
|
|
60
|
+
domain?: string;
|
|
61
|
+
externalOrgId: string;
|
|
62
|
+
externalUserId?: string;
|
|
63
|
+
contactEmail?: string;
|
|
64
|
+
contactName?: string;
|
|
65
|
+
}) => Promise<{
|
|
66
|
+
id: string;
|
|
67
|
+
shortId: string | null;
|
|
68
|
+
name: string;
|
|
69
|
+
externalOrgId: string;
|
|
70
|
+
}>;
|
|
71
|
+
/**
|
|
72
|
+
* Smart link - find and link company using hints
|
|
73
|
+
*
|
|
74
|
+
* @experimental
|
|
75
|
+
*/
|
|
76
|
+
smartLink: (input: {
|
|
77
|
+
externalOrgId: string;
|
|
78
|
+
hints: {
|
|
79
|
+
companyName?: string;
|
|
80
|
+
domain?: string;
|
|
81
|
+
emails?: string[];
|
|
82
|
+
};
|
|
83
|
+
minConfidence?: number;
|
|
84
|
+
}) => Promise<{
|
|
85
|
+
status: "already_linked";
|
|
86
|
+
customerId: string;
|
|
87
|
+
customerName: string | undefined;
|
|
88
|
+
confidence: number;
|
|
89
|
+
suggestions?: undefined;
|
|
90
|
+
reason?: undefined;
|
|
91
|
+
} | {
|
|
92
|
+
status: "no_match";
|
|
93
|
+
suggestions: never[];
|
|
94
|
+
customerId?: undefined;
|
|
95
|
+
customerName?: undefined;
|
|
96
|
+
confidence?: undefined;
|
|
97
|
+
reason?: undefined;
|
|
98
|
+
} | {
|
|
99
|
+
status: "linked";
|
|
100
|
+
customerId: string;
|
|
101
|
+
customerName: string;
|
|
102
|
+
confidence: number;
|
|
103
|
+
reason: string;
|
|
104
|
+
suggestions?: undefined;
|
|
105
|
+
} | {
|
|
106
|
+
status: "suggestions";
|
|
107
|
+
suggestions: {
|
|
108
|
+
customerId: string;
|
|
109
|
+
customerName: string;
|
|
110
|
+
confidence: number;
|
|
111
|
+
reason: string;
|
|
112
|
+
}[];
|
|
113
|
+
customerId?: undefined;
|
|
114
|
+
customerName?: undefined;
|
|
115
|
+
confidence?: undefined;
|
|
116
|
+
reason?: undefined;
|
|
117
|
+
}>;
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* Feature access operations
|
|
121
|
+
*/
|
|
122
|
+
get features(): {
|
|
123
|
+
/**
|
|
124
|
+
* Check if a company has access to a feature
|
|
125
|
+
* Returns detailed access info including usage and limits
|
|
126
|
+
*/
|
|
127
|
+
check: (input: {
|
|
128
|
+
companyId: string;
|
|
129
|
+
featureCode: string;
|
|
130
|
+
}) => Promise<{
|
|
131
|
+
featureCode: string;
|
|
132
|
+
isEnabled: boolean;
|
|
133
|
+
hasQuantity: boolean;
|
|
134
|
+
currentUsage: number;
|
|
135
|
+
quantityLimit: number | null;
|
|
136
|
+
includedQuantity: number;
|
|
137
|
+
remaining: number | null;
|
|
138
|
+
isAtLimit: boolean;
|
|
139
|
+
canUse: boolean;
|
|
140
|
+
}>;
|
|
141
|
+
/**
|
|
142
|
+
* List all features and their access status for a company
|
|
143
|
+
* Useful for showing a company's full feature set
|
|
144
|
+
*/
|
|
145
|
+
listAccess: (companyId: string) => Promise<{
|
|
146
|
+
featureCode: string;
|
|
147
|
+
featureName: string;
|
|
148
|
+
description: string | null;
|
|
149
|
+
hasQuantity: boolean;
|
|
150
|
+
isEnabled: boolean;
|
|
151
|
+
quantityLimit: number | null;
|
|
152
|
+
includedQuantity: number;
|
|
153
|
+
source: string;
|
|
154
|
+
validUntil: Date | null;
|
|
155
|
+
}[]>;
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* Billing and usage tracking
|
|
159
|
+
*/
|
|
160
|
+
get billing(): {
|
|
161
|
+
/**
|
|
162
|
+
* Track usage for a feature
|
|
163
|
+
* Returns updated usage info after tracking
|
|
164
|
+
*/
|
|
165
|
+
trackUsage: (input: {
|
|
166
|
+
companyId: string;
|
|
167
|
+
featureCode: string;
|
|
168
|
+
quantity?: number;
|
|
169
|
+
idempotencyKey?: string;
|
|
170
|
+
metadata?: Record<string, unknown>;
|
|
171
|
+
}) => Promise<{
|
|
172
|
+
success: boolean;
|
|
173
|
+
featureCode: string;
|
|
174
|
+
currentUsage: number;
|
|
175
|
+
quantityLimit: number | null;
|
|
176
|
+
remaining: number | null;
|
|
177
|
+
isAtLimit: boolean;
|
|
178
|
+
includedQuantity: number;
|
|
179
|
+
billableQuantity: number;
|
|
180
|
+
meterId: string;
|
|
181
|
+
}>;
|
|
182
|
+
};
|
|
183
|
+
/**
|
|
184
|
+
* Link operations - manually link external IDs to companies
|
|
185
|
+
*/
|
|
186
|
+
get links(): {
|
|
187
|
+
/**
|
|
188
|
+
* Simple link: associate external org ID with an existing company
|
|
189
|
+
*/
|
|
190
|
+
create: (input: {
|
|
191
|
+
companyId: string;
|
|
192
|
+
externalOrgId: string;
|
|
193
|
+
externalUserId?: string;
|
|
194
|
+
}) => Promise<{
|
|
195
|
+
id: string;
|
|
196
|
+
metadata: unknown;
|
|
197
|
+
confidence: number | null;
|
|
198
|
+
created_at: Date;
|
|
199
|
+
updated_at: Date;
|
|
200
|
+
company_id: string;
|
|
201
|
+
product_id: string;
|
|
202
|
+
external_org_id: string;
|
|
203
|
+
external_user_id: string | null;
|
|
204
|
+
link_type: string;
|
|
205
|
+
sync_status: string;
|
|
206
|
+
} | undefined>;
|
|
207
|
+
};
|
|
208
|
+
/**
|
|
209
|
+
* Subscription operations
|
|
210
|
+
*
|
|
211
|
+
* @example
|
|
212
|
+
* ```typescript
|
|
213
|
+
* // Create subscription from a tier template
|
|
214
|
+
* const sub = await os.subscriptions.create("free", {
|
|
215
|
+
* companyId: "comp_xxx",
|
|
216
|
+
* })
|
|
217
|
+
*
|
|
218
|
+
* // Create with overrides
|
|
219
|
+
* const sub = await os.subscriptions.create("pro", {
|
|
220
|
+
* companyId: "comp_xxx",
|
|
221
|
+
* features: {
|
|
222
|
+
* ai_agent: { included_quantity: 200 }
|
|
223
|
+
* }
|
|
224
|
+
* })
|
|
225
|
+
*
|
|
226
|
+
* // Get available tiers
|
|
227
|
+
* const tiers = await os.subscriptions.tiers()
|
|
228
|
+
* ```
|
|
229
|
+
*/
|
|
230
|
+
get subscriptions(): {
|
|
231
|
+
/**
|
|
232
|
+
* Create or apply a subscription tier to a company
|
|
233
|
+
*
|
|
234
|
+
* @param tierCode - The tier code (e.g., "free", "pro", "enterprise")
|
|
235
|
+
* @param options - Subscription options including companyId and optional overrides
|
|
236
|
+
*/
|
|
237
|
+
create: (tierCode: string, options: {
|
|
238
|
+
companyId: string;
|
|
239
|
+
features?: Record<string, Record<string, unknown>>;
|
|
240
|
+
}) => Promise<{
|
|
241
|
+
tierId: string;
|
|
242
|
+
tierName: string;
|
|
243
|
+
featuresApplied: number;
|
|
244
|
+
}>;
|
|
245
|
+
/**
|
|
246
|
+
* Get all available tiers for the current product
|
|
247
|
+
*/
|
|
248
|
+
tiers: () => Promise<{
|
|
249
|
+
features: {
|
|
250
|
+
id: string;
|
|
251
|
+
code: string;
|
|
252
|
+
name: string;
|
|
253
|
+
hasQuantity: boolean;
|
|
254
|
+
configValues: unknown;
|
|
255
|
+
}[];
|
|
256
|
+
name: string;
|
|
257
|
+
id: string;
|
|
258
|
+
metadata: unknown;
|
|
259
|
+
code: string;
|
|
260
|
+
description: string | null;
|
|
261
|
+
is_active: boolean;
|
|
262
|
+
display_order: number;
|
|
263
|
+
created_at: Date;
|
|
264
|
+
updated_at: Date;
|
|
265
|
+
product_id: string;
|
|
266
|
+
}[]>;
|
|
267
|
+
/**
|
|
268
|
+
* Get tier details by code
|
|
269
|
+
*/
|
|
270
|
+
getTier: (tierCode: string) => Promise<{
|
|
271
|
+
id: string;
|
|
272
|
+
code: string;
|
|
273
|
+
name: string;
|
|
274
|
+
features: {
|
|
275
|
+
id: string;
|
|
276
|
+
code: string;
|
|
277
|
+
name: string;
|
|
278
|
+
hasQuantity: boolean;
|
|
279
|
+
configValues: unknown;
|
|
280
|
+
catalogPriceId: string | null;
|
|
281
|
+
}[];
|
|
282
|
+
}>;
|
|
283
|
+
};
|
|
284
|
+
/**
|
|
285
|
+
* Tier operations (alias for subscriptions.tiers for convenience)
|
|
286
|
+
*
|
|
287
|
+
* @example
|
|
288
|
+
* ```typescript
|
|
289
|
+
* // Get tier details
|
|
290
|
+
* const freeTier = await os.tiers.get("free")
|
|
291
|
+
* console.log(freeTier.features)
|
|
292
|
+
* ```
|
|
293
|
+
*/
|
|
294
|
+
get tiers(): {
|
|
295
|
+
/**
|
|
296
|
+
* List all available tiers
|
|
297
|
+
*/
|
|
298
|
+
list: () => Promise<{
|
|
299
|
+
features: {
|
|
300
|
+
id: string;
|
|
301
|
+
code: string;
|
|
302
|
+
name: string;
|
|
303
|
+
hasQuantity: boolean;
|
|
304
|
+
configValues: unknown;
|
|
305
|
+
}[];
|
|
306
|
+
name: string;
|
|
307
|
+
id: string;
|
|
308
|
+
metadata: unknown;
|
|
309
|
+
code: string;
|
|
310
|
+
description: string | null;
|
|
311
|
+
is_active: boolean;
|
|
312
|
+
display_order: number;
|
|
313
|
+
created_at: Date;
|
|
314
|
+
updated_at: Date;
|
|
315
|
+
product_id: string;
|
|
316
|
+
}[]>;
|
|
317
|
+
/**
|
|
318
|
+
* Get tier details by code
|
|
319
|
+
*/
|
|
320
|
+
get: (tierCode: string) => Promise<{
|
|
321
|
+
id: string;
|
|
322
|
+
code: string;
|
|
323
|
+
name: string;
|
|
324
|
+
features: {
|
|
325
|
+
id: string;
|
|
326
|
+
code: string;
|
|
327
|
+
name: string;
|
|
328
|
+
hasQuantity: boolean;
|
|
329
|
+
configValues: unknown;
|
|
330
|
+
catalogPriceId: string | null;
|
|
331
|
+
}[];
|
|
332
|
+
}>;
|
|
333
|
+
/**
|
|
334
|
+
* Apply a tier to a company
|
|
335
|
+
*/
|
|
336
|
+
apply: (tierCode: string, options: {
|
|
337
|
+
companyId: string;
|
|
338
|
+
features?: Record<string, Record<string, unknown>>;
|
|
339
|
+
}) => Promise<{
|
|
340
|
+
tierId: string;
|
|
341
|
+
tierName: string;
|
|
342
|
+
featuresApplied: number;
|
|
343
|
+
}>;
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
export type { AppRouter };
|
|
347
|
+
export default ChatarminOS;
|
|
348
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAI/C,MAAM,WAAW,iBAAiB;IAChC,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAA;IACd,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAgD;gBAElD,MAAM,EAAE,iBAAiB;IAgBrC;;OAEG;IACH,IAAI,SAAS;QAET;;WAEG;kCACuB;YAAE,aAAa,EAAE,MAAM,CAAA;SAAE;;;;;;;QAGnD;;WAEG;wBACa;YACd,IAAI,EAAE,MAAM,CAAA;YACZ,MAAM,CAAC,EAAE,MAAM,CAAA;YACf,aAAa,EAAE,MAAM,CAAA;YACrB,cAAc,CAAC,EAAE,MAAM,CAAA;YACvB,YAAY,CAAC,EAAE,MAAM,CAAA;YACrB,WAAW,CAAC,EAAE,MAAM,CAAA;SACrB;;;;;;QAED;;;;WAIG;2BACgB;YACjB,aAAa,EAAE,MAAM,CAAA;YACrB,KAAK,EAAE;gBACL,WAAW,CAAC,EAAE,MAAM,CAAA;gBACpB,MAAM,CAAC,EAAE,MAAM,CAAA;gBACf,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;aAClB,CAAA;YACD,aAAa,CAAC,EAAE,MAAM,CAAA;SACvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAEJ;IAED;;OAEG;IACH,IAAI,QAAQ;QAGR;;;WAGG;uBACY;YAAE,SAAS,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,MAAM,CAAA;SAAE;;;;;;;;;;;QAGzD;;;WAGG;gCACqB,MAAM;;;;;;;;;;;MAGjC;IAED;;OAEG;IACH,IAAI,OAAO;QAEP;;;WAGG;4BACiB;YAClB,SAAS,EAAE,MAAM,CAAA;YACjB,WAAW,EAAE,MAAM,CAAA;YACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;YACjB,cAAc,CAAC,EAAE,MAAM,CAAA;YACvB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;SACnC;;;;;;;;;;;MAEJ;IAED;;OAEG;IACH,IAAI,KAAK;QAEL;;WAEG;wBACa;YACd,SAAS,EAAE,MAAM,CAAA;YACjB,aAAa,EAAE,MAAM,CAAA;YACrB,cAAc,CAAC,EAAE,MAAM,CAAA;SACxB;;;;;;;;;;;;;MASJ;IAED;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,IAAI,aAAa;QAGb;;;;;WAKG;2BAES,MAAM,WACP;YACP,SAAS,EAAE,MAAM,CAAA;YACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;SACnD;;;;;QAQH;;WAEG;;;;;;;;;;;;;;;;;;;;QAIH;;WAEG;4BACiB,MAAM;;;;;;;;;;;;;MAG7B;IAED;;;;;;;;;OASG;IACH,IAAI,KAAK;QAGL;;WAEG;;;;;;;;;;;;;;;;;;;;QAGH;;WAEG;wBACa,MAAM;;;;;;;;;;;;;QAGtB;;WAEG;0BAES,MAAM,WACP;YACP,SAAS,EAAE,MAAM,CAAA;YACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;SACnD;;;;;MAQN;CACF;AAGD,YAAY,EAAE,SAAS,EAAE,CAAA;AAGzB,eAAe,WAAW,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { createTRPCClient, httpBatchLink } from "@trpc/client";
|
|
2
|
+
import superjson from "superjson";
|
|
3
|
+
/**
|
|
4
|
+
* ChatarminOS SDK Client
|
|
5
|
+
*
|
|
6
|
+
* Type-safe client for interacting with ChatarminOS from your product.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { ChatarminOS } from '@chatarmin/os-sdk'
|
|
11
|
+
*
|
|
12
|
+
* const os = new ChatarminOS({ apiKey: process.env.OS_API_KEY! })
|
|
13
|
+
*
|
|
14
|
+
* // Resolve company by your org ID
|
|
15
|
+
* const company = await os.companies.getByProductLink({ externalOrgId: 'org_123' })
|
|
16
|
+
*
|
|
17
|
+
* // Track usage
|
|
18
|
+
* await os.billing.trackUsage({
|
|
19
|
+
* companyId: company.id,
|
|
20
|
+
* featureCode: 'ai_credit',
|
|
21
|
+
* quantity: 1
|
|
22
|
+
* })
|
|
23
|
+
*
|
|
24
|
+
* // Check feature access
|
|
25
|
+
* const access = await os.features.check({
|
|
26
|
+
* companyId: company.id,
|
|
27
|
+
* featureCode: 'whatsapp_messages'
|
|
28
|
+
* })
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export class ChatarminOS {
|
|
32
|
+
client;
|
|
33
|
+
constructor(config) {
|
|
34
|
+
const baseUrl = config.baseUrl || "https://os.chatarmin.com/api/v1";
|
|
35
|
+
this.client = createTRPCClient({
|
|
36
|
+
links: [
|
|
37
|
+
httpBatchLink({
|
|
38
|
+
url: baseUrl,
|
|
39
|
+
headers: () => ({
|
|
40
|
+
"x-api-key": config.apiKey,
|
|
41
|
+
}),
|
|
42
|
+
transformer: superjson,
|
|
43
|
+
}),
|
|
44
|
+
],
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Company operations
|
|
49
|
+
*/
|
|
50
|
+
get companies() {
|
|
51
|
+
return {
|
|
52
|
+
/**
|
|
53
|
+
* Get company by their external org ID in your product
|
|
54
|
+
*/
|
|
55
|
+
getByProductLink: (input) => this.client.companies.getByProductLink.query(input),
|
|
56
|
+
/**
|
|
57
|
+
* Create a new company and link to your product
|
|
58
|
+
*/
|
|
59
|
+
create: (input) => this.client.companies.createWithLink.mutate(input),
|
|
60
|
+
/**
|
|
61
|
+
* Smart link - find and link company using hints
|
|
62
|
+
*
|
|
63
|
+
* @experimental
|
|
64
|
+
*/
|
|
65
|
+
smartLink: (input) => this.client.companies.smartLink.mutate(input),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Feature access operations
|
|
70
|
+
*/
|
|
71
|
+
get features() {
|
|
72
|
+
const client = this.client;
|
|
73
|
+
return {
|
|
74
|
+
/**
|
|
75
|
+
* Check if a company has access to a feature
|
|
76
|
+
* Returns detailed access info including usage and limits
|
|
77
|
+
*/
|
|
78
|
+
check: (input) => client.features.check.query(input),
|
|
79
|
+
/**
|
|
80
|
+
* List all features and their access status for a company
|
|
81
|
+
* Useful for showing a company's full feature set
|
|
82
|
+
*/
|
|
83
|
+
listAccess: (companyId) => client.features.getAccess.query({ companyId }),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Billing and usage tracking
|
|
88
|
+
*/
|
|
89
|
+
get billing() {
|
|
90
|
+
return {
|
|
91
|
+
/**
|
|
92
|
+
* Track usage for a feature
|
|
93
|
+
* Returns updated usage info after tracking
|
|
94
|
+
*/
|
|
95
|
+
trackUsage: (input) => this.client.billing.trackUsage.mutate(input),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Link operations - manually link external IDs to companies
|
|
100
|
+
*/
|
|
101
|
+
get links() {
|
|
102
|
+
return {
|
|
103
|
+
/**
|
|
104
|
+
* Simple link: associate external org ID with an existing company
|
|
105
|
+
*/
|
|
106
|
+
create: (input) => this.client.companies.linkToProduct.mutate({
|
|
107
|
+
customerId: input.companyId,
|
|
108
|
+
productCode: "", // Will use the product from API key
|
|
109
|
+
externalOrgId: input.externalOrgId,
|
|
110
|
+
externalUserId: input.externalUserId,
|
|
111
|
+
linkType: "identified",
|
|
112
|
+
}),
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Subscription operations
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```typescript
|
|
120
|
+
* // Create subscription from a tier template
|
|
121
|
+
* const sub = await os.subscriptions.create("free", {
|
|
122
|
+
* companyId: "comp_xxx",
|
|
123
|
+
* })
|
|
124
|
+
*
|
|
125
|
+
* // Create with overrides
|
|
126
|
+
* const sub = await os.subscriptions.create("pro", {
|
|
127
|
+
* companyId: "comp_xxx",
|
|
128
|
+
* features: {
|
|
129
|
+
* ai_agent: { included_quantity: 200 }
|
|
130
|
+
* }
|
|
131
|
+
* })
|
|
132
|
+
*
|
|
133
|
+
* // Get available tiers
|
|
134
|
+
* const tiers = await os.subscriptions.tiers()
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
get subscriptions() {
|
|
138
|
+
const client = this.client;
|
|
139
|
+
return {
|
|
140
|
+
/**
|
|
141
|
+
* Create or apply a subscription tier to a company
|
|
142
|
+
*
|
|
143
|
+
* @param tierCode - The tier code (e.g., "free", "pro", "enterprise")
|
|
144
|
+
* @param options - Subscription options including companyId and optional overrides
|
|
145
|
+
*/
|
|
146
|
+
create: (tierCode, options) => client.tiers.applyByCode.mutate({
|
|
147
|
+
tierCode,
|
|
148
|
+
companyId: options.companyId,
|
|
149
|
+
featureOverrides: options.features,
|
|
150
|
+
}),
|
|
151
|
+
/**
|
|
152
|
+
* Get all available tiers for the current product
|
|
153
|
+
*/
|
|
154
|
+
tiers: () => client.tiers.listForProduct.query({ includeInactive: false }),
|
|
155
|
+
/**
|
|
156
|
+
* Get tier details by code
|
|
157
|
+
*/
|
|
158
|
+
getTier: (tierCode) => client.tiers.getByCode.query({ code: tierCode }),
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Tier operations (alias for subscriptions.tiers for convenience)
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* ```typescript
|
|
166
|
+
* // Get tier details
|
|
167
|
+
* const freeTier = await os.tiers.get("free")
|
|
168
|
+
* console.log(freeTier.features)
|
|
169
|
+
* ```
|
|
170
|
+
*/
|
|
171
|
+
get tiers() {
|
|
172
|
+
const client = this.client;
|
|
173
|
+
return {
|
|
174
|
+
/**
|
|
175
|
+
* List all available tiers
|
|
176
|
+
*/
|
|
177
|
+
list: () => client.tiers.listForProduct.query({ includeInactive: false }),
|
|
178
|
+
/**
|
|
179
|
+
* Get tier details by code
|
|
180
|
+
*/
|
|
181
|
+
get: (tierCode) => client.tiers.getByCode.query({ code: tierCode }),
|
|
182
|
+
/**
|
|
183
|
+
* Apply a tier to a company
|
|
184
|
+
*/
|
|
185
|
+
apply: (tierCode, options) => client.tiers.applyByCode.mutate({
|
|
186
|
+
tierCode,
|
|
187
|
+
companyId: options.companyId,
|
|
188
|
+
featureOverrides: options.features,
|
|
189
|
+
}),
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
// Default export
|
|
194
|
+
export default ChatarminOS;
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@chatarmin/os",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "Type-safe SDK for ChatarminOS - Customer & Subscription Management",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"access": "restricted"
|
|
9
|
+
},
|
|
10
|
+
"main": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"README.md"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsc --skipLibCheck",
|
|
24
|
+
"dev": "tsc --watch --skipLibCheck",
|
|
25
|
+
"typecheck": "tsc --noEmit --skipLibCheck",
|
|
26
|
+
"test": "tsx test-sdk.ts",
|
|
27
|
+
"prepublishOnly": "pnpm build",
|
|
28
|
+
"publish": "./scripts/publish.sh",
|
|
29
|
+
"publish:patch": "./scripts/publish.sh patch",
|
|
30
|
+
"publish:minor": "./scripts/publish.sh minor",
|
|
31
|
+
"publish:major": "./scripts/publish.sh major",
|
|
32
|
+
"publish:dry": "npm publish --dry-run"
|
|
33
|
+
},
|
|
34
|
+
"keywords": [
|
|
35
|
+
"chatarmin",
|
|
36
|
+
"sdk",
|
|
37
|
+
"billing",
|
|
38
|
+
"subscriptions",
|
|
39
|
+
"customer-management",
|
|
40
|
+
"trpc"
|
|
41
|
+
],
|
|
42
|
+
"author": "Chatarmin GmbH",
|
|
43
|
+
"license": "MIT",
|
|
44
|
+
"repository": {
|
|
45
|
+
"type": "git",
|
|
46
|
+
"url": "https://github.com/chatarmin/os.git",
|
|
47
|
+
"directory": "packages/sdk"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@trpc/client": "^11.0.0-rc.718",
|
|
51
|
+
"superjson": "^2.2.2"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@chatarmin/api": "workspace:*",
|
|
55
|
+
"@chatarmin/tsconfig": "workspace:*",
|
|
56
|
+
"dotenv": "^16.4.5",
|
|
57
|
+
"tsx": "^4.19.0",
|
|
58
|
+
"typescript": "^5.9.3"
|
|
59
|
+
},
|
|
60
|
+
"peerDependencies": {
|
|
61
|
+
"typescript": "^5.0.0"
|
|
62
|
+
}
|
|
63
|
+
}
|