@c15t/node-sdk 1.8.0 → 2.0.0-rc.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/README.md CHANGED
@@ -18,33 +18,237 @@
18
18
  [![Last Commit](https://img.shields.io/github/last-commit/c15t/c15t?style=flat-square)](https://github.com/c15t/c15t/commits/main)
19
19
  [![Open Issues](https://img.shields.io/github/issues/c15t/c15t?style=flat-square)](https://github.com/c15t/c15t/issues)
20
20
 
21
- A fully typed, flexible Node.js SDK for seamless interaction with the c15t consent management platform API.
21
+ A fully typed, lightweight Node.js SDK for seamless interaction with the c15t consent management platform API.
22
22
 
23
23
  ## Key Features
24
24
 
25
- - Type-safe API client with full TypeScript support
26
- - Flexible client configuration with authentication and custom headers
27
- - Supports dynamic base URL and API prefix configuration
28
- - Built on top of @orpc/client for robust API interactions
29
- - Easy integration with Node.js applications
30
- - Comprehensive error handling and URL validation
25
+ - **Type-safe API client** with full TypeScript support
26
+ - **Zero-config setup** with environment variable auto-detection
27
+ - **Result-like error handling** with `unwrap()`, `unwrapOr()`, and `expect()` helpers
28
+ - **Custom error class** (`C15TError`) for typed error handling
29
+ - **Automatic retries** with exponential backoff
30
+ - **Namespaced API methods** for intuitive organization
31
+ - **Lightweight** with minimal dependencies
31
32
 
32
33
  ## Prerequisites
33
34
 
34
35
  - Node.js 18.17.0 or later
35
36
  - A Hosted [c15t instance](https://consent.io) (free sign-up) or [self-hosted deployment](https://c15t.com/docs/self-host/v2)
36
37
 
37
- ## Manual Installation
38
+ ## Installation
38
39
 
39
40
  ```bash
41
+ # npm
42
+ npm install @c15t/node-sdk
43
+
44
+ # pnpm
40
45
  pnpm add @c15t/node-sdk
46
+
47
+ # yarn
48
+ yarn add @c15t/node-sdk
49
+
50
+ # bun
51
+ bun add @c15t/node-sdk
52
+ ```
53
+
54
+ ## Quick Start
55
+
56
+ ### Basic Setup
57
+
58
+ ```typescript
59
+ import { c15tClient } from '@c15t/node-sdk';
60
+
61
+ // Auto-configure from environment variables
62
+ // Reads C15T_API_URL and C15T_API_TOKEN automatically
63
+ const client = c15tClient();
64
+
65
+ // Or provide explicit configuration
66
+ const client = c15tClient({
67
+ baseUrl: 'https://api.example.com',
68
+ token: 'your-api-token',
69
+ });
41
70
  ```
42
71
 
43
- ## Usage
72
+ ### Environment Variables
73
+
74
+ The SDK automatically reads these environment variables:
75
+
76
+ - `C15T_API_URL` - Base URL for the API server
77
+ - `C15T_API_TOKEN` - Authentication token
78
+
79
+ ### Check Consent Status
80
+
81
+ ```typescript
82
+ const result = await client.checkConsent({
83
+ externalId: 'user_123',
84
+ type: 'analytics',
85
+ });
86
+
87
+ if (result.ok) {
88
+ console.log('Has consent:', result.data?.results.analytics?.hasConsent);
89
+ } else {
90
+ console.error('Error:', result.error?.message);
91
+ }
92
+ ```
93
+
94
+ ### Using Result Helpers
95
+
96
+ The SDK provides ergonomic helper methods inspired by Rust's Result type:
97
+
98
+ ```typescript
99
+ // Unwrap data or throw if error
100
+ const subject = (await client.getSubject('sub_123')).unwrap();
101
+
102
+ // Unwrap with custom error message
103
+ const subject = (await client.getSubject('sub_123')).expect('Subject not found');
104
+
105
+ // Unwrap with default value
106
+ const subject = (await client.getSubject('sub_123')).unwrapOr(defaultSubject);
107
+
108
+ // Transform data with map
109
+ const name = (await client.getSubject('sub_123')).map(s => s.externalId);
110
+ ```
111
+
112
+ ### Error Handling
113
+
114
+ ```typescript
115
+ import { c15tClient, C15TError, isC15TError } from '@c15t/node-sdk';
116
+
117
+ const client = c15tClient();
118
+
119
+ try {
120
+ const subject = (await client.getSubject('sub_123')).unwrap();
121
+ } catch (error) {
122
+ if (isC15TError(error)) {
123
+ console.log('Status:', error.status); // 404
124
+ console.log('Code:', error.code); // 'NOT_FOUND'
125
+ console.log('Details:', error.details);
126
+
127
+ if (error.isNotFound()) {
128
+ // Handle not found
129
+ } else if (error.isServerError()) {
130
+ // Handle server error
131
+ }
132
+ }
133
+ }
134
+ ```
44
135
 
45
- 1. Import the c15tClient function from the SDK
46
- 2. Configure the client with your API base URL
47
- 3. Interact with the c15t API using type-safe methods
136
+ ### Create Subject with Consent
137
+
138
+ ```typescript
139
+ const result = await client.createSubject({
140
+ type: 'cookie_banner',
141
+ subjectId: 'sub_123',
142
+ externalSubjectId: 'user_123',
143
+ domain: 'example.com',
144
+ preferences: {
145
+ analytics: true,
146
+ marketing: false,
147
+ },
148
+ givenAt: Date.now(),
149
+ });
150
+
151
+ if (result.ok) {
152
+ console.log('Subject created:', result.data?.subjectId);
153
+ }
154
+ ```
155
+
156
+ ### Server Component Usage (Next.js)
157
+
158
+ ```typescript
159
+ // lib/c15t-client.ts
160
+ import { c15tClient } from '@c15t/node-sdk';
161
+
162
+ export const consentClient = c15tClient({
163
+ baseUrl: process.env.C15T_API_URL || 'http://localhost:3000/api/self-host',
164
+ });
165
+
166
+ // app/consent-check/page.tsx
167
+ import { consentClient } from '@/lib/c15t-client';
168
+
169
+ export default async function ConsentCheckPage({ searchParams }) {
170
+ const { externalId } = await searchParams;
171
+
172
+ const result = await consentClient.checkConsent({
173
+ externalId,
174
+ type: 'analytics',
175
+ });
176
+
177
+ if (!result.ok) {
178
+ return <div>Error: {result.error?.message}</div>;
179
+ }
180
+
181
+ return <pre>{JSON.stringify(result.data, null, 2)}</pre>;
182
+ }
183
+ ```
184
+
185
+ ## API Reference
186
+
187
+ ### Client Methods
188
+
189
+ | Method | Description |
190
+ |--------|-------------|
191
+ | `client.status()` | Check API status |
192
+ | `client.init()` | Initialize consent manager |
193
+ | `client.checkConsent(query)` | Check consent status |
194
+ | `client.createSubject(input)` | Create a new subject |
195
+ | `client.getSubject(id)` | Get subject by ID |
196
+ | `client.patchSubject(id, input)` | Update subject |
197
+ | `client.listSubjects(query)` | List subjects |
198
+
199
+ ### Namespaced Methods
200
+
201
+ ```typescript
202
+ // Meta operations
203
+ client.meta.status();
204
+ client.meta.init();
205
+
206
+ // Consent operations
207
+ client.consent.check(query);
208
+
209
+ // Subject operations
210
+ client.subjects.create(input);
211
+ client.subjects.get(id);
212
+ client.subjects.patch(id, input);
213
+ client.subjects.list(query);
214
+ ```
215
+
216
+ ### ResponseContext
217
+
218
+ All methods return a `ResponseContext<T>` with:
219
+
220
+ ```typescript
221
+ interface ResponseContext<T> {
222
+ data: T | null; // Response data
223
+ error: {...} | null; // Error details
224
+ ok: boolean; // Success status
225
+ response: Response | null; // Raw Response object
226
+
227
+ // Helper methods
228
+ unwrap(): T; // Get data or throw
229
+ unwrapOr(default: T): T; // Get data or return default
230
+ expect(msg: string): T; // Get data or throw with custom message
231
+ map<U>(fn: (T) => U): ResponseContext<U>; // Transform data
232
+ }
233
+ ```
234
+
235
+ ### Configuration Options
236
+
237
+ ```typescript
238
+ interface C15TClientOptions {
239
+ baseUrl?: string; // API base URL (or use C15T_API_URL env var)
240
+ token?: string; // Auth token (or use C15T_API_TOKEN env var)
241
+ headers?: Record<string, string>; // Custom headers
242
+ prefix?: string; // API path prefix
243
+ retryConfig?: {
244
+ maxRetries?: number; // Default: 3
245
+ initialDelayMs?: number; // Default: 100
246
+ backoffFactor?: number; // Default: 2
247
+ retryableStatusCodes?: number[]; // Default: [500, 502, 503, 504]
248
+ retryOnNetworkError?: boolean; // Default: true
249
+ };
250
+ }
251
+ ```
48
252
 
49
253
  ## Support
50
254
 
@@ -82,4 +286,4 @@ Our preference is that you make use of GitHub's private vulnerability reporting
82
286
 
83
287
  ---
84
288
 
85
- **Built with ❤️ by the [consent.io](https://www.consent.io?utm_source=github&utm_medium=repopage_%40c15t%2Fnode-sdk) team**
289
+ **Built with love by the [consent.io](https://www.consent.io?utm_source=github&utm_medium=repopage_%40c15t%2Fnode-sdk) team**
@@ -0,0 +1,433 @@
1
+ import type { CheckConsentOutput, CheckConsentQuery, GetSubjectOutput, GetSubjectQuery, InitOutput, ListSubjectsOutput, ListSubjectsQuery, PatchSubjectFullInput, PatchSubjectOutput, PostSubjectInput, PostSubjectOutput, StatusOutput } from '@c15t/schema/types';
2
+ import type { C15TClientOptions, FetchOptions, ResponseContext } from './types';
3
+ /**
4
+ * C15T Client for interacting with the consent management API
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * const client = new C15TClient({
9
+ * baseUrl: 'https://api.example.com',
10
+ * token: 'your-auth-token',
11
+ * });
12
+ *
13
+ * // Check API status
14
+ * const statusResponse = await client.status();
15
+ *
16
+ * // Initialize consent manager
17
+ * const initResponse = await client.init();
18
+ *
19
+ * // Create a subject with consent
20
+ * const subject = await client.createSubject({
21
+ * type: 'new',
22
+ * subjectId: 'sub_123',
23
+ * consents: { analytics: true },
24
+ * });
25
+ * ```
26
+ */
27
+ export declare class C15TClient {
28
+ /**
29
+ * Internal fetcher context
30
+ */
31
+ private context;
32
+ /**
33
+ * Creates a new C15T client instance
34
+ *
35
+ * @param options - Client configuration options
36
+ * @throws {TypeError} If baseUrl is invalid or not provided (and no env var)
37
+ */
38
+ constructor(options?: C15TClientOptions);
39
+ /**
40
+ * Get API status
41
+ *
42
+ * @param options - Optional fetch options
43
+ * @returns Status response with version and client info
44
+ */
45
+ status(options?: FetchOptions<StatusOutput>): Promise<ResponseContext<StatusOutput>>;
46
+ /**
47
+ * Initialize consent manager
48
+ *
49
+ * @param options - Optional fetch options
50
+ * @returns Init response with jurisdiction, location, translations, branding
51
+ */
52
+ init(options?: FetchOptions<InitOutput>): Promise<ResponseContext<InitOutput>>;
53
+ /**
54
+ * Create a new subject with consent preferences
55
+ *
56
+ * @param input - Subject creation input
57
+ * @param options - Optional fetch options
58
+ * @returns Created subject response
59
+ */
60
+ createSubject(input: PostSubjectInput, options?: FetchOptions<PostSubjectOutput, PostSubjectInput>): Promise<ResponseContext<PostSubjectOutput>>;
61
+ /**
62
+ * Get a subject by ID
63
+ *
64
+ * @param id - Subject ID
65
+ * @param query - Optional query parameters
66
+ * @param options - Optional fetch options
67
+ * @returns Subject data response
68
+ */
69
+ getSubject(id: string, query?: GetSubjectQuery, options?: FetchOptions<GetSubjectOutput, never, GetSubjectQuery>): Promise<ResponseContext<GetSubjectOutput>>;
70
+ /**
71
+ * Update a subject (link external ID or update preferences)
72
+ *
73
+ * @param id - Subject ID
74
+ * @param input - Patch input with externalId or other fields
75
+ * @param options - Optional fetch options
76
+ * @returns Updated subject response
77
+ */
78
+ patchSubject(id: string, input: Omit<PatchSubjectFullInput, 'id'>, options?: FetchOptions<PatchSubjectOutput, Omit<PatchSubjectFullInput, 'id'>>): Promise<ResponseContext<PatchSubjectOutput>>;
79
+ /**
80
+ * List subjects with optional filtering
81
+ *
82
+ * @param query - Query parameters for filtering
83
+ * @param options - Optional fetch options
84
+ * @returns List of subjects
85
+ */
86
+ listSubjects(query?: ListSubjectsQuery, options?: FetchOptions<ListSubjectsOutput, never, ListSubjectsQuery>): Promise<ResponseContext<ListSubjectsOutput>>;
87
+ /**
88
+ * Check consent status for an external ID
89
+ *
90
+ * @param query - Query parameters (externalId required)
91
+ * @param options - Optional fetch options
92
+ * @returns Consent check response
93
+ */
94
+ checkConsent(query: CheckConsentQuery, options?: FetchOptions<CheckConsentOutput, never, CheckConsentQuery>): Promise<ResponseContext<CheckConsentOutput>>;
95
+ /**
96
+ * Make a custom API request to any endpoint
97
+ *
98
+ * @param path - API endpoint path
99
+ * @param options - Fetch options
100
+ * @returns Response context
101
+ */
102
+ $fetch<ResponseType, BodyType = unknown, QueryType = unknown>(path: string, options?: FetchOptions<ResponseType, BodyType, QueryType>): Promise<ResponseContext<ResponseType>>;
103
+ /**
104
+ * Namespaced access to consent endpoints
105
+ */
106
+ consent: {
107
+ /**
108
+ * Check consent status for an external ID
109
+ */
110
+ check: (query: CheckConsentQuery, options?: FetchOptions<CheckConsentOutput, never, CheckConsentQuery>) => Promise<ResponseContext<{
111
+ results: {
112
+ [x: string]: {
113
+ hasConsent: boolean;
114
+ isLatestPolicy: boolean;
115
+ };
116
+ };
117
+ }>>;
118
+ };
119
+ /**
120
+ * Namespaced access to subject endpoints
121
+ */
122
+ subjects: {
123
+ /**
124
+ * Create a new subject
125
+ */
126
+ create: (input: PostSubjectInput, options?: FetchOptions<PostSubjectOutput, PostSubjectInput>) => Promise<ResponseContext<{
127
+ subjectId: string;
128
+ consentId: string;
129
+ domainId: string;
130
+ domain: string;
131
+ type: "cookie_banner" | "privacy_policy" | "dpa" | "terms_and_conditions" | "marketing_communications" | "age_verification" | "other";
132
+ status: string;
133
+ recordId: string;
134
+ metadata?: {
135
+ [x: string]: unknown;
136
+ } | undefined;
137
+ uiSource?: string | undefined;
138
+ givenAt: Date;
139
+ }>>;
140
+ /**
141
+ * Get a subject by ID
142
+ */
143
+ get: (id: string, query?: GetSubjectQuery, options?: FetchOptions<GetSubjectOutput, never, GetSubjectQuery>) => Promise<ResponseContext<{
144
+ subject: {
145
+ id: string;
146
+ externalId?: string | undefined;
147
+ isIdentified: boolean;
148
+ createdAt?: Date | undefined;
149
+ };
150
+ consents: {
151
+ id: string;
152
+ type: string;
153
+ policyId?: string | undefined;
154
+ isLatestPolicy: boolean;
155
+ preferences?: {
156
+ [x: string]: boolean;
157
+ } | undefined;
158
+ givenAt: Date;
159
+ }[];
160
+ isValid: boolean;
161
+ }>>;
162
+ /**
163
+ * Update a subject
164
+ */
165
+ patch: (id: string, input: Omit<PatchSubjectFullInput, "id">, options?: FetchOptions<PatchSubjectOutput, Omit<PatchSubjectFullInput, "id">>) => Promise<ResponseContext<{
166
+ success: boolean;
167
+ subject: {
168
+ id: string;
169
+ externalId: string;
170
+ isIdentified: boolean;
171
+ };
172
+ }>>;
173
+ /**
174
+ * List subjects
175
+ */
176
+ list: (query?: ListSubjectsQuery, options?: FetchOptions<ListSubjectsOutput, never, ListSubjectsQuery>) => Promise<ResponseContext<{
177
+ subjects: {
178
+ id: string;
179
+ externalId: string;
180
+ isIdentified: boolean;
181
+ createdAt: Date;
182
+ consents: {
183
+ id: string;
184
+ type: string;
185
+ policyId?: string | undefined;
186
+ isLatestPolicy: boolean;
187
+ preferences?: {
188
+ [x: string]: boolean;
189
+ } | undefined;
190
+ givenAt: Date;
191
+ }[];
192
+ }[];
193
+ }>>;
194
+ };
195
+ /**
196
+ * Namespaced access to meta endpoints
197
+ */
198
+ meta: {
199
+ /**
200
+ * Get API status
201
+ */
202
+ status: (options?: FetchOptions<StatusOutput>) => Promise<ResponseContext<{
203
+ version: string;
204
+ timestamp: Date;
205
+ client: {
206
+ ip: string | null;
207
+ acceptLanguage: string | null;
208
+ userAgent: string | null;
209
+ region: {
210
+ countryCode: string | null;
211
+ regionCode: string | null;
212
+ };
213
+ };
214
+ }>>;
215
+ /**
216
+ * Initialize consent manager
217
+ */
218
+ init: (options?: FetchOptions<InitOutput>) => Promise<ResponseContext<{
219
+ jurisdiction: "UK_GDPR" | "GDPR" | "CH" | "BR" | "PIPEDA" | "QC_LAW25" | "AU" | "APPI" | "PIPA" | "CCPA" | "NONE";
220
+ location: {
221
+ countryCode: string | null;
222
+ regionCode: string | null;
223
+ };
224
+ translations: {
225
+ language: string;
226
+ translations: {
227
+ common: {
228
+ acceptAll: string;
229
+ rejectAll: string;
230
+ customize: string;
231
+ save: string;
232
+ };
233
+ cookieBanner: {
234
+ title: string;
235
+ description: string;
236
+ };
237
+ consentManagerDialog: {
238
+ title: string;
239
+ description: string;
240
+ };
241
+ consentTypes: {
242
+ experience: {
243
+ title: string;
244
+ description: string;
245
+ };
246
+ functionality: {
247
+ title: string;
248
+ description: string;
249
+ };
250
+ marketing: {
251
+ title: string;
252
+ description: string;
253
+ };
254
+ measurement: {
255
+ title: string;
256
+ description: string;
257
+ };
258
+ necessary: {
259
+ title: string;
260
+ description: string;
261
+ };
262
+ };
263
+ frame: {
264
+ title: string;
265
+ actionButton: string;
266
+ };
267
+ legalLinks: {
268
+ privacyPolicy: string;
269
+ termsOfService: string;
270
+ cookiePolicy: string;
271
+ };
272
+ } | {
273
+ common: {
274
+ acceptAll?: string | undefined;
275
+ rejectAll?: string | undefined;
276
+ customize?: string | undefined;
277
+ save?: string | undefined;
278
+ };
279
+ cookieBanner: {
280
+ title?: string | undefined;
281
+ description?: string | undefined;
282
+ };
283
+ consentManagerDialog: {
284
+ title?: string | undefined;
285
+ description?: string | undefined;
286
+ };
287
+ consentTypes: {
288
+ experience?: {
289
+ title?: string | undefined;
290
+ description?: string | undefined;
291
+ } | undefined;
292
+ functionality?: {
293
+ title?: string | undefined;
294
+ description?: string | undefined;
295
+ } | undefined;
296
+ marketing?: {
297
+ title?: string | undefined;
298
+ description?: string | undefined;
299
+ } | undefined;
300
+ measurement?: {
301
+ title?: string | undefined;
302
+ description?: string | undefined;
303
+ } | undefined;
304
+ necessary?: {
305
+ title?: string | undefined;
306
+ description?: string | undefined;
307
+ } | undefined;
308
+ };
309
+ frame?: {
310
+ title?: string | undefined;
311
+ actionButton?: string | undefined;
312
+ } | undefined;
313
+ legalLinks?: {
314
+ privacyPolicy?: string | undefined;
315
+ termsOfService?: string | undefined;
316
+ cookiePolicy?: string | undefined;
317
+ } | undefined;
318
+ };
319
+ };
320
+ branding: "c15t" | "consent" | "none";
321
+ gvl?: {
322
+ gvlSpecificationVersion: number;
323
+ vendorListVersion: number;
324
+ tcfPolicyVersion: number;
325
+ lastUpdated: string;
326
+ purposes: {
327
+ [x: string]: {
328
+ id: number;
329
+ name: string;
330
+ description: string;
331
+ illustrations: string[];
332
+ descriptionLegal?: string | undefined;
333
+ };
334
+ };
335
+ specialPurposes: {
336
+ [x: string]: {
337
+ id: number;
338
+ name: string;
339
+ description: string;
340
+ illustrations: string[];
341
+ descriptionLegal?: string | undefined;
342
+ };
343
+ };
344
+ features: {
345
+ [x: string]: {
346
+ id: number;
347
+ name: string;
348
+ description: string;
349
+ illustrations: string[];
350
+ descriptionLegal?: string | undefined;
351
+ };
352
+ };
353
+ specialFeatures: {
354
+ [x: string]: {
355
+ id: number;
356
+ name: string;
357
+ description: string;
358
+ illustrations: string[];
359
+ descriptionLegal?: string | undefined;
360
+ };
361
+ };
362
+ vendors: {
363
+ [x: string]: {
364
+ id: number;
365
+ name: string;
366
+ purposes: number[];
367
+ legIntPurposes: number[];
368
+ flexiblePurposes: number[];
369
+ specialPurposes: number[];
370
+ features: number[];
371
+ specialFeatures: number[];
372
+ cookieMaxAgeSeconds: number | null;
373
+ usesCookies: boolean;
374
+ cookieRefresh: boolean;
375
+ usesNonCookieAccess: boolean;
376
+ urls: {
377
+ langId: string;
378
+ privacy?: string | undefined;
379
+ legIntClaim?: string | undefined;
380
+ }[];
381
+ deviceStorageDisclosureUrl?: string | undefined;
382
+ dataCategories?: number[] | undefined;
383
+ dataRetention?: {
384
+ purposes?: {
385
+ [x: string]: number;
386
+ } | undefined;
387
+ specialPurposes?: {
388
+ [x: string]: number;
389
+ } | undefined;
390
+ stdRetention?: number | undefined;
391
+ } | undefined;
392
+ deletedDate?: string | undefined;
393
+ overflow?: {
394
+ httpGetLimit: number;
395
+ } | undefined;
396
+ };
397
+ };
398
+ stacks: {
399
+ [x: string]: {
400
+ id: number;
401
+ name: string;
402
+ description: string;
403
+ purposes: number[];
404
+ specialFeatures: number[];
405
+ };
406
+ };
407
+ dataCategories?: {
408
+ [x: string]: {
409
+ id: number;
410
+ name: string;
411
+ description: string;
412
+ };
413
+ } | undefined;
414
+ } | null | undefined;
415
+ customVendors?: {
416
+ id: string | number;
417
+ name: string;
418
+ privacyPolicyUrl: string;
419
+ description?: string | undefined;
420
+ purposes: number[];
421
+ legIntPurposes?: number[] | undefined;
422
+ features?: number[] | undefined;
423
+ specialFeatures?: number[] | undefined;
424
+ dataCategories?: number[] | undefined;
425
+ cookieMaxAgeSeconds?: number | undefined;
426
+ usesCookies?: boolean | undefined;
427
+ usesNonCookieAccess?: boolean | undefined;
428
+ dataRetentionDays?: number | undefined;
429
+ }[] | undefined;
430
+ }>>;
431
+ };
432
+ }
433
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}