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 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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "perspectapi-ts-sdk",
3
- "version": "2.6.0",
3
+ "version": "2.7.0",
4
4
  "description": "TypeScript SDK for PerspectAPI - Cloudflare Workers compatible",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -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(siteName?: string, slug?: string, id?: number, slugPrefix?: string): string[] {
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,
@@ -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;