perspectapi-ts-sdk 4.1.0 → 5.0.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.
@@ -0,0 +1,105 @@
1
+ /**
2
+ * PerspectAPI v2 SDK Client
3
+ *
4
+ * Stripe-style API with consistent envelopes, prefixed IDs,
5
+ * cursor pagination, and snake_case responses.
6
+ *
7
+ * Usage:
8
+ * import { PerspectApiV2Client } from 'perspectapi-ts-sdk/v2';
9
+ * const client = new PerspectApiV2Client({ baseUrl: '...', apiKey: '...' });
10
+ * const posts = await client.content.list('mysite', { type: 'post', limit: 10 });
11
+ */
12
+
13
+ import { HttpClient } from '../utils/http-client';
14
+ import type { PerspectApiConfig } from '../types';
15
+
16
+ import { ContentV2Client } from './client/content-client';
17
+ import { ProductsV2Client } from './client/products-client';
18
+ import { CategoriesV2Client } from './client/categories-client';
19
+ import { CollectionsV2Client } from './client/collections-client';
20
+ import { OrdersV2Client } from './client/orders-client';
21
+ import { SiteUsersV2Client } from './client/site-users-client';
22
+ import { NewsletterV2Client } from './client/newsletter-client';
23
+ import { ContactsV2Client } from './client/contacts-client';
24
+ import { OrganizationsV2Client } from './client/organizations-client';
25
+ import { SitesV2Client } from './client/sites-client';
26
+ import { ApiKeysV2Client } from './client/api-keys-client';
27
+ import { WebhooksV2Client } from './client/webhooks-client';
28
+
29
+ export class PerspectApiV2Client {
30
+ private http: HttpClient;
31
+
32
+ readonly content: ContentV2Client;
33
+ readonly products: ProductsV2Client;
34
+ readonly categories: CategoriesV2Client;
35
+ readonly collections: CollectionsV2Client;
36
+ readonly orders: OrdersV2Client;
37
+ readonly siteUsers: SiteUsersV2Client;
38
+ readonly newsletter: NewsletterV2Client;
39
+ readonly contacts: ContactsV2Client;
40
+ readonly organizations: OrganizationsV2Client;
41
+ readonly sites: SitesV2Client;
42
+ readonly apiKeys: ApiKeysV2Client;
43
+ readonly webhooks: WebhooksV2Client;
44
+
45
+ constructor(config: PerspectApiConfig) {
46
+ // Ensure base URL points to /api/v2
47
+ const baseUrl = config.baseUrl.replace(/\/+$/, '');
48
+ const v2BaseUrl = baseUrl.endsWith('/api/v2')
49
+ ? baseUrl
50
+ : `${baseUrl}/api/v2`;
51
+
52
+ this.http = new HttpClient({ ...config, baseUrl: v2BaseUrl });
53
+
54
+ const basePath = '';
55
+ this.content = new ContentV2Client(this.http, basePath);
56
+ this.products = new ProductsV2Client(this.http, basePath);
57
+ this.categories = new CategoriesV2Client(this.http, basePath);
58
+ this.collections = new CollectionsV2Client(this.http, basePath);
59
+ this.orders = new OrdersV2Client(this.http, basePath);
60
+ this.siteUsers = new SiteUsersV2Client(this.http, basePath);
61
+ this.newsletter = new NewsletterV2Client(this.http, basePath);
62
+ this.contacts = new ContactsV2Client(this.http, basePath);
63
+ this.organizations = new OrganizationsV2Client(this.http, basePath);
64
+ this.sites = new SitesV2Client(this.http, basePath);
65
+ this.apiKeys = new ApiKeysV2Client(this.http, basePath);
66
+ this.webhooks = new WebhooksV2Client(this.http, basePath);
67
+ }
68
+
69
+ /** Update the JWT token for authenticated requests. */
70
+ setAuth(jwt: string): void {
71
+ this.http.setAuth(jwt);
72
+ }
73
+
74
+ /** Update the API key. */
75
+ setApiKey(apiKey: string): void {
76
+ this.http.setApiKey(apiKey);
77
+ }
78
+
79
+ /** Clear authentication. */
80
+ clearAuth(): void {
81
+ this.http.clearAuth();
82
+ }
83
+ }
84
+
85
+ export function createPerspectApiV2Client(config: PerspectApiConfig): PerspectApiV2Client {
86
+ return new PerspectApiV2Client(config);
87
+ }
88
+
89
+ // Re-export all types
90
+ export type * from './types';
91
+
92
+ // Re-export client classes
93
+ export { BaseV2Client, PerspectV2Error } from './client/base-v2-client';
94
+ export { ContentV2Client } from './client/content-client';
95
+ export { ProductsV2Client } from './client/products-client';
96
+ export { CategoriesV2Client } from './client/categories-client';
97
+ export { CollectionsV2Client } from './client/collections-client';
98
+ export { OrdersV2Client } from './client/orders-client';
99
+ export { SiteUsersV2Client } from './client/site-users-client';
100
+ export { NewsletterV2Client } from './client/newsletter-client';
101
+ export { ContactsV2Client } from './client/contacts-client';
102
+ export { OrganizationsV2Client } from './client/organizations-client';
103
+ export { SitesV2Client } from './client/sites-client';
104
+ export { ApiKeysV2Client } from './client/api-keys-client';
105
+ export { WebhooksV2Client } from './client/webhooks-client';
@@ -0,0 +1,395 @@
1
+ /**
2
+ * v2 SDK Types — matches the API wire format exactly (snake_case).
3
+ *
4
+ * These types reflect the actual JSON returned by /api/v2/ endpoints.
5
+ * No transformation layer is needed in the SDK.
6
+ */
7
+
8
+ // --- Base types ---
9
+
10
+ export interface V2Object {
11
+ object: string;
12
+ id: string;
13
+ }
14
+
15
+ export interface V2List<T> {
16
+ object: "list";
17
+ data: T[];
18
+ has_more: boolean;
19
+ url: string;
20
+ }
21
+
22
+ export interface V2Deleted {
23
+ object: string;
24
+ id: string;
25
+ deleted: true;
26
+ }
27
+
28
+ export interface V2Error {
29
+ error: {
30
+ type: V2ErrorType;
31
+ code: string;
32
+ message: string;
33
+ param?: string;
34
+ };
35
+ }
36
+
37
+ export type V2ErrorType =
38
+ | "invalid_request_error"
39
+ | "authentication_error"
40
+ | "permission_error"
41
+ | "not_found_error"
42
+ | "rate_limit_error"
43
+ | "api_error";
44
+
45
+ // --- Pagination ---
46
+
47
+ export interface V2PaginationParams {
48
+ limit?: number;
49
+ starting_after?: string;
50
+ ending_before?: string;
51
+ }
52
+
53
+ // --- Content ---
54
+
55
+ export interface V2Content extends V2Object {
56
+ object: "content";
57
+ title: string;
58
+ content: string;
59
+ markdown: string | null;
60
+ slug: string;
61
+ slug_prefix: string | null;
62
+ type: "post" | "page" | "block";
63
+ status: "draft" | "publish" | "private" | "trash" | "scheduled";
64
+ author: string | null;
65
+ custom: Record<string, unknown> | null;
66
+ featured_image?: string | null;
67
+ scheduled_at: string | null;
68
+ published_at: string;
69
+ updated_at: string;
70
+ }
71
+
72
+ export interface V2ContentCreateParams {
73
+ title: string;
74
+ content: string;
75
+ markdown?: string;
76
+ custom?: Record<string, unknown>;
77
+ slug?: string;
78
+ slug_prefix?: string;
79
+ published_at?: string;
80
+ scheduled_at?: string | null;
81
+ status?: "draft" | "publish" | "private" | "trash" | "scheduled";
82
+ type?: "post" | "page" | "block";
83
+ }
84
+
85
+ export interface V2ContentUpdateParams extends Partial<V2ContentCreateParams> {}
86
+
87
+ export interface V2ContentListParams extends V2PaginationParams {
88
+ status?: "draft" | "publish" | "private" | "trash" | "scheduled";
89
+ type?: "post" | "page" | "block";
90
+ search?: string;
91
+ slug_prefix?: string;
92
+ }
93
+
94
+ // --- Products ---
95
+
96
+ export interface V2Product extends V2Object {
97
+ object: "product";
98
+ name: string;
99
+ description: string | null;
100
+ excerpt: string | null;
101
+ meta_description: string | null;
102
+ price: number;
103
+ unit_amount: number;
104
+ currency: string;
105
+ sku: string | null;
106
+ slug: string | null;
107
+ slug_prefix: string | null;
108
+ published: boolean;
109
+ stock_quantity: number | null;
110
+ custom: Record<string, unknown> | null;
111
+ recurring: { interval: string; interval_count?: number } | null;
112
+ tax_behavior: "inclusive" | "exclusive" | "unspecified" | null;
113
+ category_id: string | null;
114
+ created_at: string | null;
115
+ updated_at: string | null;
116
+ }
117
+
118
+ export interface V2ProductCreateParams {
119
+ name: string;
120
+ description?: string;
121
+ excerpt?: string;
122
+ meta_description?: string;
123
+ category_id?: string;
124
+ price: number;
125
+ unit_amount: number;
126
+ currency?: string;
127
+ sku?: string;
128
+ custom?: Record<string, unknown>;
129
+ slug?: string;
130
+ slug_prefix?: string;
131
+ published?: boolean;
132
+ stock_quantity?: number | null;
133
+ recurring?: { interval: "day" | "week" | "month" | "year"; interval_count?: number };
134
+ tax_behavior?: "inclusive" | "exclusive" | "unspecified";
135
+ attachment_ids?: number[];
136
+ }
137
+
138
+ export interface V2ProductUpdateParams extends Partial<V2ProductCreateParams> {}
139
+
140
+ export interface V2ProductListParams extends V2PaginationParams {
141
+ published?: boolean;
142
+ category_id?: string;
143
+ search?: string;
144
+ slug_prefix?: string;
145
+ }
146
+
147
+ // --- Categories ---
148
+
149
+ export interface V2Category extends V2Object {
150
+ object: "category";
151
+ name: string;
152
+ description: string | null;
153
+ slug: string | null;
154
+ slug_prefix: string | null;
155
+ parent_id: string | null;
156
+ type: "post" | "product" | null;
157
+ created_at: string | null;
158
+ updated_at: string | null;
159
+ }
160
+
161
+ export interface V2CategoryCreateParams {
162
+ name: string;
163
+ description?: string;
164
+ slug?: string;
165
+ slug_prefix?: string;
166
+ parent_id?: string;
167
+ type?: "post" | "product";
168
+ }
169
+
170
+ export interface V2CategoryUpdateParams extends Partial<V2CategoryCreateParams> {}
171
+
172
+ // --- Collections ---
173
+
174
+ export interface V2Collection extends V2Object {
175
+ object: "collection";
176
+ name: string;
177
+ description: string | null;
178
+ available_from: string | null;
179
+ available_until: string | null;
180
+ published: boolean;
181
+ created_at: string | null;
182
+ updated_at: string | null;
183
+ }
184
+
185
+ export interface V2CollectionItem extends V2Object {
186
+ object: "collection_item";
187
+ collection_id: string;
188
+ product_id: string;
189
+ max_quantity: number | null;
190
+ position: number;
191
+ }
192
+
193
+ export interface V2CollectionCreateParams {
194
+ name: string;
195
+ description?: string | null;
196
+ available_from?: string | null;
197
+ available_until?: string | null;
198
+ published?: boolean;
199
+ }
200
+
201
+ export interface V2CollectionUpdateParams extends Partial<V2CollectionCreateParams> {}
202
+
203
+ // --- Orders (Checkout Sessions) ---
204
+
205
+ export interface V2Order extends V2Object {
206
+ object: "checkout_session";
207
+ customer_email: string;
208
+ customer_name: string | null;
209
+ customer_phone: string | null;
210
+ customer_details: Record<string, unknown> | null;
211
+ shipping_details: Record<string, unknown> | null;
212
+ order_id: string | null;
213
+ line_items: unknown[] | null;
214
+ amount_total: number;
215
+ currency: string;
216
+ tax_summary: Record<string, unknown> | null;
217
+ status: string;
218
+ payment_status: string | null;
219
+ fulfillment_status: string | null;
220
+ tracking_number: string | null;
221
+ notes: string | null;
222
+ live_mode: boolean;
223
+ metadata: Record<string, unknown> | null;
224
+ created_at: string;
225
+ completed_at: string | null;
226
+ expires_at: string | null;
227
+ }
228
+
229
+ export interface V2OrderListParams extends V2PaginationParams {
230
+ status?: string;
231
+ customer_email?: string;
232
+ date_from?: string;
233
+ date_to?: string;
234
+ }
235
+
236
+ // --- Site Users ---
237
+
238
+ export interface V2SiteUser extends V2Object {
239
+ object: "site_user";
240
+ email: string;
241
+ email_verified: boolean;
242
+ first_name: string | null;
243
+ last_name: string | null;
244
+ avatar_url: string | null;
245
+ status: string;
246
+ waitlist: boolean;
247
+ metadata: Record<string, unknown> | null;
248
+ created_at: string | null;
249
+ updated_at: string | null;
250
+ last_login_at: string | null;
251
+ }
252
+
253
+ export interface V2SiteUserUpdateParams {
254
+ first_name?: string;
255
+ last_name?: string;
256
+ avatar_url?: string;
257
+ status?: "active" | "suspended" | "pending_verification";
258
+ metadata?: Record<string, unknown>;
259
+ }
260
+
261
+ export interface V2SiteUserListParams extends V2PaginationParams {
262
+ status?: "active" | "suspended" | "pending_verification";
263
+ email?: string;
264
+ }
265
+
266
+ // --- Newsletter ---
267
+
268
+ export interface V2NewsletterSubscription extends V2Object {
269
+ object: "newsletter_subscription";
270
+ email: string;
271
+ name: string | null;
272
+ status: string;
273
+ double_opt_in: boolean;
274
+ confirmed_at: string | null;
275
+ source: string | null;
276
+ frequency: string | null;
277
+ topics: string[] | null;
278
+ language: string | null;
279
+ tags: string[] | null;
280
+ custom_fields: Record<string, unknown> | null;
281
+ unsubscribed_at: string | null;
282
+ created_at: string | null;
283
+ updated_at: string | null;
284
+ }
285
+
286
+ export interface V2NewsletterList extends V2Object {
287
+ object: "newsletter_list";
288
+ name: string;
289
+ slug: string;
290
+ description: string | null;
291
+ is_default: boolean;
292
+ subscriber_count: number;
293
+ created_at: string | null;
294
+ updated_at: string | null;
295
+ }
296
+
297
+ export interface V2NewsletterCampaign extends V2Object {
298
+ object: "newsletter_campaign";
299
+ name: string;
300
+ slug: string | null;
301
+ subject: string;
302
+ preview_text: string | null;
303
+ status: string;
304
+ sent_at: string | null;
305
+ completed_at: string | null;
306
+ total_recipients: number;
307
+ sent_count: number;
308
+ opened_count: number;
309
+ clicked_count: number;
310
+ created_at: string | null;
311
+ updated_at: string | null;
312
+ }
313
+
314
+ // --- Contact ---
315
+
316
+ export interface V2ContactSubmission extends V2Object {
317
+ object: "contact_submission";
318
+ name: string | null;
319
+ first_name: string | null;
320
+ last_name: string | null;
321
+ email: string;
322
+ subject: string | null;
323
+ message: string;
324
+ phone: string | null;
325
+ company: string | null;
326
+ status: string;
327
+ metadata: Record<string, unknown> | null;
328
+ created_at: string | null;
329
+ processed_at: string | null;
330
+ }
331
+
332
+ // --- Organizations ---
333
+
334
+ export interface V2Organization extends V2Object {
335
+ object: "organization";
336
+ name: string;
337
+ slug: string | null;
338
+ endpoint_status: string | null;
339
+ endpoint_url: string | null;
340
+ created_at: string | null;
341
+ updated_at: string | null;
342
+ }
343
+
344
+ // --- Sites ---
345
+
346
+ export interface V2Site extends V2Object {
347
+ object: "site";
348
+ name: string;
349
+ title: string | null;
350
+ description: string | null;
351
+ domain: string | null;
352
+ custom_domain: string | null;
353
+ organization_id: string | null;
354
+ tax_enabled: boolean;
355
+ lifecycle_status: string | null;
356
+ created_at: string | null;
357
+ updated_at: string | null;
358
+ }
359
+
360
+ // --- API Keys ---
361
+
362
+ export interface V2ApiKey extends V2Object {
363
+ object: "api_key";
364
+ name: string;
365
+ description: string | null;
366
+ organization_id: string | null;
367
+ site_name: string | null;
368
+ permissions: string[] | null;
369
+ is_active: boolean;
370
+ expires_at: string | null;
371
+ last_used_at: string | null;
372
+ created_at: string | null;
373
+ updated_at: string | null;
374
+ }
375
+
376
+ // --- Webhooks ---
377
+
378
+ export interface V2Webhook extends V2Object {
379
+ object: "webhook";
380
+ url: string;
381
+ description: string | null;
382
+ events: string[] | null;
383
+ is_active: boolean;
384
+ created_at: string | null;
385
+ updated_at: string | null;
386
+ }
387
+
388
+ export interface V2WebhookCreateParams {
389
+ url: string;
390
+ description?: string;
391
+ events?: string[];
392
+ is_active?: boolean;
393
+ }
394
+
395
+ export interface V2WebhookUpdateParams extends Partial<V2WebhookCreateParams> {}