@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 +217 -13
- package/dist/client.d.ts +433 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/endpoints/consent.d.ts +17 -0
- package/dist/endpoints/consent.d.ts.map +1 -0
- package/dist/endpoints/index.d.ts +5 -0
- package/dist/endpoints/index.d.ts.map +1 -0
- package/dist/endpoints/init.d.ts +16 -0
- package/dist/endpoints/init.d.ts.map +1 -0
- package/dist/endpoints/status.d.ts +16 -0
- package/dist/endpoints/status.d.ts.map +1 -0
- package/dist/endpoints/subjects.d.ts +46 -0
- package/dist/endpoints/subjects.d.ts.map +1 -0
- package/dist/error.d.ts +86 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/fetcher.d.ts +38 -0
- package/dist/fetcher.d.ts.map +1 -0
- package/dist/index.cjs +386 -19
- package/dist/index.d.ts +31 -34
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +365 -16
- package/dist/testing.d.ts +132 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/types.d.ts +235 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +67 -72
- package/LICENSE.md +0 -595
- package/dist/index.test.d.ts +0 -2
- package/dist/index.test.d.ts.map +0 -1
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { CheckConsentOutput, CheckConsentQuery } from '@c15t/schema/types';
|
|
2
|
+
import type { FetcherContext } from '../fetcher';
|
|
3
|
+
import type { FetchOptions, ResponseContext } from '../types';
|
|
4
|
+
/**
|
|
5
|
+
* API endpoint path for consent check
|
|
6
|
+
*/
|
|
7
|
+
export declare const CONSENT_CHECK_PATH = "/consents/check";
|
|
8
|
+
/**
|
|
9
|
+
* Check consent status for an external ID
|
|
10
|
+
*
|
|
11
|
+
* @param context - Fetcher context
|
|
12
|
+
* @param query - Query parameters (externalId required)
|
|
13
|
+
* @param options - Optional fetch options
|
|
14
|
+
* @returns Consent check response
|
|
15
|
+
*/
|
|
16
|
+
export declare function checkConsent(context: FetcherContext, query: CheckConsentQuery, options?: FetchOptions<CheckConsentOutput, never, CheckConsentQuery>): Promise<ResponseContext<CheckConsentOutput>>;
|
|
17
|
+
//# sourceMappingURL=consent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consent.d.ts","sourceRoot":"","sources":["../../src/endpoints/consent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAChF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE9D;;GAEG;AACH,eAAO,MAAM,kBAAkB,oBAAoB,CAAC;AAEpD;;;;;;;GAOG;AACH,wBAAsB,YAAY,CACjC,OAAO,EAAE,cAAc,EACvB,KAAK,EAAE,iBAAiB,EACxB,OAAO,CAAC,EAAE,YAAY,CAAC,kBAAkB,EAAE,KAAK,EAAE,iBAAiB,CAAC,GAClE,OAAO,CAAC,eAAe,CAAC,kBAAkB,CAAC,CAAC,CAU9C"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { CONSENT_CHECK_PATH, checkConsent } from './consent';
|
|
2
|
+
export { INIT_PATH, init } from './init';
|
|
3
|
+
export { STATUS_PATH, status } from './status';
|
|
4
|
+
export { createSubject, getSubject, listSubjects, patchSubject, SUBJECTS_PATH, } from './subjects';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/endpoints/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,EACN,aAAa,EACb,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,aAAa,GACb,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { InitOutput } from '@c15t/schema/types';
|
|
2
|
+
import type { FetcherContext } from '../fetcher';
|
|
3
|
+
import type { FetchOptions, ResponseContext } from '../types';
|
|
4
|
+
/**
|
|
5
|
+
* API endpoint path for init
|
|
6
|
+
*/
|
|
7
|
+
export declare const INIT_PATH = "/init";
|
|
8
|
+
/**
|
|
9
|
+
* Initialize consent manager
|
|
10
|
+
*
|
|
11
|
+
* @param context - Fetcher context
|
|
12
|
+
* @param options - Optional fetch options
|
|
13
|
+
* @returns Init response with jurisdiction, location, translations, branding
|
|
14
|
+
*/
|
|
15
|
+
export declare function init(context: FetcherContext, options?: FetchOptions<InitOutput>): Promise<ResponseContext<InitOutput>>;
|
|
16
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/endpoints/init.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE9D;;GAEG;AACH,eAAO,MAAM,SAAS,UAAU,CAAC;AAEjC;;;;;;GAMG;AACH,wBAAsB,IAAI,CACzB,OAAO,EAAE,cAAc,EACvB,OAAO,CAAC,EAAE,YAAY,CAAC,UAAU,CAAC,GAChC,OAAO,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CAKtC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { StatusOutput } from '@c15t/schema/types';
|
|
2
|
+
import type { FetcherContext } from '../fetcher';
|
|
3
|
+
import type { FetchOptions, ResponseContext } from '../types';
|
|
4
|
+
/**
|
|
5
|
+
* API endpoint path for status
|
|
6
|
+
*/
|
|
7
|
+
export declare const STATUS_PATH = "/status";
|
|
8
|
+
/**
|
|
9
|
+
* Get API status
|
|
10
|
+
*
|
|
11
|
+
* @param context - Fetcher context
|
|
12
|
+
* @param options - Optional fetch options
|
|
13
|
+
* @returns Status response
|
|
14
|
+
*/
|
|
15
|
+
export declare function status(context: FetcherContext, options?: FetchOptions<StatusOutput>): Promise<ResponseContext<StatusOutput>>;
|
|
16
|
+
//# sourceMappingURL=status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/endpoints/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE9D;;GAEG;AACH,eAAO,MAAM,WAAW,YAAY,CAAC;AAErC;;;;;;GAMG;AACH,wBAAsB,MAAM,CAC3B,OAAO,EAAE,cAAc,EACvB,OAAO,CAAC,EAAE,YAAY,CAAC,YAAY,CAAC,GAClC,OAAO,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC,CAKxC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { GetSubjectOutput, GetSubjectQuery, ListSubjectsOutput, ListSubjectsQuery, PatchSubjectFullInput, PatchSubjectOutput, PostSubjectInput, PostSubjectOutput } from '@c15t/schema/types';
|
|
2
|
+
import type { FetcherContext } from '../fetcher';
|
|
3
|
+
import type { FetchOptions, ResponseContext } from '../types';
|
|
4
|
+
/**
|
|
5
|
+
* API endpoint paths for subjects
|
|
6
|
+
*/
|
|
7
|
+
export declare const SUBJECTS_PATH = "/subjects";
|
|
8
|
+
/**
|
|
9
|
+
* Create a new subject with consent preferences
|
|
10
|
+
*
|
|
11
|
+
* @param context - Fetcher context
|
|
12
|
+
* @param input - Subject creation input
|
|
13
|
+
* @param options - Optional fetch options
|
|
14
|
+
* @returns Created subject response
|
|
15
|
+
*/
|
|
16
|
+
export declare function createSubject(context: FetcherContext, input: PostSubjectInput, options?: FetchOptions<PostSubjectOutput, PostSubjectInput>): Promise<ResponseContext<PostSubjectOutput>>;
|
|
17
|
+
/**
|
|
18
|
+
* Get a subject by ID
|
|
19
|
+
*
|
|
20
|
+
* @param context - Fetcher context
|
|
21
|
+
* @param id - Subject ID
|
|
22
|
+
* @param query - Optional query parameters
|
|
23
|
+
* @param options - Optional fetch options
|
|
24
|
+
* @returns Subject data response
|
|
25
|
+
*/
|
|
26
|
+
export declare function getSubject(context: FetcherContext, id: string, query?: GetSubjectQuery, options?: FetchOptions<GetSubjectOutput, never, GetSubjectQuery>): Promise<ResponseContext<GetSubjectOutput>>;
|
|
27
|
+
/**
|
|
28
|
+
* Update a subject (link external ID or update preferences)
|
|
29
|
+
*
|
|
30
|
+
* @param context - Fetcher context
|
|
31
|
+
* @param id - Subject ID
|
|
32
|
+
* @param input - Patch input with externalId or other fields
|
|
33
|
+
* @param options - Optional fetch options
|
|
34
|
+
* @returns Updated subject response
|
|
35
|
+
*/
|
|
36
|
+
export declare function patchSubject(context: FetcherContext, id: string, input: Omit<PatchSubjectFullInput, 'id'>, options?: FetchOptions<PatchSubjectOutput, Omit<PatchSubjectFullInput, 'id'>>): Promise<ResponseContext<PatchSubjectOutput>>;
|
|
37
|
+
/**
|
|
38
|
+
* List subjects with optional filtering
|
|
39
|
+
*
|
|
40
|
+
* @param context - Fetcher context
|
|
41
|
+
* @param query - Query parameters for filtering
|
|
42
|
+
* @param options - Optional fetch options
|
|
43
|
+
* @returns List of subjects
|
|
44
|
+
*/
|
|
45
|
+
export declare function listSubjects(context: FetcherContext, query?: ListSubjectsQuery, options?: FetchOptions<ListSubjectsOutput, never, ListSubjectsQuery>): Promise<ResponseContext<ListSubjectsOutput>>;
|
|
46
|
+
//# sourceMappingURL=subjects.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subjects.d.ts","sourceRoot":"","sources":["../../src/endpoints/subjects.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE9D;;GAEG;AACH,eAAO,MAAM,aAAa,cAAc,CAAC;AAEzC;;;;;;;GAOG;AACH,wBAAsB,aAAa,CAClC,OAAO,EAAE,cAAc,EACvB,KAAK,EAAE,gBAAgB,EACvB,OAAO,CAAC,EAAE,YAAY,CAAC,iBAAiB,EAAE,gBAAgB,CAAC,GACzD,OAAO,CAAC,eAAe,CAAC,iBAAiB,CAAC,CAAC,CAM7C;AAED;;;;;;;;GAQG;AACH,wBAAsB,UAAU,CAC/B,OAAO,EAAE,cAAc,EACvB,EAAE,EAAE,MAAM,EACV,KAAK,CAAC,EAAE,eAAe,EACvB,OAAO,CAAC,EAAE,YAAY,CAAC,gBAAgB,EAAE,KAAK,EAAE,eAAe,CAAC,GAC9D,OAAO,CAAC,eAAe,CAAC,gBAAgB,CAAC,CAAC,CAU5C;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CACjC,OAAO,EAAE,cAAc,EACvB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,IAAI,CAAC,qBAAqB,EAAE,IAAI,CAAC,EACxC,OAAO,CAAC,EAAE,YAAY,CAAC,kBAAkB,EAAE,IAAI,CAAC,qBAAqB,EAAE,IAAI,CAAC,CAAC,GAC3E,OAAO,CAAC,eAAe,CAAC,kBAAkB,CAAC,CAAC,CAU9C;AAED;;;;;;;GAOG;AACH,wBAAsB,YAAY,CACjC,OAAO,EAAE,cAAc,EACvB,KAAK,CAAC,EAAE,iBAAiB,EACzB,OAAO,CAAC,EAAE,YAAY,CAAC,kBAAkB,EAAE,KAAK,EAAE,iBAAiB,CAAC,GAClE,OAAO,CAAC,eAAe,CAAC,kBAAkB,CAAC,CAAC,CAU9C"}
|
package/dist/error.d.ts
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* C15TError - Custom error class for typed error handling
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```typescript
|
|
6
|
+
* import { C15TError } from '@c15t/node-sdk';
|
|
7
|
+
*
|
|
8
|
+
* try {
|
|
9
|
+
* const subject = (await client.getSubject('sub_123')).unwrap();
|
|
10
|
+
* } catch (error) {
|
|
11
|
+
* if (error instanceof C15TError) {
|
|
12
|
+
* console.log(error.status); // 404
|
|
13
|
+
* console.log(error.code); // 'NOT_FOUND'
|
|
14
|
+
* console.log(error.details);
|
|
15
|
+
* }
|
|
16
|
+
* }
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare class C15TError extends Error {
|
|
20
|
+
/**
|
|
21
|
+
* HTTP status code of the error response
|
|
22
|
+
*/
|
|
23
|
+
readonly status: number;
|
|
24
|
+
/**
|
|
25
|
+
* Error code for programmatic error identification
|
|
26
|
+
*/
|
|
27
|
+
readonly code?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Additional error details
|
|
30
|
+
*/
|
|
31
|
+
readonly details?: Record<string, unknown> | null;
|
|
32
|
+
/**
|
|
33
|
+
* Original cause of the error (if any)
|
|
34
|
+
*/
|
|
35
|
+
readonly cause?: unknown;
|
|
36
|
+
constructor(options: {
|
|
37
|
+
message: string;
|
|
38
|
+
status: number;
|
|
39
|
+
code?: string;
|
|
40
|
+
details?: Record<string, unknown> | null;
|
|
41
|
+
cause?: unknown;
|
|
42
|
+
});
|
|
43
|
+
/**
|
|
44
|
+
* Check if the error is a specific HTTP status code
|
|
45
|
+
*/
|
|
46
|
+
isStatus(status: number): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Check if the error is a not found error (404)
|
|
49
|
+
*/
|
|
50
|
+
isNotFound(): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Check if the error is a validation error (400)
|
|
53
|
+
*/
|
|
54
|
+
isValidationError(): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Check if the error is an authentication error (401)
|
|
57
|
+
*/
|
|
58
|
+
isUnauthorized(): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Check if the error is a forbidden error (403)
|
|
61
|
+
*/
|
|
62
|
+
isForbidden(): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Check if the error is a server error (5xx)
|
|
65
|
+
*/
|
|
66
|
+
isServerError(): boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Check if the error is a network error
|
|
69
|
+
*/
|
|
70
|
+
isNetworkError(): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Convert error to a plain object for serialization
|
|
73
|
+
*/
|
|
74
|
+
toJSON(): {
|
|
75
|
+
name: string;
|
|
76
|
+
message: string;
|
|
77
|
+
status: number;
|
|
78
|
+
code?: string;
|
|
79
|
+
details?: Record<string, unknown> | null;
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Type guard to check if an error is a C15TError
|
|
84
|
+
*/
|
|
85
|
+
export declare function isC15TError(error: unknown): error is C15TError;
|
|
86
|
+
//# sourceMappingURL=error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,SAAU,SAAQ,KAAK;IACnC;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAElD;;OAEG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;gBAEb,OAAO,EAAE;QACpB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;QACzC,KAAK,CAAC,EAAE,OAAO,CAAC;KAChB;IAcD;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAIjC;;OAEG;IACH,UAAU,IAAI,OAAO;IAIrB;;OAEG;IACH,iBAAiB,IAAI,OAAO;IAI5B;;OAEG;IACH,cAAc,IAAI,OAAO;IAIzB;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACH,aAAa,IAAI,OAAO;IAIxB;;OAEG;IACH,cAAc,IAAI,OAAO;IAIzB;;OAEG;IACH,MAAM,IAAI;QACT,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;KACzC;CASD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CAE9D"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { FetchOptions, ResponseContext, RetryConfig } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Default retry configuration
|
|
4
|
+
*/
|
|
5
|
+
export declare const DEFAULT_RETRY_CONFIG: RetryConfig;
|
|
6
|
+
/**
|
|
7
|
+
* Default timeout in milliseconds (30 seconds)
|
|
8
|
+
*/
|
|
9
|
+
export declare const DEFAULT_TIMEOUT_MS = 30000;
|
|
10
|
+
/**
|
|
11
|
+
* Base context for fetcher operations
|
|
12
|
+
*/
|
|
13
|
+
export interface FetcherContext {
|
|
14
|
+
baseUrl: string;
|
|
15
|
+
headers: Record<string, string>;
|
|
16
|
+
retryConfig: RetryConfig;
|
|
17
|
+
debug: boolean;
|
|
18
|
+
timeout: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Creates a response context object with Result-like helper methods
|
|
22
|
+
*/
|
|
23
|
+
export declare function createResponseContext<T>(isSuccess: boolean, data?: T | null, error?: {
|
|
24
|
+
message: string;
|
|
25
|
+
status: number;
|
|
26
|
+
code?: string;
|
|
27
|
+
cause?: unknown;
|
|
28
|
+
details?: Record<string, unknown> | null;
|
|
29
|
+
} | null, response?: Response | null): ResponseContext<T>;
|
|
30
|
+
/**
|
|
31
|
+
* Resolves a URL path against the base URL
|
|
32
|
+
*/
|
|
33
|
+
export declare function resolveUrl(baseUrl: string, path: string): string;
|
|
34
|
+
/**
|
|
35
|
+
* Makes an HTTP request with retry logic
|
|
36
|
+
*/
|
|
37
|
+
export declare function fetcher<ResponseType, BodyType = unknown, QueryType = unknown>(context: FetcherContext, path: string, options?: FetchOptions<ResponseType, BodyType, QueryType>): Promise<ResponseContext<ResponseType>>;
|
|
38
|
+
//# sourceMappingURL=fetcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetcher.d.ts","sourceRoot":"","sources":["../src/fetcher.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE1E;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAE,WAOlC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB,QAAQ,CAAC;AAExC;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,WAAW,EAAE,WAAW,CAAC;IACzB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CAChB;AAsCD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EACtC,SAAS,EAAE,OAAO,EAClB,IAAI,GAAE,CAAC,GAAG,IAAW,EACrB,KAAK,GAAE;IACN,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CACzC,GAAG,IAAW,EACf,QAAQ,GAAE,QAAQ,GAAG,IAAW,GAC9B,eAAe,CAAC,CAAC,CAAC,CA2DpB;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMhE;AAED;;GAEG;AACH,wBAAsB,OAAO,CAC5B,YAAY,EACZ,QAAQ,GAAG,OAAO,EAClB,SAAS,GAAG,OAAO,EAEnB,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,YAAY,CAAC,YAAY,EAAE,QAAQ,EAAE,SAAS,CAAC,GACvD,OAAO,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC,CAkRxC"}
|
package/dist/index.cjs
CHANGED
|
@@ -24,30 +24,397 @@ var __webpack_require__ = {};
|
|
|
24
24
|
var __webpack_exports__ = {};
|
|
25
25
|
__webpack_require__.r(__webpack_exports__);
|
|
26
26
|
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
-
|
|
27
|
+
resolveUrl: ()=>resolveUrl,
|
|
28
|
+
c15tClient: ()=>c15tClient,
|
|
29
|
+
C15TClient: ()=>C15TClient,
|
|
30
|
+
createResponseContext: ()=>createResponseContext,
|
|
31
|
+
fetcher: ()=>fetcher,
|
|
32
|
+
isC15TError: ()=>isC15TError,
|
|
33
|
+
C15TError: ()=>C15TError
|
|
28
34
|
});
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
35
|
+
class C15TError extends Error {
|
|
36
|
+
status;
|
|
37
|
+
code;
|
|
38
|
+
details;
|
|
39
|
+
cause;
|
|
40
|
+
constructor(options){
|
|
41
|
+
super(options.message);
|
|
42
|
+
this.name = 'C15TError';
|
|
43
|
+
this.status = options.status;
|
|
44
|
+
this.code = options.code;
|
|
45
|
+
this.details = options.details;
|
|
46
|
+
this.cause = options.cause;
|
|
47
|
+
if (Error.captureStackTrace) Error.captureStackTrace(this, C15TError);
|
|
48
|
+
}
|
|
49
|
+
isStatus(status) {
|
|
50
|
+
return this.status === status;
|
|
51
|
+
}
|
|
52
|
+
isNotFound() {
|
|
53
|
+
return 404 === this.status || 'NOT_FOUND' === this.code;
|
|
54
|
+
}
|
|
55
|
+
isValidationError() {
|
|
56
|
+
return 400 === this.status || 'VALIDATION_ERROR' === this.code;
|
|
57
|
+
}
|
|
58
|
+
isUnauthorized() {
|
|
59
|
+
return 401 === this.status || 'UNAUTHORIZED' === this.code;
|
|
60
|
+
}
|
|
61
|
+
isForbidden() {
|
|
62
|
+
return 403 === this.status || 'FORBIDDEN' === this.code;
|
|
63
|
+
}
|
|
64
|
+
isServerError() {
|
|
65
|
+
return this.status >= 500 && this.status < 600;
|
|
66
|
+
}
|
|
67
|
+
isNetworkError() {
|
|
68
|
+
return 0 === this.status || 'NETWORK_ERROR' === this.code;
|
|
69
|
+
}
|
|
70
|
+
toJSON() {
|
|
71
|
+
return {
|
|
72
|
+
name: this.name,
|
|
73
|
+
message: this.message,
|
|
74
|
+
status: this.status,
|
|
75
|
+
code: this.code,
|
|
76
|
+
details: this.details
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function isC15TError(error) {
|
|
81
|
+
return error instanceof C15TError;
|
|
82
|
+
}
|
|
83
|
+
const DEFAULT_RETRY_CONFIG = {
|
|
84
|
+
maxRetries: 3,
|
|
85
|
+
initialDelayMs: 100,
|
|
86
|
+
backoffFactor: 2,
|
|
87
|
+
retryableStatusCodes: [
|
|
88
|
+
500,
|
|
89
|
+
502,
|
|
90
|
+
503,
|
|
91
|
+
504
|
|
92
|
+
],
|
|
93
|
+
nonRetryableStatusCodes: [
|
|
94
|
+
400,
|
|
95
|
+
401,
|
|
96
|
+
403,
|
|
97
|
+
404
|
|
98
|
+
],
|
|
99
|
+
retryOnNetworkError: true
|
|
100
|
+
};
|
|
101
|
+
const DEFAULT_TIMEOUT_MS = 30000;
|
|
102
|
+
function debugLog(debug, method, path, durationMs, status) {
|
|
103
|
+
if (!debug) return;
|
|
104
|
+
const timestamp = new Date().toISOString();
|
|
105
|
+
console.log(`[c15t] ${timestamp} ${method} ${path} (${durationMs}ms) -> ${status}`);
|
|
106
|
+
}
|
|
107
|
+
const delay = (ms)=>new Promise((resolve)=>setTimeout(resolve, ms));
|
|
108
|
+
function generateUUID() {
|
|
109
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c)=>{
|
|
110
|
+
const r = 16 * Math.random() | 0;
|
|
111
|
+
const v = 'x' === c ? r : 0x3 & r | 0x8;
|
|
112
|
+
return v.toString(16);
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
function createResponseContext(isSuccess, data = null, error = null, response = null) {
|
|
116
|
+
return {
|
|
117
|
+
data,
|
|
118
|
+
error,
|
|
119
|
+
ok: isSuccess,
|
|
120
|
+
response,
|
|
121
|
+
unwrap () {
|
|
122
|
+
if (!isSuccess || null === data) throw new C15TError({
|
|
123
|
+
message: error?.message || 'Request failed',
|
|
124
|
+
status: error?.status || 0,
|
|
125
|
+
code: error?.code,
|
|
126
|
+
details: error?.details,
|
|
127
|
+
cause: error?.cause
|
|
128
|
+
});
|
|
129
|
+
return data;
|
|
130
|
+
},
|
|
131
|
+
unwrapOr (defaultValue) {
|
|
132
|
+
if (!isSuccess || null === data) return defaultValue;
|
|
133
|
+
return data;
|
|
134
|
+
},
|
|
135
|
+
expect (message) {
|
|
136
|
+
if (!isSuccess || null === data) throw new C15TError({
|
|
137
|
+
message,
|
|
138
|
+
status: error?.status || 0,
|
|
139
|
+
code: error?.code,
|
|
140
|
+
details: error?.details,
|
|
141
|
+
cause: error?.cause
|
|
142
|
+
});
|
|
143
|
+
return data;
|
|
144
|
+
},
|
|
145
|
+
map (fn) {
|
|
146
|
+
if (!isSuccess || null === data) return createResponseContext(false, null, error, response);
|
|
147
|
+
return createResponseContext(true, fn(data), null, response);
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
function resolveUrl(baseUrl, path) {
|
|
152
|
+
const cleanBase = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
|
|
153
|
+
const cleanPath = path.startsWith('/') ? path.slice(1) : path;
|
|
154
|
+
return `${cleanBase}/${cleanPath}`;
|
|
155
|
+
}
|
|
156
|
+
async function fetcher(context, path, options) {
|
|
157
|
+
const finalRetryConfig = {
|
|
158
|
+
...DEFAULT_RETRY_CONFIG,
|
|
159
|
+
...context.retryConfig,
|
|
160
|
+
...options?.retryConfig || {}
|
|
161
|
+
};
|
|
162
|
+
const { maxRetries = 3, initialDelayMs = 100, backoffFactor = 2, retryableStatusCodes = [
|
|
163
|
+
500,
|
|
164
|
+
502,
|
|
165
|
+
503,
|
|
166
|
+
504
|
|
167
|
+
], nonRetryableStatusCodes = [
|
|
168
|
+
400,
|
|
169
|
+
401,
|
|
170
|
+
403,
|
|
171
|
+
404
|
|
172
|
+
], retryOnNetworkError = true } = finalRetryConfig;
|
|
173
|
+
let attemptsMade = 0;
|
|
174
|
+
let currentDelay = initialDelayMs;
|
|
175
|
+
let lastErrorResponse = null;
|
|
176
|
+
while(attemptsMade <= maxRetries){
|
|
177
|
+
const requestId = generateUUID();
|
|
178
|
+
const resolvedUrl = resolveUrl(context.baseUrl, path);
|
|
179
|
+
const url = new URL(resolvedUrl);
|
|
180
|
+
if (options?.query) {
|
|
181
|
+
for (const [key, value] of Object.entries(options.query))if (null != value) url.searchParams.append(key, String(value));
|
|
182
|
+
}
|
|
183
|
+
const timeoutMs = options?.timeout ?? context.timeout;
|
|
184
|
+
const controller = new AbortController();
|
|
185
|
+
let timeoutId;
|
|
186
|
+
if (timeoutMs > 0) timeoutId = setTimeout(()=>controller.abort(), timeoutMs);
|
|
187
|
+
const requestOptions = {
|
|
188
|
+
method: options?.method || 'GET',
|
|
189
|
+
headers: {
|
|
190
|
+
'Content-Type': 'application/json',
|
|
191
|
+
...context.headers,
|
|
192
|
+
'X-Request-ID': requestId,
|
|
193
|
+
...options?.headers
|
|
194
|
+
},
|
|
195
|
+
signal: controller.signal
|
|
196
|
+
};
|
|
197
|
+
if (options?.body && 'GET' !== requestOptions.method) requestOptions.body = JSON.stringify(options.body);
|
|
198
|
+
const startTime = Date.now();
|
|
199
|
+
try {
|
|
200
|
+
const response = await fetch(url.toString(), requestOptions);
|
|
201
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
202
|
+
const durationMs = Date.now() - startTime;
|
|
203
|
+
let data = null;
|
|
204
|
+
let parseError = null;
|
|
205
|
+
try {
|
|
206
|
+
const contentType = response.headers.get('content-type');
|
|
207
|
+
if (contentType?.includes('application/json') && 204 !== response.status && '0' !== response.headers.get('content-length')) data = await response.json();
|
|
208
|
+
else if (204 === response.status) data = null;
|
|
209
|
+
} catch (err) {
|
|
210
|
+
parseError = err;
|
|
211
|
+
}
|
|
212
|
+
if (parseError) {
|
|
213
|
+
const errorResponse = createResponseContext(false, null, {
|
|
214
|
+
message: 'Failed to parse response',
|
|
215
|
+
status: response.status,
|
|
216
|
+
code: 'PARSE_ERROR',
|
|
217
|
+
cause: parseError
|
|
218
|
+
}, response);
|
|
219
|
+
options?.onError?.(errorResponse, path);
|
|
220
|
+
if (options?.throw) throw new Error('Failed to parse response');
|
|
221
|
+
return errorResponse;
|
|
222
|
+
}
|
|
223
|
+
const isSuccess = response.status >= 200 && response.status < 300;
|
|
224
|
+
if (isSuccess) {
|
|
225
|
+
debugLog(context.debug, requestOptions.method || 'GET', path, durationMs, response.status);
|
|
226
|
+
const successResponse = createResponseContext(true, data, null, response);
|
|
227
|
+
options?.onSuccess?.(successResponse);
|
|
228
|
+
return successResponse;
|
|
229
|
+
}
|
|
230
|
+
const errorData = data;
|
|
231
|
+
const errorResponse = createResponseContext(false, null, {
|
|
232
|
+
message: errorData?.message || `Request failed with status ${response.status}`,
|
|
233
|
+
status: response.status,
|
|
234
|
+
code: errorData?.code || 'API_ERROR',
|
|
235
|
+
details: errorData?.details || null
|
|
236
|
+
}, response);
|
|
237
|
+
lastErrorResponse = errorResponse;
|
|
238
|
+
let shouldRetryThisRequest = false;
|
|
239
|
+
shouldRetryThisRequest = nonRetryableStatusCodes.includes(response.status) ? false : retryableStatusCodes.includes(response.status);
|
|
240
|
+
if (!shouldRetryThisRequest || attemptsMade >= maxRetries) {
|
|
241
|
+
debugLog(context.debug, requestOptions.method || 'GET', path, durationMs, response.status);
|
|
242
|
+
options?.onError?.(errorResponse, path);
|
|
243
|
+
if (options?.throw) throw new Error(errorResponse.error?.message || 'Request failed');
|
|
244
|
+
return errorResponse;
|
|
245
|
+
}
|
|
246
|
+
attemptsMade++;
|
|
247
|
+
await delay(currentDelay);
|
|
248
|
+
currentDelay *= backoffFactor;
|
|
249
|
+
} catch (fetchError) {
|
|
250
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
251
|
+
if (fetchError instanceof Error && 'Failed to parse response' === fetchError.message) throw fetchError;
|
|
252
|
+
const isAbortError = fetchError instanceof Error && 'AbortError' === fetchError.name;
|
|
253
|
+
const isNetworkError = !(fetchError instanceof Response);
|
|
254
|
+
const errorResponse = createResponseContext(false, null, {
|
|
255
|
+
message: isAbortError ? `Request timed out after ${timeoutMs}ms` : fetchError instanceof Error ? fetchError.message : String(fetchError),
|
|
256
|
+
status: 0,
|
|
257
|
+
code: isAbortError ? 'TIMEOUT' : 'NETWORK_ERROR',
|
|
258
|
+
cause: fetchError
|
|
259
|
+
}, null);
|
|
260
|
+
lastErrorResponse = errorResponse;
|
|
261
|
+
const shouldRetryThisRequest = isNetworkError && retryOnNetworkError;
|
|
262
|
+
if (!shouldRetryThisRequest || attemptsMade >= maxRetries) {
|
|
263
|
+
debugLog(context.debug, requestOptions.method || 'GET', path, Date.now() - startTime, 'ERROR');
|
|
264
|
+
options?.onError?.(errorResponse, path);
|
|
265
|
+
if (options?.throw) throw fetchError;
|
|
266
|
+
return errorResponse;
|
|
267
|
+
}
|
|
268
|
+
attemptsMade++;
|
|
269
|
+
await delay(currentDelay);
|
|
270
|
+
currentDelay *= backoffFactor;
|
|
43
271
|
}
|
|
272
|
+
}
|
|
273
|
+
const maxRetriesErrorResponse = lastErrorResponse || createResponseContext(false, null, {
|
|
274
|
+
message: `Request failed after ${maxRetries} retries`,
|
|
275
|
+
status: 0,
|
|
276
|
+
code: 'MAX_RETRIES_EXCEEDED'
|
|
277
|
+
}, null);
|
|
278
|
+
options?.onError?.(maxRetriesErrorResponse, path);
|
|
279
|
+
if (options?.throw) throw new Error(`Request failed after ${maxRetries} retries`);
|
|
280
|
+
return maxRetriesErrorResponse;
|
|
281
|
+
}
|
|
282
|
+
const CONSENT_CHECK_PATH = '/consents/check';
|
|
283
|
+
async function checkConsent(context, query, options) {
|
|
284
|
+
return fetcher(context, CONSENT_CHECK_PATH, {
|
|
285
|
+
method: 'GET',
|
|
286
|
+
query,
|
|
287
|
+
...options
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
const INIT_PATH = '/init';
|
|
291
|
+
async function init(context, options) {
|
|
292
|
+
return fetcher(context, INIT_PATH, {
|
|
293
|
+
method: 'GET',
|
|
294
|
+
...options
|
|
44
295
|
});
|
|
45
|
-
return (0, client_namespaceObject.createORPCClient)(link);
|
|
46
296
|
}
|
|
297
|
+
const STATUS_PATH = '/status';
|
|
298
|
+
async function status_status(context, options) {
|
|
299
|
+
return fetcher(context, STATUS_PATH, {
|
|
300
|
+
method: 'GET',
|
|
301
|
+
...options
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
const SUBJECTS_PATH = '/subjects';
|
|
305
|
+
async function createSubject(context, input, options) {
|
|
306
|
+
return fetcher(context, SUBJECTS_PATH, {
|
|
307
|
+
method: 'POST',
|
|
308
|
+
body: input,
|
|
309
|
+
...options
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
async function getSubject(context, id, query, options) {
|
|
313
|
+
return fetcher(context, `${SUBJECTS_PATH}/${id}`, {
|
|
314
|
+
method: 'GET',
|
|
315
|
+
query,
|
|
316
|
+
...options
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
async function patchSubject(context, id, input, options) {
|
|
320
|
+
return fetcher(context, `${SUBJECTS_PATH}/${id}`, {
|
|
321
|
+
method: 'PATCH',
|
|
322
|
+
body: input,
|
|
323
|
+
...options
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
async function listSubjects(context, query, options) {
|
|
327
|
+
return fetcher(context, SUBJECTS_PATH, {
|
|
328
|
+
method: 'GET',
|
|
329
|
+
query,
|
|
330
|
+
...options
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
class C15TClient {
|
|
334
|
+
context;
|
|
335
|
+
constructor(options = {}){
|
|
336
|
+
const baseUrlString = options.baseUrl || ('undefined' != typeof process ? process.env?.C15T_API_URL : void 0);
|
|
337
|
+
if (!baseUrlString) throw new TypeError('baseUrl is required. Provide it in options or set C15T_API_URL environment variable.');
|
|
338
|
+
const baseUrl = new URL(baseUrlString);
|
|
339
|
+
if (options.prefix) baseUrl.pathname = options.prefix;
|
|
340
|
+
const token = options.token || ('undefined' != typeof process ? process.env?.C15T_API_TOKEN : void 0);
|
|
341
|
+
const authHeaders = token ? {
|
|
342
|
+
Authorization: `Bearer ${token}`
|
|
343
|
+
} : {};
|
|
344
|
+
const retryConfig = {
|
|
345
|
+
...DEFAULT_RETRY_CONFIG,
|
|
346
|
+
...options.retryConfig
|
|
347
|
+
};
|
|
348
|
+
const debug = options.debug ?? ('undefined' != typeof process ? process.env?.C15T_DEBUG === 'true' : false);
|
|
349
|
+
const timeout = options.timeout ?? DEFAULT_TIMEOUT_MS;
|
|
350
|
+
this.context = {
|
|
351
|
+
baseUrl: baseUrl.toString(),
|
|
352
|
+
headers: {
|
|
353
|
+
...authHeaders,
|
|
354
|
+
...options.headers
|
|
355
|
+
},
|
|
356
|
+
retryConfig,
|
|
357
|
+
debug,
|
|
358
|
+
timeout
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
async status(options) {
|
|
362
|
+
return status_status(this.context, options);
|
|
363
|
+
}
|
|
364
|
+
async init(options) {
|
|
365
|
+
return init(this.context, options);
|
|
366
|
+
}
|
|
367
|
+
async createSubject(input, options) {
|
|
368
|
+
return createSubject(this.context, input, options);
|
|
369
|
+
}
|
|
370
|
+
async getSubject(id, query, options) {
|
|
371
|
+
return getSubject(this.context, id, query, options);
|
|
372
|
+
}
|
|
373
|
+
async patchSubject(id, input, options) {
|
|
374
|
+
return patchSubject(this.context, id, input, options);
|
|
375
|
+
}
|
|
376
|
+
async listSubjects(query, options) {
|
|
377
|
+
return listSubjects(this.context, query, options);
|
|
378
|
+
}
|
|
379
|
+
async checkConsent(query, options) {
|
|
380
|
+
return checkConsent(this.context, query, options);
|
|
381
|
+
}
|
|
382
|
+
async $fetch(path, options) {
|
|
383
|
+
return fetcher(this.context, path, options);
|
|
384
|
+
}
|
|
385
|
+
consent = {
|
|
386
|
+
check: (query, options)=>this.checkConsent(query, options)
|
|
387
|
+
};
|
|
388
|
+
subjects = {
|
|
389
|
+
create: (input, options)=>this.createSubject(input, options),
|
|
390
|
+
get: (id, query, options)=>this.getSubject(id, query, options),
|
|
391
|
+
patch: (id, input, options)=>this.patchSubject(id, input, options),
|
|
392
|
+
list: (query, options)=>this.listSubjects(query, options)
|
|
393
|
+
};
|
|
394
|
+
meta = {
|
|
395
|
+
status: (options)=>this.status(options),
|
|
396
|
+
init: (options)=>this.init(options)
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
function c15tClient(options) {
|
|
400
|
+
return new C15TClient(options);
|
|
401
|
+
}
|
|
402
|
+
exports.C15TClient = __webpack_exports__.C15TClient;
|
|
403
|
+
exports.C15TError = __webpack_exports__.C15TError;
|
|
47
404
|
exports.c15tClient = __webpack_exports__.c15tClient;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
405
|
+
exports.createResponseContext = __webpack_exports__.createResponseContext;
|
|
406
|
+
exports.fetcher = __webpack_exports__.fetcher;
|
|
407
|
+
exports.isC15TError = __webpack_exports__.isC15TError;
|
|
408
|
+
exports.resolveUrl = __webpack_exports__.resolveUrl;
|
|
409
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
410
|
+
"C15TClient",
|
|
411
|
+
"C15TError",
|
|
412
|
+
"c15tClient",
|
|
413
|
+
"createResponseContext",
|
|
414
|
+
"fetcher",
|
|
415
|
+
"isC15TError",
|
|
416
|
+
"resolveUrl"
|
|
417
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
51
418
|
Object.defineProperty(exports, '__esModule', {
|
|
52
419
|
value: true
|
|
53
420
|
});
|