perspectapi-ts-sdk 2.6.0 → 2.7.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 +14 -1
- package/dist/index.d.mts +21 -1
- package/dist/index.d.ts +21 -1
- package/dist/index.js +49 -1
- package/dist/index.mjs +49 -1
- package/package.json +1 -1
- package/src/client/content-client.ts +67 -1
- package/src/index.ts +3 -1
- package/src/types/index.ts +18 -0
package/README.md
CHANGED
|
@@ -147,7 +147,7 @@ export default {
|
|
|
147
147
|
};
|
|
148
148
|
```
|
|
149
149
|
|
|
150
|
-
When PerspectAPI sends a webhook—or when your Worker mutates data directly—call `perspect.cache.invalidate({ tags: [...] })` using the tags emitted by the SDK (`products:site:<site>`, `content:slug:<site>:<slug>`, etc.) so stale entries are purged immediately.
|
|
150
|
+
When PerspectAPI sends a webhook—or when your Worker mutates data directly—call `perspect.cache.invalidate({ tags: [...] })` using the tags emitted by the SDK (`products:site:<site>`, `content:slug:<site>:<slug>`, `content:category:<site>:<category_slug>`, etc.) so stale entries are purged immediately.
|
|
151
151
|
|
|
152
152
|
### Webhook-driven cache invalidation
|
|
153
153
|
|
|
@@ -200,6 +200,8 @@ const tagMap: Record<string, (e: WebhookEvent) => string[]> = {
|
|
|
200
200
|
`categories`,
|
|
201
201
|
`categories:site:${event.site}`,
|
|
202
202
|
`categories:product:${event.site}:${event.slug}`,
|
|
203
|
+
`products:category:${event.site}:${event.slug}`,
|
|
204
|
+
`content:category:${event.site}:${event.slug}`,
|
|
203
205
|
],
|
|
204
206
|
};
|
|
205
207
|
|
|
@@ -392,6 +394,17 @@ const post = await client.content.getContentById(123);
|
|
|
392
394
|
// Get content by slug
|
|
393
395
|
const page = await client.content.getContentBySlug('your-site-name', 'about-us');
|
|
394
396
|
|
|
397
|
+
// Get content by category slug
|
|
398
|
+
const categoryContent = await client.content.getContentByCategorySlug(
|
|
399
|
+
'your-site-name',
|
|
400
|
+
'news',
|
|
401
|
+
{
|
|
402
|
+
page: 1,
|
|
403
|
+
limit: 20,
|
|
404
|
+
page_type: 'post'
|
|
405
|
+
}
|
|
406
|
+
);
|
|
407
|
+
|
|
395
408
|
// Create new content
|
|
396
409
|
const newPost = await client.content.createContent({
|
|
397
410
|
page_title: 'My New Post',
|
package/dist/index.d.mts
CHANGED
|
@@ -312,6 +312,22 @@ interface Category {
|
|
|
312
312
|
createdAt: string;
|
|
313
313
|
updatedAt: string;
|
|
314
314
|
}
|
|
315
|
+
interface CategorySummary {
|
|
316
|
+
id: number;
|
|
317
|
+
name: string;
|
|
318
|
+
slug: string;
|
|
319
|
+
description?: string;
|
|
320
|
+
}
|
|
321
|
+
interface ContentCategoryResponse {
|
|
322
|
+
category: CategorySummary;
|
|
323
|
+
items: Content[];
|
|
324
|
+
pagination: {
|
|
325
|
+
page: number;
|
|
326
|
+
limit: number;
|
|
327
|
+
total: number;
|
|
328
|
+
pages: number;
|
|
329
|
+
};
|
|
330
|
+
}
|
|
315
331
|
interface CreateCategoryRequest {
|
|
316
332
|
name: string;
|
|
317
333
|
slug?: string;
|
|
@@ -781,6 +797,10 @@ declare class ContentClient extends BaseClient {
|
|
|
781
797
|
* Get content by ID
|
|
782
798
|
*/
|
|
783
799
|
getContentById(id: number, cachePolicy?: CachePolicy): Promise<ApiResponse<Content>>;
|
|
800
|
+
/**
|
|
801
|
+
* Get content by category slug for a site
|
|
802
|
+
*/
|
|
803
|
+
getContentByCategorySlug(siteName: string, categorySlug: string, params?: ContentQueryParams, cachePolicy?: CachePolicy): Promise<ApiResponse<ContentCategoryResponse>>;
|
|
784
804
|
/**
|
|
785
805
|
* Get content by slug for a site
|
|
786
806
|
*/
|
|
@@ -2452,4 +2472,4 @@ declare function createCheckoutSession(options: CheckoutSessionOptions): Promise
|
|
|
2452
2472
|
error: string;
|
|
2453
2473
|
}>;
|
|
2454
2474
|
|
|
2455
|
-
export { type ApiError, type ApiKey, ApiKeysClient, type ApiResponse, AuthClient, type AuthResponse, BaseClient, type BlogPost, type CacheConfig, CacheManager, CategoriesClient, type Category, type CheckoutAddress, CheckoutClient, type CheckoutMetadata, type CheckoutMetadataValue, type CheckoutSession, type CheckoutSessionOptions, type CheckoutSessionTax, type CheckoutTaxBreakdownItem, type CheckoutTaxCustomerExemptionRequest, type CheckoutTaxExemptionStatus, type CheckoutTaxRequest, type CheckoutTaxStrategy, ContactClient, type ContactStatusResponse, type ContactSubmission, type ContactSubmitResponse, type Content, ContentClient, type ContentQueryParams, type ContentStatus, type ContentType, type CreateApiKeyRequest, type CreateCategoryRequest, type CreateCheckoutSessionRequest, type CreateContactRequest, type CreateContentRequest, type CreateNewsletterSubscriptionRequest, type CreateOrganizationRequest, type CreatePaymentGatewayRequest, type CreateProductRequest, type CreateSiteRequest, type CreateWebhookRequest, DEFAULT_IMAGE_SIZES, HttpClient, type HttpMethod, type ImageTransformOptions, InMemoryCacheAdapter, type LoadContentBySlugOptions, type LoadContentOptions, type LoadProductBySlugOptions, type LoadProductsOptions, type LoaderLogger, type LoaderOptions, type MediaItem, NewsletterClient, type NewsletterConfirmResponse, type NewsletterList, type NewsletterPreferences, type NewsletterStatusResponse, type NewsletterSubscribeResponse, type NewsletterSubscription, type NewsletterUnsubscribeRequest, type NewsletterUnsubscribeResponse, NoopCacheAdapter, type Organization, OrganizationsClient, type PaginatedResponse, type PaginationParams, type PaymentGateway, PerspectApiClient, type PerspectApiConfig, type Product, type ProductQueryParams, ProductsClient, type RequestOptions, type ResponsiveImageSizes, type SignInRequest, type SignUpRequest, type Site, SitesClient, type UpdateApiKeyRequest, type UpdateContentRequest, type User, type Webhook, WebhooksClient, buildImageUrl, createApiError, createCheckoutSession, createPerspectApiClient, PerspectApiClient as default, generateResponsiveImageHtml, generateResponsiveUrls, generateSizesAttribute, generateSrcSet, loadAllContent, loadContentBySlug, loadPages, loadPosts, loadProductBySlug, loadProducts, transformContent, transformMediaItem, transformProduct };
|
|
2475
|
+
export { type ApiError, type ApiKey, ApiKeysClient, type ApiResponse, AuthClient, type AuthResponse, BaseClient, type BlogPost, type CacheConfig, CacheManager, CategoriesClient, type Category, type CategorySummary, type CheckoutAddress, CheckoutClient, type CheckoutMetadata, type CheckoutMetadataValue, type CheckoutSession, type CheckoutSessionOptions, type CheckoutSessionTax, type CheckoutTaxBreakdownItem, type CheckoutTaxCustomerExemptionRequest, type CheckoutTaxExemptionStatus, type CheckoutTaxRequest, type CheckoutTaxStrategy, ContactClient, type ContactStatusResponse, type ContactSubmission, type ContactSubmitResponse, type Content, type ContentCategoryResponse, ContentClient, type ContentQueryParams, type ContentStatus, type ContentType, type CreateApiKeyRequest, type CreateCategoryRequest, type CreateCheckoutSessionRequest, type CreateContactRequest, type CreateContentRequest, type CreateNewsletterSubscriptionRequest, type CreateOrganizationRequest, type CreatePaymentGatewayRequest, type CreateProductRequest, type CreateSiteRequest, type CreateWebhookRequest, DEFAULT_IMAGE_SIZES, HttpClient, type HttpMethod, type ImageTransformOptions, InMemoryCacheAdapter, type LoadContentBySlugOptions, type LoadContentOptions, type LoadProductBySlugOptions, type LoadProductsOptions, type LoaderLogger, type LoaderOptions, type MediaItem, NewsletterClient, type NewsletterConfirmResponse, type NewsletterList, type NewsletterPreferences, type NewsletterStatusResponse, type NewsletterSubscribeResponse, type NewsletterSubscription, type NewsletterUnsubscribeRequest, type NewsletterUnsubscribeResponse, NoopCacheAdapter, type Organization, OrganizationsClient, type PaginatedResponse, type PaginationParams, type PaymentGateway, PerspectApiClient, type PerspectApiConfig, type Product, type ProductQueryParams, ProductsClient, type RequestOptions, type ResponsiveImageSizes, type SignInRequest, type SignUpRequest, type Site, SitesClient, type UpdateApiKeyRequest, type UpdateContentRequest, type User, type Webhook, WebhooksClient, buildImageUrl, createApiError, createCheckoutSession, createPerspectApiClient, PerspectApiClient as default, generateResponsiveImageHtml, generateResponsiveUrls, generateSizesAttribute, generateSrcSet, loadAllContent, loadContentBySlug, loadPages, loadPosts, loadProductBySlug, loadProducts, transformContent, transformMediaItem, transformProduct };
|
package/dist/index.d.ts
CHANGED
|
@@ -312,6 +312,22 @@ interface Category {
|
|
|
312
312
|
createdAt: string;
|
|
313
313
|
updatedAt: string;
|
|
314
314
|
}
|
|
315
|
+
interface CategorySummary {
|
|
316
|
+
id: number;
|
|
317
|
+
name: string;
|
|
318
|
+
slug: string;
|
|
319
|
+
description?: string;
|
|
320
|
+
}
|
|
321
|
+
interface ContentCategoryResponse {
|
|
322
|
+
category: CategorySummary;
|
|
323
|
+
items: Content[];
|
|
324
|
+
pagination: {
|
|
325
|
+
page: number;
|
|
326
|
+
limit: number;
|
|
327
|
+
total: number;
|
|
328
|
+
pages: number;
|
|
329
|
+
};
|
|
330
|
+
}
|
|
315
331
|
interface CreateCategoryRequest {
|
|
316
332
|
name: string;
|
|
317
333
|
slug?: string;
|
|
@@ -781,6 +797,10 @@ declare class ContentClient extends BaseClient {
|
|
|
781
797
|
* Get content by ID
|
|
782
798
|
*/
|
|
783
799
|
getContentById(id: number, cachePolicy?: CachePolicy): Promise<ApiResponse<Content>>;
|
|
800
|
+
/**
|
|
801
|
+
* Get content by category slug for a site
|
|
802
|
+
*/
|
|
803
|
+
getContentByCategorySlug(siteName: string, categorySlug: string, params?: ContentQueryParams, cachePolicy?: CachePolicy): Promise<ApiResponse<ContentCategoryResponse>>;
|
|
784
804
|
/**
|
|
785
805
|
* Get content by slug for a site
|
|
786
806
|
*/
|
|
@@ -2452,4 +2472,4 @@ declare function createCheckoutSession(options: CheckoutSessionOptions): Promise
|
|
|
2452
2472
|
error: string;
|
|
2453
2473
|
}>;
|
|
2454
2474
|
|
|
2455
|
-
export { type ApiError, type ApiKey, ApiKeysClient, type ApiResponse, AuthClient, type AuthResponse, BaseClient, type BlogPost, type CacheConfig, CacheManager, CategoriesClient, type Category, type CheckoutAddress, CheckoutClient, type CheckoutMetadata, type CheckoutMetadataValue, type CheckoutSession, type CheckoutSessionOptions, type CheckoutSessionTax, type CheckoutTaxBreakdownItem, type CheckoutTaxCustomerExemptionRequest, type CheckoutTaxExemptionStatus, type CheckoutTaxRequest, type CheckoutTaxStrategy, ContactClient, type ContactStatusResponse, type ContactSubmission, type ContactSubmitResponse, type Content, ContentClient, type ContentQueryParams, type ContentStatus, type ContentType, type CreateApiKeyRequest, type CreateCategoryRequest, type CreateCheckoutSessionRequest, type CreateContactRequest, type CreateContentRequest, type CreateNewsletterSubscriptionRequest, type CreateOrganizationRequest, type CreatePaymentGatewayRequest, type CreateProductRequest, type CreateSiteRequest, type CreateWebhookRequest, DEFAULT_IMAGE_SIZES, HttpClient, type HttpMethod, type ImageTransformOptions, InMemoryCacheAdapter, type LoadContentBySlugOptions, type LoadContentOptions, type LoadProductBySlugOptions, type LoadProductsOptions, type LoaderLogger, type LoaderOptions, type MediaItem, NewsletterClient, type NewsletterConfirmResponse, type NewsletterList, type NewsletterPreferences, type NewsletterStatusResponse, type NewsletterSubscribeResponse, type NewsletterSubscription, type NewsletterUnsubscribeRequest, type NewsletterUnsubscribeResponse, NoopCacheAdapter, type Organization, OrganizationsClient, type PaginatedResponse, type PaginationParams, type PaymentGateway, PerspectApiClient, type PerspectApiConfig, type Product, type ProductQueryParams, ProductsClient, type RequestOptions, type ResponsiveImageSizes, type SignInRequest, type SignUpRequest, type Site, SitesClient, type UpdateApiKeyRequest, type UpdateContentRequest, type User, type Webhook, WebhooksClient, buildImageUrl, createApiError, createCheckoutSession, createPerspectApiClient, PerspectApiClient as default, generateResponsiveImageHtml, generateResponsiveUrls, generateSizesAttribute, generateSrcSet, loadAllContent, loadContentBySlug, loadPages, loadPosts, loadProductBySlug, loadProducts, transformContent, transformMediaItem, transformProduct };
|
|
2475
|
+
export { type ApiError, type ApiKey, ApiKeysClient, type ApiResponse, AuthClient, type AuthResponse, BaseClient, type BlogPost, type CacheConfig, CacheManager, CategoriesClient, type Category, type CategorySummary, type CheckoutAddress, CheckoutClient, type CheckoutMetadata, type CheckoutMetadataValue, type CheckoutSession, type CheckoutSessionOptions, type CheckoutSessionTax, type CheckoutTaxBreakdownItem, type CheckoutTaxCustomerExemptionRequest, type CheckoutTaxExemptionStatus, type CheckoutTaxRequest, type CheckoutTaxStrategy, ContactClient, type ContactStatusResponse, type ContactSubmission, type ContactSubmitResponse, type Content, type ContentCategoryResponse, ContentClient, type ContentQueryParams, type ContentStatus, type ContentType, type CreateApiKeyRequest, type CreateCategoryRequest, type CreateCheckoutSessionRequest, type CreateContactRequest, type CreateContentRequest, type CreateNewsletterSubscriptionRequest, type CreateOrganizationRequest, type CreatePaymentGatewayRequest, type CreateProductRequest, type CreateSiteRequest, type CreateWebhookRequest, DEFAULT_IMAGE_SIZES, HttpClient, type HttpMethod, type ImageTransformOptions, InMemoryCacheAdapter, type LoadContentBySlugOptions, type LoadContentOptions, type LoadProductBySlugOptions, type LoadProductsOptions, type LoaderLogger, type LoaderOptions, type MediaItem, NewsletterClient, type NewsletterConfirmResponse, type NewsletterList, type NewsletterPreferences, type NewsletterStatusResponse, type NewsletterSubscribeResponse, type NewsletterSubscription, type NewsletterUnsubscribeRequest, type NewsletterUnsubscribeResponse, NoopCacheAdapter, type Organization, OrganizationsClient, type PaginatedResponse, type PaginationParams, type PaymentGateway, PerspectApiClient, type PerspectApiConfig, type Product, type ProductQueryParams, ProductsClient, type RequestOptions, type ResponsiveImageSizes, type SignInRequest, type SignUpRequest, type Site, SitesClient, type UpdateApiKeyRequest, type UpdateContentRequest, type User, type Webhook, WebhooksClient, buildImageUrl, createApiError, createCheckoutSession, createPerspectApiClient, PerspectApiClient as default, generateResponsiveImageHtml, generateResponsiveUrls, generateSizesAttribute, generateSrcSet, loadAllContent, loadContentBySlug, loadPages, loadPosts, loadProductBySlug, loadProducts, transformContent, transformMediaItem, transformProduct };
|
package/dist/index.js
CHANGED
|
@@ -902,6 +902,50 @@ var ContentClient = class extends BaseClient {
|
|
|
902
902
|
() => this.http.get(path)
|
|
903
903
|
);
|
|
904
904
|
}
|
|
905
|
+
/**
|
|
906
|
+
* Get content by category slug for a site
|
|
907
|
+
*/
|
|
908
|
+
async getContentByCategorySlug(siteName, categorySlug, params, cachePolicy) {
|
|
909
|
+
const endpoint = this.siteScopedEndpoint(
|
|
910
|
+
siteName,
|
|
911
|
+
`/category/${encodeURIComponent(categorySlug)}`
|
|
912
|
+
);
|
|
913
|
+
const path = this.buildPath(endpoint);
|
|
914
|
+
const normalizedParams = params ? { ...params } : void 0;
|
|
915
|
+
if (normalizedParams) {
|
|
916
|
+
const validatedLimit = validateOptionalLimit(
|
|
917
|
+
normalizedParams.limit,
|
|
918
|
+
"content category query"
|
|
919
|
+
);
|
|
920
|
+
if (validatedLimit !== void 0) {
|
|
921
|
+
normalizedParams.limit = validatedLimit;
|
|
922
|
+
} else {
|
|
923
|
+
delete normalizedParams.limit;
|
|
924
|
+
}
|
|
925
|
+
const validatedPageType = validateOptionalContentType(
|
|
926
|
+
normalizedParams.page_type,
|
|
927
|
+
"content category query"
|
|
928
|
+
);
|
|
929
|
+
if (validatedPageType !== void 0) {
|
|
930
|
+
normalizedParams.page_type = validatedPageType;
|
|
931
|
+
} else {
|
|
932
|
+
delete normalizedParams.page_type;
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
return this.fetchWithCache(
|
|
936
|
+
endpoint,
|
|
937
|
+
normalizedParams,
|
|
938
|
+
this.buildContentTags(
|
|
939
|
+
siteName,
|
|
940
|
+
void 0,
|
|
941
|
+
void 0,
|
|
942
|
+
normalizedParams?.slug_prefix,
|
|
943
|
+
categorySlug
|
|
944
|
+
),
|
|
945
|
+
cachePolicy,
|
|
946
|
+
() => this.http.get(path, normalizedParams)
|
|
947
|
+
);
|
|
948
|
+
}
|
|
905
949
|
/**
|
|
906
950
|
* Get content by slug for a site
|
|
907
951
|
*/
|
|
@@ -977,7 +1021,7 @@ var ContentClient = class extends BaseClient {
|
|
|
977
1021
|
async duplicateContent(id) {
|
|
978
1022
|
return this.create(`/content/${id}/duplicate`, {});
|
|
979
1023
|
}
|
|
980
|
-
buildContentTags(siteName, slug, id, slugPrefix) {
|
|
1024
|
+
buildContentTags(siteName, slug, id, slugPrefix, categorySlug) {
|
|
981
1025
|
const tags = /* @__PURE__ */ new Set(["content"]);
|
|
982
1026
|
if (siteName) {
|
|
983
1027
|
tags.add(`content:site:${siteName}`);
|
|
@@ -991,6 +1035,10 @@ var ContentClient = class extends BaseClient {
|
|
|
991
1035
|
if (slugPrefix) {
|
|
992
1036
|
tags.add(`content:prefix:${slugPrefix}`);
|
|
993
1037
|
}
|
|
1038
|
+
if (categorySlug && siteName) {
|
|
1039
|
+
tags.add("content:category");
|
|
1040
|
+
tags.add(`content:category:${siteName}:${categorySlug}`);
|
|
1041
|
+
}
|
|
994
1042
|
return Array.from(tags.values());
|
|
995
1043
|
}
|
|
996
1044
|
/**
|
package/dist/index.mjs
CHANGED
|
@@ -841,6 +841,50 @@ var ContentClient = class extends BaseClient {
|
|
|
841
841
|
() => this.http.get(path)
|
|
842
842
|
);
|
|
843
843
|
}
|
|
844
|
+
/**
|
|
845
|
+
* Get content by category slug for a site
|
|
846
|
+
*/
|
|
847
|
+
async getContentByCategorySlug(siteName, categorySlug, params, cachePolicy) {
|
|
848
|
+
const endpoint = this.siteScopedEndpoint(
|
|
849
|
+
siteName,
|
|
850
|
+
`/category/${encodeURIComponent(categorySlug)}`
|
|
851
|
+
);
|
|
852
|
+
const path = this.buildPath(endpoint);
|
|
853
|
+
const normalizedParams = params ? { ...params } : void 0;
|
|
854
|
+
if (normalizedParams) {
|
|
855
|
+
const validatedLimit = validateOptionalLimit(
|
|
856
|
+
normalizedParams.limit,
|
|
857
|
+
"content category query"
|
|
858
|
+
);
|
|
859
|
+
if (validatedLimit !== void 0) {
|
|
860
|
+
normalizedParams.limit = validatedLimit;
|
|
861
|
+
} else {
|
|
862
|
+
delete normalizedParams.limit;
|
|
863
|
+
}
|
|
864
|
+
const validatedPageType = validateOptionalContentType(
|
|
865
|
+
normalizedParams.page_type,
|
|
866
|
+
"content category query"
|
|
867
|
+
);
|
|
868
|
+
if (validatedPageType !== void 0) {
|
|
869
|
+
normalizedParams.page_type = validatedPageType;
|
|
870
|
+
} else {
|
|
871
|
+
delete normalizedParams.page_type;
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
return this.fetchWithCache(
|
|
875
|
+
endpoint,
|
|
876
|
+
normalizedParams,
|
|
877
|
+
this.buildContentTags(
|
|
878
|
+
siteName,
|
|
879
|
+
void 0,
|
|
880
|
+
void 0,
|
|
881
|
+
normalizedParams?.slug_prefix,
|
|
882
|
+
categorySlug
|
|
883
|
+
),
|
|
884
|
+
cachePolicy,
|
|
885
|
+
() => this.http.get(path, normalizedParams)
|
|
886
|
+
);
|
|
887
|
+
}
|
|
844
888
|
/**
|
|
845
889
|
* Get content by slug for a site
|
|
846
890
|
*/
|
|
@@ -916,7 +960,7 @@ var ContentClient = class extends BaseClient {
|
|
|
916
960
|
async duplicateContent(id) {
|
|
917
961
|
return this.create(`/content/${id}/duplicate`, {});
|
|
918
962
|
}
|
|
919
|
-
buildContentTags(siteName, slug, id, slugPrefix) {
|
|
963
|
+
buildContentTags(siteName, slug, id, slugPrefix, categorySlug) {
|
|
920
964
|
const tags = /* @__PURE__ */ new Set(["content"]);
|
|
921
965
|
if (siteName) {
|
|
922
966
|
tags.add(`content:site:${siteName}`);
|
|
@@ -930,6 +974,10 @@ var ContentClient = class extends BaseClient {
|
|
|
930
974
|
if (slugPrefix) {
|
|
931
975
|
tags.add(`content:prefix:${slugPrefix}`);
|
|
932
976
|
}
|
|
977
|
+
if (categorySlug && siteName) {
|
|
978
|
+
tags.add("content:category");
|
|
979
|
+
tags.add(`content:category:${siteName}:${categorySlug}`);
|
|
980
|
+
}
|
|
933
981
|
return Array.from(tags.values());
|
|
934
982
|
}
|
|
935
983
|
/**
|
package/package.json
CHANGED
|
@@ -12,6 +12,7 @@ import type {
|
|
|
12
12
|
ContentQueryParams,
|
|
13
13
|
PaginatedResponse,
|
|
14
14
|
ApiResponse,
|
|
15
|
+
ContentCategoryResponse,
|
|
15
16
|
} from '../types';
|
|
16
17
|
import { validateOptionalContentType, validateOptionalLimit } from '../utils/validators';
|
|
17
18
|
|
|
@@ -139,6 +140,61 @@ export class ContentClient extends BaseClient {
|
|
|
139
140
|
);
|
|
140
141
|
}
|
|
141
142
|
|
|
143
|
+
/**
|
|
144
|
+
* Get content by category slug for a site
|
|
145
|
+
*/
|
|
146
|
+
async getContentByCategorySlug(
|
|
147
|
+
siteName: string,
|
|
148
|
+
categorySlug: string,
|
|
149
|
+
params?: ContentQueryParams,
|
|
150
|
+
cachePolicy?: CachePolicy
|
|
151
|
+
): Promise<ApiResponse<ContentCategoryResponse>> {
|
|
152
|
+
const endpoint = this.siteScopedEndpoint(
|
|
153
|
+
siteName,
|
|
154
|
+
`/category/${encodeURIComponent(categorySlug)}`
|
|
155
|
+
);
|
|
156
|
+
const path = this.buildPath(endpoint);
|
|
157
|
+
const normalizedParams: ContentQueryParams | undefined = params
|
|
158
|
+
? { ...params }
|
|
159
|
+
: undefined;
|
|
160
|
+
|
|
161
|
+
if (normalizedParams) {
|
|
162
|
+
const validatedLimit = validateOptionalLimit(
|
|
163
|
+
normalizedParams.limit,
|
|
164
|
+
'content category query',
|
|
165
|
+
);
|
|
166
|
+
if (validatedLimit !== undefined) {
|
|
167
|
+
normalizedParams.limit = validatedLimit;
|
|
168
|
+
} else {
|
|
169
|
+
delete normalizedParams.limit;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const validatedPageType = validateOptionalContentType(
|
|
173
|
+
normalizedParams.page_type,
|
|
174
|
+
'content category query',
|
|
175
|
+
);
|
|
176
|
+
if (validatedPageType !== undefined) {
|
|
177
|
+
normalizedParams.page_type = validatedPageType;
|
|
178
|
+
} else {
|
|
179
|
+
delete normalizedParams.page_type;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return this.fetchWithCache<ApiResponse<ContentCategoryResponse>>(
|
|
184
|
+
endpoint,
|
|
185
|
+
normalizedParams,
|
|
186
|
+
this.buildContentTags(
|
|
187
|
+
siteName,
|
|
188
|
+
undefined,
|
|
189
|
+
undefined,
|
|
190
|
+
normalizedParams?.slug_prefix,
|
|
191
|
+
categorySlug
|
|
192
|
+
),
|
|
193
|
+
cachePolicy,
|
|
194
|
+
() => this.http.get<ContentCategoryResponse>(path, normalizedParams)
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
|
|
142
198
|
/**
|
|
143
199
|
* Get content by slug for a site
|
|
144
200
|
*/
|
|
@@ -230,7 +286,13 @@ export class ContentClient extends BaseClient {
|
|
|
230
286
|
return this.create<Record<string, never>, Content>(`/content/${id}/duplicate`, {});
|
|
231
287
|
}
|
|
232
288
|
|
|
233
|
-
private buildContentTags(
|
|
289
|
+
private buildContentTags(
|
|
290
|
+
siteName?: string,
|
|
291
|
+
slug?: string,
|
|
292
|
+
id?: number,
|
|
293
|
+
slugPrefix?: string,
|
|
294
|
+
categorySlug?: string
|
|
295
|
+
): string[] {
|
|
234
296
|
const tags = new Set<string>(['content']);
|
|
235
297
|
if (siteName) {
|
|
236
298
|
tags.add(`content:site:${siteName}`);
|
|
@@ -244,6 +306,10 @@ export class ContentClient extends BaseClient {
|
|
|
244
306
|
if (slugPrefix) {
|
|
245
307
|
tags.add(`content:prefix:${slugPrefix}`);
|
|
246
308
|
}
|
|
309
|
+
if (categorySlug && siteName) {
|
|
310
|
+
tags.add('content:category');
|
|
311
|
+
tags.add(`content:category:${siteName}:${categorySlug}`);
|
|
312
|
+
}
|
|
247
313
|
return Array.from(tags.values());
|
|
248
314
|
}
|
|
249
315
|
|
package/src/index.ts
CHANGED
|
@@ -80,12 +80,14 @@ export type {
|
|
|
80
80
|
PaginatedResponse,
|
|
81
81
|
ApiError,
|
|
82
82
|
User,
|
|
83
|
-
Content,
|
|
83
|
+
Content,
|
|
84
|
+
ContentCategoryResponse,
|
|
84
85
|
Product,
|
|
85
86
|
ProductQueryParams,
|
|
86
87
|
MediaItem,
|
|
87
88
|
BlogPost,
|
|
88
89
|
Category,
|
|
90
|
+
CategorySummary,
|
|
89
91
|
Organization,
|
|
90
92
|
Site,
|
|
91
93
|
ApiKey,
|
package/src/types/index.ts
CHANGED
|
@@ -268,6 +268,24 @@ export interface Category {
|
|
|
268
268
|
updatedAt: string;
|
|
269
269
|
}
|
|
270
270
|
|
|
271
|
+
export interface CategorySummary {
|
|
272
|
+
id: number;
|
|
273
|
+
name: string;
|
|
274
|
+
slug: string;
|
|
275
|
+
description?: string;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export interface ContentCategoryResponse {
|
|
279
|
+
category: CategorySummary;
|
|
280
|
+
items: Content[];
|
|
281
|
+
pagination: {
|
|
282
|
+
page: number;
|
|
283
|
+
limit: number;
|
|
284
|
+
total: number;
|
|
285
|
+
pages: number;
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
|
|
271
289
|
export interface CreateCategoryRequest {
|
|
272
290
|
name: string;
|
|
273
291
|
slug?: string;
|