perspectapi-ts-sdk 2.6.0 → 2.8.1

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
@@ -265,7 +265,7 @@ interface NewsletterUnsubscribeResponse {
265
265
  status?: string;
266
266
  }
267
267
  type ContentStatus = 'draft' | 'publish' | 'private' | 'trash';
268
- type ContentType = 'post' | 'page';
268
+ type ContentType = 'post' | 'page' | 'block';
269
269
  interface Content {
270
270
  id: number;
271
271
  pageTitle: string;
@@ -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;
@@ -557,6 +573,83 @@ interface ContactStatusResponse {
557
573
  processed_at?: string;
558
574
  metadata?: Record<string, any>;
559
575
  }
576
+ interface SiteUser {
577
+ id: string;
578
+ email: string;
579
+ first_name?: string;
580
+ last_name?: string;
581
+ avatar_url?: string;
582
+ status: 'active' | 'suspended' | 'pending_verification';
583
+ email_verified: boolean;
584
+ waitlist: boolean;
585
+ created_at: string;
586
+ last_login_at?: string;
587
+ }
588
+ interface SiteUserProfile {
589
+ [key: string]: {
590
+ value: any;
591
+ updated_at: string;
592
+ };
593
+ }
594
+ interface SiteUserSubscription {
595
+ id: string;
596
+ provider: string;
597
+ provider_subscription_id?: string;
598
+ plan_name?: string;
599
+ plan_id?: string;
600
+ status: 'active' | 'past_due' | 'canceled' | 'paused' | 'trialing' | 'expired';
601
+ amount?: number;
602
+ currency?: string;
603
+ billing_interval?: string;
604
+ billing_interval_count?: number;
605
+ current_period_start?: string;
606
+ current_period_end?: string;
607
+ trial_start?: string;
608
+ trial_end?: string;
609
+ canceled_at?: string;
610
+ cancel_at_period_end: boolean;
611
+ created_at: string;
612
+ updated_at: string;
613
+ }
614
+ interface SiteUserOrder {
615
+ session_id: string;
616
+ order_id?: string;
617
+ customer_email?: string;
618
+ amount_total: number;
619
+ currency: string;
620
+ status: string;
621
+ payment_status?: string;
622
+ line_items: any[];
623
+ created_at: string;
624
+ updated_at: string;
625
+ }
626
+ interface RequestOtpRequest {
627
+ email: string;
628
+ waitlist?: boolean;
629
+ }
630
+ interface VerifyOtpRequest {
631
+ email: string;
632
+ code: string;
633
+ }
634
+ interface VerifyOtpResponse {
635
+ success: boolean;
636
+ token: string;
637
+ user: {
638
+ id: string;
639
+ email: string;
640
+ first_name?: string;
641
+ last_name?: string;
642
+ avatar_url?: string;
643
+ };
644
+ }
645
+ interface UpdateSiteUserRequest {
646
+ first_name?: string;
647
+ last_name?: string;
648
+ avatar_url?: string;
649
+ }
650
+ interface SetProfileValueRequest {
651
+ value: string;
652
+ }
560
653
  interface ApiError {
561
654
  message: string;
562
655
  code?: string;
@@ -781,6 +874,10 @@ declare class ContentClient extends BaseClient {
781
874
  * Get content by ID
782
875
  */
783
876
  getContentById(id: number, cachePolicy?: CachePolicy): Promise<ApiResponse<Content>>;
877
+ /**
878
+ * Get content by category slug for a site
879
+ */
880
+ getContentByCategorySlug(siteName: string, categorySlug: string, params?: ContentQueryParams, cachePolicy?: CachePolicy): Promise<ApiResponse<ContentCategoryResponse>>;
784
881
  /**
785
882
  * Get content by slug for a site
786
883
  */
@@ -1236,6 +1333,72 @@ declare class ProductsClient extends BaseClient {
1236
1333
  * e.g., 'shop/shoes/nike-air' -> 'shop', 'product-name' -> undefined
1237
1334
  */
1238
1335
  private extractSlugPrefix;
1336
+ /**
1337
+ * Get all options (and their values) for a product
1338
+ */
1339
+ getProductOptions(siteName: string, productId: number): Promise<ApiResponse<Array<{
1340
+ option_id: number;
1341
+ option_name: string;
1342
+ display_order: number;
1343
+ values: Array<{
1344
+ value_id: number;
1345
+ value: string;
1346
+ display_order: number;
1347
+ }>;
1348
+ }>>>;
1349
+ /**
1350
+ * Create a new product option (e.g., "Size", "Color")
1351
+ */
1352
+ createProductOption(siteName: string, productId: number, data: {
1353
+ option_name: string;
1354
+ display_order?: number;
1355
+ }): Promise<ApiResponse<{
1356
+ option_id: number;
1357
+ option_name: string;
1358
+ display_order: number;
1359
+ }>>;
1360
+ /**
1361
+ * Create a new value for a product option (e.g., "Small", "Red")
1362
+ */
1363
+ createProductOptionValue(siteName: string, productId: number, optionId: number, data: {
1364
+ value: string;
1365
+ display_order?: number;
1366
+ }): Promise<ApiResponse<{
1367
+ value_id: number;
1368
+ value: string;
1369
+ display_order: number;
1370
+ }>>;
1371
+ /**
1372
+ * Get all SKUs for a product (with their option value combinations)
1373
+ */
1374
+ getProductSkus(siteName: string, productId: number): Promise<ApiResponse<Array<{
1375
+ sku_id: number;
1376
+ sku: string;
1377
+ price?: number;
1378
+ sale_price?: number;
1379
+ stock_quantity?: number;
1380
+ combination_key: string;
1381
+ value_ids: number[];
1382
+ created_at: string;
1383
+ updated_at: string;
1384
+ }>>>;
1385
+ /**
1386
+ * Create or update a SKU for a product variant combination
1387
+ */
1388
+ createProductSku(siteName: string, productId: number, data: {
1389
+ sku: string;
1390
+ price?: number | null;
1391
+ sale_price?: number | null;
1392
+ stock_quantity?: number | null;
1393
+ value_ids: number[];
1394
+ }): Promise<ApiResponse<{
1395
+ sku_id: number;
1396
+ sku: string;
1397
+ price?: number;
1398
+ sale_price?: number;
1399
+ stock_quantity?: number;
1400
+ combination_key: string;
1401
+ }>>;
1239
1402
  }
1240
1403
 
1241
1404
  /**
@@ -2029,6 +2192,210 @@ declare class NewsletterClient extends BaseClient {
2029
2192
  static getTrackingPixel(): Uint8Array;
2030
2193
  }
2031
2194
 
2195
+ /**
2196
+ * Site Users client for PerspectAPI SDK
2197
+ * Handles per-site customer accounts (OTP-based auth, profiles, orders, subscriptions)
2198
+ */
2199
+
2200
+ declare class SiteUsersClient extends BaseClient {
2201
+ constructor(http: any, cache?: CacheManager);
2202
+ /**
2203
+ * Build a site user endpoint scoped to a site (without /sites prefix)
2204
+ */
2205
+ private siteUserEndpoint;
2206
+ /**
2207
+ * Request OTP for login/signup
2208
+ * @param siteName - The site name
2209
+ * @param data - Email address
2210
+ * @param csrfToken - CSRF token (required for browser-based submissions)
2211
+ */
2212
+ requestOtp(siteName: string, data: RequestOtpRequest, csrfToken?: string): Promise<ApiResponse<{
2213
+ success: boolean;
2214
+ }>>;
2215
+ /**
2216
+ * Verify OTP and get JWT token
2217
+ *
2218
+ * For cross-domain authentication, you must manually set the token after verification:
2219
+ * ```typescript
2220
+ * const response = await client.siteUsers.verifyOtp('mysite', { email, code });
2221
+ * const { token, user } = response.data;
2222
+ *
2223
+ * // Store token securely (choose one):
2224
+ * // Option 1: Memory (lost on refresh, most secure)
2225
+ * client.setAuth(token);
2226
+ *
2227
+ * // Option 2: httpOnly cookie on YOUR domain (recommended for production)
2228
+ * await fetch('/your-api/set-auth-cookie', {
2229
+ * method: 'POST',
2230
+ * body: JSON.stringify({ token })
2231
+ * });
2232
+ * client.setAuth(token);
2233
+ *
2234
+ * // Option 3: localStorage (vulnerable to XSS, not recommended)
2235
+ * localStorage.setItem('site_user_token', token);
2236
+ * client.setAuth(token);
2237
+ * ```
2238
+ *
2239
+ * For convenience, use `verifyOtpAndSetAuth()` to automatically set the token in memory.
2240
+ *
2241
+ * @param siteName - The site name
2242
+ * @param data - Email and code
2243
+ * @param csrfToken - CSRF token (required for browser-based submissions)
2244
+ */
2245
+ verifyOtp(siteName: string, data: VerifyOtpRequest, csrfToken?: string): Promise<ApiResponse<VerifyOtpResponse>>;
2246
+ /**
2247
+ * Verify OTP and automatically set the token for subsequent requests
2248
+ *
2249
+ * Convenience method that:
2250
+ * 1. Verifies the OTP
2251
+ * 2. Automatically calls setAuth() with the returned token
2252
+ *
2253
+ * Note: Token is stored in memory only and will be lost on page refresh.
2254
+ * For persistent auth, use verifyOtp() and store the token yourself.
2255
+ *
2256
+ * @param siteName - The site name
2257
+ * @param data - Email and code
2258
+ * @param csrfToken - CSRF token (required for browser-based submissions)
2259
+ */
2260
+ verifyOtpAndSetAuth(siteName: string, data: VerifyOtpRequest, csrfToken?: string): Promise<ApiResponse<VerifyOtpResponse>>;
2261
+ /**
2262
+ * Logout (clear session cookie)
2263
+ * @param siteName - The site name
2264
+ */
2265
+ logout(siteName: string): Promise<ApiResponse<{
2266
+ success: boolean;
2267
+ }>>;
2268
+ /**
2269
+ * Get current user profile
2270
+ * @param siteName - The site name
2271
+ */
2272
+ getMe(siteName: string): Promise<ApiResponse<{
2273
+ user: SiteUser;
2274
+ profile: SiteUserProfile;
2275
+ }>>;
2276
+ /**
2277
+ * Update current user profile
2278
+ * @param siteName - The site name
2279
+ * @param data - Fields to update
2280
+ * @param csrfToken - CSRF token (required)
2281
+ */
2282
+ updateMe(siteName: string, data: UpdateSiteUserRequest, csrfToken?: string): Promise<ApiResponse<{
2283
+ success: boolean;
2284
+ }>>;
2285
+ /**
2286
+ * Get all profile key-values
2287
+ * @param siteName - The site name
2288
+ */
2289
+ getProfile(siteName: string): Promise<ApiResponse<{
2290
+ profile: SiteUserProfile;
2291
+ }>>;
2292
+ /**
2293
+ * Set a profile key-value
2294
+ * @param siteName - The site name
2295
+ * @param key - Profile key (e.g., 'phone', 'whatsapp', 'address_shipping')
2296
+ * @param value - Profile value (string or JSON string)
2297
+ * @param csrfToken - CSRF token (required)
2298
+ */
2299
+ setProfileValue(siteName: string, key: string, value: string, csrfToken?: string): Promise<ApiResponse<{
2300
+ success: boolean;
2301
+ }>>;
2302
+ /**
2303
+ * Delete a profile key-value
2304
+ * @param siteName - The site name
2305
+ * @param key - Profile key to delete
2306
+ * @param csrfToken - CSRF token (required)
2307
+ */
2308
+ deleteProfileValue(siteName: string, key: string, csrfToken?: string): Promise<ApiResponse<{
2309
+ success: boolean;
2310
+ }>>;
2311
+ /**
2312
+ * Get transaction/order history
2313
+ * @param siteName - The site name
2314
+ * @param params - Pagination params
2315
+ */
2316
+ getOrders(siteName: string, params?: {
2317
+ limit?: number;
2318
+ offset?: number;
2319
+ }): Promise<ApiResponse<{
2320
+ orders: SiteUserOrder[];
2321
+ }>>;
2322
+ /**
2323
+ * Get single order detail
2324
+ * @param siteName - The site name
2325
+ * @param orderId - Order ID or session ID
2326
+ */
2327
+ getOrder(siteName: string, orderId: string): Promise<ApiResponse<{
2328
+ order: any;
2329
+ }>>;
2330
+ /**
2331
+ * Get payment subscriptions
2332
+ * @param siteName - The site name
2333
+ * @param params - Pagination params
2334
+ */
2335
+ getSubscriptions(siteName: string, params?: {
2336
+ limit?: number;
2337
+ offset?: number;
2338
+ }): Promise<ApiResponse<{
2339
+ subscriptions: SiteUserSubscription[];
2340
+ }>>;
2341
+ /**
2342
+ * Get single subscription detail
2343
+ * @param siteName - The site name
2344
+ * @param id - Subscription ID
2345
+ */
2346
+ getSubscription(siteName: string, id: string): Promise<ApiResponse<{
2347
+ subscription: SiteUserSubscription;
2348
+ }>>;
2349
+ /**
2350
+ * Cancel a subscription (marks for cancellation at period end)
2351
+ * @param siteName - The site name
2352
+ * @param id - Subscription ID
2353
+ * @param csrfToken - CSRF token (required)
2354
+ */
2355
+ cancelSubscription(siteName: string, id: string, csrfToken?: string): Promise<ApiResponse<{
2356
+ success: boolean;
2357
+ message: string;
2358
+ }>>;
2359
+ /**
2360
+ * Get linked newsletter subscriptions
2361
+ * @param siteName - The site name
2362
+ */
2363
+ getNewsletterSubscriptions(siteName: string): Promise<ApiResponse<{
2364
+ newsletters: any[];
2365
+ }>>;
2366
+ /**
2367
+ * List all site users (admin only)
2368
+ * @param siteName - The site name
2369
+ * @param params - Query params (limit, offset, status)
2370
+ */
2371
+ listUsers(siteName: string, params?: {
2372
+ limit?: number;
2373
+ offset?: number;
2374
+ status?: string;
2375
+ }): Promise<ApiResponse<{
2376
+ users: SiteUser[];
2377
+ }>>;
2378
+ /**
2379
+ * Get user detail (admin only)
2380
+ * @param siteName - The site name
2381
+ * @param userId - User ID
2382
+ */
2383
+ getUser(siteName: string, userId: string): Promise<ApiResponse<{
2384
+ user: SiteUser;
2385
+ profile: SiteUserProfile;
2386
+ }>>;
2387
+ /**
2388
+ * Update user status (admin only)
2389
+ * @param siteName - The site name
2390
+ * @param userId - User ID
2391
+ * @param status - New status
2392
+ * @param csrfToken - CSRF token (required)
2393
+ */
2394
+ updateUserStatus(siteName: string, userId: string, status: 'active' | 'suspended' | 'pending_verification', csrfToken?: string): Promise<ApiResponse<{
2395
+ success: boolean;
2396
+ }>>;
2397
+ }
2398
+
2032
2399
  /**
2033
2400
  * Main PerspectAPI SDK Client
2034
2401
  * Cloudflare Workers compatible TypeScript SDK
@@ -2048,6 +2415,7 @@ declare class PerspectApiClient {
2048
2415
  readonly checkout: CheckoutClient;
2049
2416
  readonly contact: ContactClient;
2050
2417
  readonly newsletter: NewsletterClient;
2418
+ readonly siteUsers: SiteUsersClient;
2051
2419
  constructor(config: PerspectApiConfig);
2052
2420
  /**
2053
2421
  * Update authentication token
@@ -2452,4 +2820,4 @@ declare function createCheckoutSession(options: CheckoutSessionOptions): Promise
2452
2820
  error: string;
2453
2821
  }>;
2454
2822
 
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 };
2823
+ 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 RequestOtpRequest, type ResponsiveImageSizes, type SetProfileValueRequest, type SignInRequest, type SignUpRequest, type Site, type SiteUser, type SiteUserOrder, type SiteUserProfile, type SiteUserSubscription, SiteUsersClient, SitesClient, type UpdateApiKeyRequest, type UpdateContentRequest, type UpdateSiteUserRequest, type User, type VerifyOtpRequest, type VerifyOtpResponse, type Webhook, WebhooksClient, buildImageUrl, createApiError, createCheckoutSession, createPerspectApiClient, PerspectApiClient as default, generateResponsiveImageHtml, generateResponsiveUrls, generateSizesAttribute, generateSrcSet, loadAllContent, loadContentBySlug, loadPages, loadPosts, loadProductBySlug, loadProducts, transformContent, transformMediaItem, transformProduct };