perspectapi-ts-sdk 1.5.2 → 2.1.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 +148 -0
- package/dist/index.d.mts +154 -22
- package/dist/index.d.ts +154 -22
- package/dist/index.js +510 -70
- package/dist/index.mjs +507 -70
- package/package.json +1 -1
- package/src/cache/cache-manager.ts +302 -0
- package/src/cache/in-memory-adapter.ts +49 -0
- package/src/cache/noop-adapter.ts +27 -0
- package/src/cache/types.ts +78 -0
- package/src/client/api-keys-client.ts +3 -2
- package/src/client/auth-client.ts +3 -2
- package/src/client/base-client.ts +88 -1
- package/src/client/categories-client.ts +34 -10
- package/src/client/checkout-client.ts +3 -2
- package/src/client/contact-client.ts +3 -2
- package/src/client/content-client.ts +59 -10
- package/src/client/newsletter-client.ts +4 -3
- package/src/client/organizations-client.ts +3 -2
- package/src/client/products-client.ts +115 -22
- package/src/client/sites-client.ts +3 -2
- package/src/client/webhooks-client.ts +3 -2
- package/src/index.ts +5 -0
- package/src/perspect-api-client.ts +14 -11
- package/src/types/index.ts +6 -0
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { BaseClient } from './base-client';
|
|
6
|
+
import type { CacheManager } from '../cache/cache-manager';
|
|
6
7
|
import type {
|
|
7
8
|
ContactSubmission,
|
|
8
9
|
CreateContactRequest,
|
|
@@ -13,8 +14,8 @@ import type {
|
|
|
13
14
|
} from '../types';
|
|
14
15
|
|
|
15
16
|
export class ContactClient extends BaseClient {
|
|
16
|
-
constructor(http: any) {
|
|
17
|
-
super(http, '/api/v1');
|
|
17
|
+
constructor(http: any, cache?: CacheManager) {
|
|
18
|
+
super(http, '/api/v1', cache);
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
/**
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { BaseClient } from './base-client';
|
|
6
|
+
import type { CacheManager } from '../cache/cache-manager';
|
|
7
|
+
import type { CachePolicy } from '../cache/types';
|
|
6
8
|
import type {
|
|
7
9
|
Content,
|
|
8
10
|
CreateContentRequest,
|
|
@@ -13,31 +15,64 @@ import type {
|
|
|
13
15
|
} from '../types';
|
|
14
16
|
|
|
15
17
|
export class ContentClient extends BaseClient {
|
|
16
|
-
constructor(http: any) {
|
|
17
|
-
super(http, '/api/v1');
|
|
18
|
+
constructor(http: any, cache?: CacheManager) {
|
|
19
|
+
super(http, '/api/v1', cache);
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
/**
|
|
21
23
|
* Get all content with pagination and filtering for a site
|
|
22
24
|
*/
|
|
23
|
-
async getContent(
|
|
24
|
-
|
|
25
|
+
async getContent(
|
|
26
|
+
siteName: string,
|
|
27
|
+
params?: ContentQueryParams,
|
|
28
|
+
cachePolicy?: CachePolicy
|
|
29
|
+
): Promise<PaginatedResponse<Content>> {
|
|
30
|
+
const endpoint = this.siteScopedEndpoint(siteName);
|
|
31
|
+
const path = this.buildPath(endpoint);
|
|
32
|
+
|
|
33
|
+
return this.fetchWithCache<PaginatedResponse<Content>>(
|
|
34
|
+
endpoint,
|
|
35
|
+
params,
|
|
36
|
+
this.buildContentTags(siteName),
|
|
37
|
+
cachePolicy,
|
|
38
|
+
() => this.http.get(path, params) as Promise<PaginatedResponse<Content>>
|
|
39
|
+
);
|
|
25
40
|
}
|
|
26
41
|
|
|
27
42
|
/**
|
|
28
43
|
* Get content by ID
|
|
29
44
|
*/
|
|
30
|
-
async getContentById(id: number): Promise<ApiResponse<Content>> {
|
|
31
|
-
|
|
45
|
+
async getContentById(id: number, cachePolicy?: CachePolicy): Promise<ApiResponse<Content>> {
|
|
46
|
+
const endpoint = `/content/${id}`;
|
|
47
|
+
const path = this.buildPath(endpoint);
|
|
48
|
+
|
|
49
|
+
return this.fetchWithCache<ApiResponse<Content>>(
|
|
50
|
+
endpoint,
|
|
51
|
+
undefined,
|
|
52
|
+
this.buildContentTags(undefined, undefined, id),
|
|
53
|
+
cachePolicy,
|
|
54
|
+
() => this.http.get<Content>(path)
|
|
55
|
+
);
|
|
32
56
|
}
|
|
33
57
|
|
|
34
58
|
/**
|
|
35
59
|
* Get content by slug for a site
|
|
36
60
|
*/
|
|
37
|
-
async getContentBySlug(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
61
|
+
async getContentBySlug(
|
|
62
|
+
siteName: string,
|
|
63
|
+
slug: string,
|
|
64
|
+
cachePolicy?: CachePolicy
|
|
65
|
+
): Promise<ApiResponse<Content>> {
|
|
66
|
+
const endpoint = this.siteScopedEndpoint(siteName, `/slug/${encodeURIComponent(slug)}`);
|
|
67
|
+
const path = this.buildPath(endpoint);
|
|
68
|
+
|
|
69
|
+
return this.fetchWithCache<ApiResponse<Content>>(
|
|
70
|
+
endpoint,
|
|
71
|
+
undefined,
|
|
72
|
+
this.buildContentTags(siteName, slug),
|
|
73
|
+
cachePolicy,
|
|
74
|
+
() => this.http.get<Content>(path)
|
|
75
|
+
);
|
|
41
76
|
}
|
|
42
77
|
|
|
43
78
|
/**
|
|
@@ -109,4 +144,18 @@ export class ContentClient extends BaseClient {
|
|
|
109
144
|
async duplicateContent(id: number): Promise<ApiResponse<Content>> {
|
|
110
145
|
return this.create<Record<string, never>, Content>(`/content/${id}/duplicate`, {});
|
|
111
146
|
}
|
|
147
|
+
|
|
148
|
+
private buildContentTags(siteName?: string, slug?: string, id?: number): string[] {
|
|
149
|
+
const tags = new Set<string>(['content']);
|
|
150
|
+
if (siteName) {
|
|
151
|
+
tags.add(`content:site:${siteName}`);
|
|
152
|
+
}
|
|
153
|
+
if (slug) {
|
|
154
|
+
tags.add(`content:slug:${siteName}:${slug}`);
|
|
155
|
+
}
|
|
156
|
+
if (typeof id === 'number') {
|
|
157
|
+
tags.add(`content:id:${id}`);
|
|
158
|
+
}
|
|
159
|
+
return Array.from(tags.values());
|
|
160
|
+
}
|
|
112
161
|
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { BaseClient } from './base-client';
|
|
6
|
+
import type { CacheManager } from '../cache/cache-manager';
|
|
6
7
|
import type {
|
|
7
8
|
NewsletterSubscription,
|
|
8
9
|
CreateNewsletterSubscriptionRequest,
|
|
@@ -18,8 +19,8 @@ import type {
|
|
|
18
19
|
} from '../types';
|
|
19
20
|
|
|
20
21
|
export class NewsletterClient extends BaseClient {
|
|
21
|
-
constructor(http: any) {
|
|
22
|
-
super(http, '/api/v1');
|
|
22
|
+
constructor(http: any, cache?: CacheManager) {
|
|
23
|
+
super(http, '/api/v1', cache);
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
/**
|
|
@@ -379,4 +380,4 @@ export class NewsletterClient extends BaseClient {
|
|
|
379
380
|
data
|
|
380
381
|
);
|
|
381
382
|
}
|
|
382
|
-
}
|
|
383
|
+
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { BaseClient } from './base-client';
|
|
6
|
+
import type { CacheManager } from '../cache/cache-manager';
|
|
6
7
|
import type {
|
|
7
8
|
Organization,
|
|
8
9
|
CreateOrganizationRequest,
|
|
@@ -11,8 +12,8 @@ import type {
|
|
|
11
12
|
} from '../types';
|
|
12
13
|
|
|
13
14
|
export class OrganizationsClient extends BaseClient {
|
|
14
|
-
constructor(http: any) {
|
|
15
|
-
super(http, '/api/v1');
|
|
15
|
+
constructor(http: any, cache?: CacheManager) {
|
|
16
|
+
super(http, '/api/v1', cache);
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
/**
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { BaseClient } from './base-client';
|
|
6
|
+
import type { CacheManager } from '../cache/cache-manager';
|
|
7
|
+
import type { CachePolicy } from '../cache/types';
|
|
6
8
|
import type {
|
|
7
9
|
Product,
|
|
8
10
|
CreateProductRequest,
|
|
@@ -12,14 +14,18 @@ import type {
|
|
|
12
14
|
} from '../types';
|
|
13
15
|
|
|
14
16
|
export class ProductsClient extends BaseClient {
|
|
15
|
-
constructor(http: any) {
|
|
16
|
-
super(http, '/api/v1');
|
|
17
|
+
constructor(http: any, cache?: CacheManager) {
|
|
18
|
+
super(http, '/api/v1', cache);
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
/**
|
|
20
22
|
* Get all products for a site
|
|
21
23
|
*/
|
|
22
|
-
async getProducts(
|
|
24
|
+
async getProducts(
|
|
25
|
+
siteName: string,
|
|
26
|
+
params?: ProductQueryParams,
|
|
27
|
+
cachePolicy?: CachePolicy
|
|
28
|
+
): Promise<PaginatedResponse<Product>> {
|
|
23
29
|
const normalizeList = (value: string | number | Array<string | number> | undefined): string | undefined => {
|
|
24
30
|
if (value === undefined || value === null) {
|
|
25
31
|
return undefined;
|
|
@@ -50,33 +56,72 @@ export class ProductsClient extends BaseClient {
|
|
|
50
56
|
}
|
|
51
57
|
}
|
|
52
58
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
59
|
+
const endpoint = this.siteScopedEndpoint(siteName, '/products', { includeSitesSegment: false });
|
|
60
|
+
const path = this.buildPath(endpoint);
|
|
61
|
+
|
|
62
|
+
return this.fetchWithCache<PaginatedResponse<Product>>(
|
|
63
|
+
endpoint,
|
|
64
|
+
normalizedParams,
|
|
65
|
+
this.buildProductTags(siteName, ['products:list']),
|
|
66
|
+
cachePolicy,
|
|
67
|
+
() => this.http.get(path, normalizedParams) as Promise<PaginatedResponse<Product>>
|
|
56
68
|
);
|
|
57
69
|
}
|
|
58
70
|
|
|
59
71
|
/**
|
|
60
72
|
* Get product by ID
|
|
61
73
|
*/
|
|
62
|
-
async getProductById(id: number): Promise<ApiResponse<Product>> {
|
|
63
|
-
|
|
74
|
+
async getProductById(id: number, cachePolicy?: CachePolicy): Promise<ApiResponse<Product>> {
|
|
75
|
+
const endpoint = `/products/${id}`;
|
|
76
|
+
const path = this.buildPath(endpoint);
|
|
77
|
+
|
|
78
|
+
return this.fetchWithCache<ApiResponse<Product>>(
|
|
79
|
+
endpoint,
|
|
80
|
+
undefined,
|
|
81
|
+
this.buildProductTags(undefined, [`products:id:${id}`]),
|
|
82
|
+
cachePolicy,
|
|
83
|
+
() => this.http.get<Product>(path)
|
|
84
|
+
);
|
|
64
85
|
}
|
|
65
86
|
|
|
66
87
|
/**
|
|
67
88
|
* Get product by SKU
|
|
68
89
|
*/
|
|
69
|
-
async getProductBySku(sku: string): Promise<ApiResponse<Product>> {
|
|
70
|
-
|
|
90
|
+
async getProductBySku(sku: string, cachePolicy?: CachePolicy): Promise<ApiResponse<Product>> {
|
|
91
|
+
const endpoint = `/products/sku/${encodeURIComponent(sku)}`;
|
|
92
|
+
const path = this.buildPath(endpoint);
|
|
93
|
+
|
|
94
|
+
return this.fetchWithCache<ApiResponse<Product>>(
|
|
95
|
+
endpoint,
|
|
96
|
+
undefined,
|
|
97
|
+
this.buildProductTags(undefined, [`products:sku:${sku.toLowerCase()}`]),
|
|
98
|
+
cachePolicy,
|
|
99
|
+
() => this.http.get<Product>(path)
|
|
100
|
+
);
|
|
71
101
|
}
|
|
72
102
|
|
|
73
103
|
/**
|
|
74
104
|
* Get product by slug and site name
|
|
75
105
|
*/
|
|
76
|
-
async getProductBySlug(
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
106
|
+
async getProductBySlug(
|
|
107
|
+
siteName: string,
|
|
108
|
+
slug: string,
|
|
109
|
+
cachePolicy?: CachePolicy
|
|
110
|
+
): Promise<ApiResponse<Product & { variants?: any[] }>> {
|
|
111
|
+
const endpoint = this.siteScopedEndpoint(
|
|
112
|
+
siteName,
|
|
113
|
+
`/products/slug/${encodeURIComponent(slug)}`,
|
|
114
|
+
{ includeSitesSegment: false }
|
|
115
|
+
);
|
|
116
|
+
const path = this.buildPath(endpoint);
|
|
117
|
+
|
|
118
|
+
return this.fetchWithCache<ApiResponse<Product & { variants?: any[] }>>(
|
|
119
|
+
endpoint,
|
|
120
|
+
undefined,
|
|
121
|
+
this.buildProductTags(siteName, [`products:slug:${siteName}:${slug}`]),
|
|
122
|
+
cachePolicy,
|
|
123
|
+
() => this.http.get<Product & { variants?: any[] }>(path)
|
|
124
|
+
);
|
|
80
125
|
}
|
|
81
126
|
|
|
82
127
|
/**
|
|
@@ -221,7 +266,8 @@ export class ProductsClient extends BaseClient {
|
|
|
221
266
|
limit?: number;
|
|
222
267
|
published?: boolean;
|
|
223
268
|
search?: string;
|
|
224
|
-
}
|
|
269
|
+
},
|
|
270
|
+
cachePolicy?: CachePolicy
|
|
225
271
|
): Promise<ApiResponse<{
|
|
226
272
|
data: Product[];
|
|
227
273
|
category: {
|
|
@@ -243,12 +289,59 @@ export class ProductsClient extends BaseClient {
|
|
|
243
289
|
search: params.search
|
|
244
290
|
} : undefined;
|
|
245
291
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
292
|
+
const endpoint = this.siteScopedEndpoint(
|
|
293
|
+
siteName,
|
|
294
|
+
`/products/category/${encodeURIComponent(categorySlug)}`,
|
|
295
|
+
{ includeSitesSegment: false }
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
const path = this.buildPath(endpoint);
|
|
299
|
+
|
|
300
|
+
return this.fetchWithCache<ApiResponse<{
|
|
301
|
+
data: Product[];
|
|
302
|
+
category: {
|
|
303
|
+
id: number;
|
|
304
|
+
name: string;
|
|
305
|
+
slug: string;
|
|
306
|
+
description?: string;
|
|
307
|
+
};
|
|
308
|
+
meta: {
|
|
309
|
+
count: number;
|
|
310
|
+
limit?: number;
|
|
311
|
+
offset?: number;
|
|
312
|
+
};
|
|
313
|
+
}>>(
|
|
314
|
+
endpoint,
|
|
315
|
+
queryParams,
|
|
316
|
+
this.buildProductTags(siteName, [
|
|
317
|
+
'products:category',
|
|
318
|
+
`products:category:${siteName}:${categorySlug}`,
|
|
319
|
+
]),
|
|
320
|
+
cachePolicy,
|
|
321
|
+
() =>
|
|
322
|
+
this.http.get<{
|
|
323
|
+
data: Product[];
|
|
324
|
+
category: {
|
|
325
|
+
id: number;
|
|
326
|
+
name: string;
|
|
327
|
+
slug: string;
|
|
328
|
+
description?: string;
|
|
329
|
+
};
|
|
330
|
+
meta: {
|
|
331
|
+
count: number;
|
|
332
|
+
limit?: number;
|
|
333
|
+
offset?: number;
|
|
334
|
+
};
|
|
335
|
+
}>(path, queryParams)
|
|
336
|
+
);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
private buildProductTags(siteName?: string, extraTags: string[] = []): string[] {
|
|
340
|
+
const tags = new Set<string>(['products']);
|
|
341
|
+
if (siteName) {
|
|
342
|
+
tags.add(`products:site:${siteName}`);
|
|
343
|
+
}
|
|
344
|
+
extraTags.filter(Boolean).forEach(tag => tags.add(tag));
|
|
345
|
+
return Array.from(tags.values());
|
|
253
346
|
}
|
|
254
347
|
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { BaseClient } from './base-client';
|
|
6
|
+
import type { CacheManager } from '../cache/cache-manager';
|
|
6
7
|
import type {
|
|
7
8
|
Site,
|
|
8
9
|
CreateSiteRequest,
|
|
@@ -11,8 +12,8 @@ import type {
|
|
|
11
12
|
} from '../types';
|
|
12
13
|
|
|
13
14
|
export class SitesClient extends BaseClient {
|
|
14
|
-
constructor(http: any) {
|
|
15
|
-
super(http, '/api/v1');
|
|
15
|
+
constructor(http: any, cache?: CacheManager) {
|
|
16
|
+
super(http, '/api/v1', cache);
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
/**
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { BaseClient } from './base-client';
|
|
6
|
+
import type { CacheManager } from '../cache/cache-manager';
|
|
6
7
|
import type {
|
|
7
8
|
Webhook,
|
|
8
9
|
CreateWebhookRequest,
|
|
@@ -11,8 +12,8 @@ import type {
|
|
|
11
12
|
} from '../types';
|
|
12
13
|
|
|
13
14
|
export class WebhooksClient extends BaseClient {
|
|
14
|
-
constructor(http: any) {
|
|
15
|
-
super(http, '/api/v1');
|
|
15
|
+
constructor(http: any, cache?: CacheManager) {
|
|
16
|
+
super(http, '/api/v1', cache);
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
/**
|
package/src/index.ts
CHANGED
|
@@ -26,6 +26,11 @@ export { BaseClient } from './client/base-client';
|
|
|
26
26
|
// Utilities
|
|
27
27
|
export { HttpClient, createApiError } from './utils/http-client';
|
|
28
28
|
|
|
29
|
+
// Cache utilities
|
|
30
|
+
export { CacheManager } from './cache/cache-manager';
|
|
31
|
+
export { InMemoryCacheAdapter } from './cache/in-memory-adapter';
|
|
32
|
+
export { NoopCacheAdapter } from './cache/noop-adapter';
|
|
33
|
+
|
|
29
34
|
// Image transformation utilities
|
|
30
35
|
export {
|
|
31
36
|
buildImageUrl,
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { HttpClient } from './utils/http-client';
|
|
7
|
+
import { CacheManager } from './cache/cache-manager';
|
|
7
8
|
import { AuthClient } from './client/auth-client';
|
|
8
9
|
import { ContentClient } from './client/content-client';
|
|
9
10
|
import { ApiKeysClient } from './client/api-keys-client';
|
|
@@ -20,6 +21,7 @@ import type { PerspectApiConfig, ApiResponse } from './types';
|
|
|
20
21
|
|
|
21
22
|
export class PerspectApiClient {
|
|
22
23
|
private http: HttpClient;
|
|
24
|
+
public readonly cache: CacheManager;
|
|
23
25
|
|
|
24
26
|
// Service clients
|
|
25
27
|
public readonly auth: AuthClient;
|
|
@@ -42,19 +44,20 @@ export class PerspectApiClient {
|
|
|
42
44
|
|
|
43
45
|
// Initialize HTTP client
|
|
44
46
|
this.http = new HttpClient(config);
|
|
47
|
+
this.cache = new CacheManager(config.cache);
|
|
45
48
|
|
|
46
49
|
// Initialize service clients
|
|
47
|
-
this.auth = new AuthClient(this.http);
|
|
48
|
-
this.content = new ContentClient(this.http);
|
|
49
|
-
this.apiKeys = new ApiKeysClient(this.http);
|
|
50
|
-
this.organizations = new OrganizationsClient(this.http);
|
|
51
|
-
this.sites = new SitesClient(this.http);
|
|
52
|
-
this.products = new ProductsClient(this.http);
|
|
53
|
-
this.categories = new CategoriesClient(this.http);
|
|
54
|
-
this.webhooks = new WebhooksClient(this.http);
|
|
55
|
-
this.checkout = new CheckoutClient(this.http);
|
|
56
|
-
this.contact = new ContactClient(this.http);
|
|
57
|
-
this.newsletter = new NewsletterClient(this.http);
|
|
50
|
+
this.auth = new AuthClient(this.http, this.cache);
|
|
51
|
+
this.content = new ContentClient(this.http, this.cache);
|
|
52
|
+
this.apiKeys = new ApiKeysClient(this.http, this.cache);
|
|
53
|
+
this.organizations = new OrganizationsClient(this.http, this.cache);
|
|
54
|
+
this.sites = new SitesClient(this.http, this.cache);
|
|
55
|
+
this.products = new ProductsClient(this.http, this.cache);
|
|
56
|
+
this.categories = new CategoriesClient(this.http, this.cache);
|
|
57
|
+
this.webhooks = new WebhooksClient(this.http, this.cache);
|
|
58
|
+
this.checkout = new CheckoutClient(this.http, this.cache);
|
|
59
|
+
this.contact = new ContactClient(this.http, this.cache);
|
|
60
|
+
this.newsletter = new NewsletterClient(this.http, this.cache);
|
|
58
61
|
}
|
|
59
62
|
|
|
60
63
|
/**
|
package/src/types/index.ts
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* Core types and interfaces for PerspectAPI SDK
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import type { CacheConfig } from '../cache/types';
|
|
6
|
+
|
|
5
7
|
// Base API Response
|
|
6
8
|
export interface ApiResponse<T = any> {
|
|
7
9
|
data?: T;
|
|
@@ -495,6 +497,7 @@ export interface PerspectApiConfig {
|
|
|
495
497
|
timeout?: number;
|
|
496
498
|
retries?: number;
|
|
497
499
|
headers?: Record<string, string>;
|
|
500
|
+
cache?: CacheConfig;
|
|
498
501
|
}
|
|
499
502
|
|
|
500
503
|
// HTTP Methods
|
|
@@ -509,3 +512,6 @@ export interface RequestOptions {
|
|
|
509
512
|
timeout?: number;
|
|
510
513
|
csrfToken?: string; // Optional CSRF token for protected endpoints
|
|
511
514
|
}
|
|
515
|
+
|
|
516
|
+
// Cache types re-exported for convenience
|
|
517
|
+
export type { CacheConfig } from '../cache/types';
|