perspectapi-ts-sdk 1.1.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.
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Main PerspectAPI SDK Client
3
+ * Cloudflare Workers compatible TypeScript SDK
4
+ */
5
+
6
+ import { HttpClient } from './utils/http-client';
7
+ import { AuthClient } from './client/auth-client';
8
+ import { ContentClient } from './client/content-client';
9
+ import { ApiKeysClient } from './client/api-keys-client';
10
+ import { OrganizationsClient } from './client/organizations-client';
11
+ import { SitesClient } from './client/sites-client';
12
+ import { ProductsClient } from './client/products-client';
13
+ import { CategoriesClient } from './client/categories-client';
14
+ import { WebhooksClient } from './client/webhooks-client';
15
+ import { CheckoutClient } from './client/checkout-client';
16
+ import { ContactClient } from './client/contact-client';
17
+
18
+ import type { PerspectApiConfig, ApiResponse } from './types';
19
+
20
+ export class PerspectApiClient {
21
+ private http: HttpClient;
22
+
23
+ // Service clients
24
+ public readonly auth: AuthClient;
25
+ public readonly content: ContentClient;
26
+ public readonly apiKeys: ApiKeysClient;
27
+ public readonly organizations: OrganizationsClient;
28
+ public readonly sites: SitesClient;
29
+ public readonly products: ProductsClient;
30
+ public readonly categories: CategoriesClient;
31
+ public readonly webhooks: WebhooksClient;
32
+ public readonly checkout: CheckoutClient;
33
+ public readonly contact: ContactClient;
34
+
35
+ constructor(config: PerspectApiConfig) {
36
+ // Validate required configuration
37
+ if (!config.baseUrl) {
38
+ throw new Error('baseUrl is required in PerspectApiConfig');
39
+ }
40
+
41
+ // Initialize HTTP client
42
+ this.http = new HttpClient(config);
43
+
44
+ // Initialize service clients
45
+ this.auth = new AuthClient(this.http);
46
+ this.content = new ContentClient(this.http);
47
+ this.apiKeys = new ApiKeysClient(this.http);
48
+ this.organizations = new OrganizationsClient(this.http);
49
+ this.sites = new SitesClient(this.http);
50
+ this.products = new ProductsClient(this.http);
51
+ this.categories = new CategoriesClient(this.http);
52
+ this.webhooks = new WebhooksClient(this.http);
53
+ this.checkout = new CheckoutClient(this.http);
54
+ this.contact = new ContactClient(this.http);
55
+ }
56
+
57
+ /**
58
+ * Update authentication token
59
+ */
60
+ setAuth(jwt: string): void {
61
+ this.http.setAuth(jwt);
62
+ }
63
+
64
+ /**
65
+ * Update API key
66
+ */
67
+ setApiKey(apiKey: string): void {
68
+ this.http.setApiKey(apiKey);
69
+ }
70
+
71
+ /**
72
+ * Clear authentication
73
+ */
74
+ clearAuth(): void {
75
+ this.http.clearAuth();
76
+ }
77
+
78
+ /**
79
+ * Health check endpoint
80
+ */
81
+ async health(): Promise<ApiResponse<{
82
+ status: string;
83
+ timestamp: string;
84
+ version?: string;
85
+ uptime?: number;
86
+ }>> {
87
+ return this.http.get('/health');
88
+ }
89
+
90
+ /**
91
+ * Get API version info
92
+ */
93
+ async getVersion(): Promise<ApiResponse<{
94
+ version: string;
95
+ buildDate: string;
96
+ gitCommit?: string;
97
+ }>> {
98
+ return this.http.get('/api/v1/version');
99
+ }
100
+
101
+ /**
102
+ * Get API status and statistics
103
+ */
104
+ async getStatus(): Promise<ApiResponse<{
105
+ status: string;
106
+ database: {
107
+ connected: boolean;
108
+ latency?: number;
109
+ };
110
+ cache: {
111
+ connected: boolean;
112
+ hitRate?: number;
113
+ };
114
+ queues: {
115
+ connected: boolean;
116
+ pendingJobs?: number;
117
+ };
118
+ uptime: number;
119
+ requestsPerMinute: number;
120
+ }>> {
121
+ return this.http.get('/api/v1/status');
122
+ }
123
+
124
+ /**
125
+ * Test API connectivity and authentication
126
+ */
127
+ async test(): Promise<ApiResponse<{
128
+ success: boolean;
129
+ authenticated: boolean;
130
+ user?: {
131
+ id: string;
132
+ email: string;
133
+ };
134
+ permissions?: string[];
135
+ timestamp: string;
136
+ }>> {
137
+ return this.http.get('/api/v1/test');
138
+ }
139
+
140
+ /**
141
+ * Get CSRF token (for form submissions)
142
+ * @param siteName - Optional site name for site-specific token (recommended for development)
143
+ */
144
+ async getCsrfToken(siteName?: string): Promise<ApiResponse<{
145
+ token?: string;
146
+ csrf_token?: string;
147
+ site_id?: string;
148
+ site_name?: string;
149
+ }>> {
150
+ if (siteName) {
151
+ // Use site-specific endpoint (works from localhost/development)
152
+ return this.http.get(`/api/v1/csrf/token/${siteName}`);
153
+ }
154
+ // Use host-based endpoint (requires correct Host header)
155
+ return this.http.get('/api/v1/csrf/token');
156
+ }
157
+
158
+ /**
159
+ * Validate CSRF token
160
+ */
161
+ async validateCsrfToken(token: string): Promise<ApiResponse<{
162
+ valid: boolean;
163
+ message?: string;
164
+ }>> {
165
+ return this.http.post('/api/v1/csrf/validate', { token });
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Create a new PerspectAPI client instance
171
+ */
172
+ export function createPerspectApiClient(config: PerspectApiConfig): PerspectApiClient {
173
+ return new PerspectApiClient(config);
174
+ }
175
+
176
+ /**
177
+ * Default export for convenience
178
+ */
179
+ export default PerspectApiClient;
@@ -0,0 +1,399 @@
1
+ /**
2
+ * Core types and interfaces for PerspectAPI SDK
3
+ */
4
+
5
+ // Base API Response
6
+ export interface ApiResponse<T = any> {
7
+ data?: T;
8
+ message?: string;
9
+ error?: string;
10
+ success?: boolean;
11
+ }
12
+
13
+ // Pagination
14
+ export interface PaginationParams {
15
+ page?: number;
16
+ limit?: number;
17
+ offset?: number;
18
+ }
19
+
20
+ export interface PaginatedResponse<T> extends ApiResponse<T[]> {
21
+ pagination?: {
22
+ page: number;
23
+ limit: number;
24
+ total: number;
25
+ totalPages: number;
26
+ };
27
+ }
28
+
29
+ // Authentication
30
+ export interface SignUpRequest {
31
+ email: string;
32
+ password: string;
33
+ firstName?: string;
34
+ lastName?: string;
35
+ }
36
+
37
+ export interface SignInRequest {
38
+ email: string;
39
+ password: string;
40
+ }
41
+
42
+ export interface AuthResponse {
43
+ message: string;
44
+ user?: User;
45
+ token?: string;
46
+ }
47
+
48
+ export interface User {
49
+ id: string;
50
+ email: string;
51
+ firstName?: string;
52
+ lastName?: string;
53
+ createdAt?: string;
54
+ isActive?: boolean;
55
+ }
56
+
57
+ // API Keys
58
+ export interface ApiKey {
59
+ id: string;
60
+ name: string;
61
+ description?: string;
62
+ permissions: string[];
63
+ organizationId?: number;
64
+ siteName?: string;
65
+ isActive: boolean;
66
+ createdAt: string;
67
+ expiresAt?: string;
68
+ lastUsedAt?: string;
69
+ }
70
+
71
+ export interface CreateApiKeyRequest {
72
+ name: string;
73
+ description?: string;
74
+ permissions: string[];
75
+ organizationId?: number;
76
+ siteName?: string;
77
+ expiresAt?: string;
78
+ }
79
+
80
+ export interface UpdateApiKeyRequest {
81
+ name?: string;
82
+ description?: string;
83
+ permissions?: string[];
84
+ isActive?: boolean;
85
+ }
86
+
87
+ // Organizations
88
+ export interface Organization {
89
+ id: number;
90
+ name: string;
91
+ description?: string;
92
+ createdAt: string;
93
+ updatedAt: string;
94
+ }
95
+
96
+ export interface CreateOrganizationRequest {
97
+ name: string;
98
+ description?: string;
99
+ }
100
+
101
+ // Sites
102
+ export interface Site {
103
+ id: number;
104
+ name: string;
105
+ domain?: string;
106
+ managementDomain?: string;
107
+ description?: string;
108
+ organizationId: number;
109
+ isActive: boolean;
110
+ createdAt: string;
111
+ updatedAt: string;
112
+ }
113
+
114
+ export interface CreateSiteRequest {
115
+ name: string;
116
+ domain?: string;
117
+ managementDomain?: string;
118
+ description?: string;
119
+ organizationId: number;
120
+ }
121
+
122
+ // Content Management
123
+ export type ContentStatus = 'draft' | 'publish' | 'private' | 'trash';
124
+ export type ContentType = 'post' | 'page';
125
+
126
+ export interface Content {
127
+ id: number;
128
+ pageTitle: string;
129
+ pageContent: string;
130
+ contentMarkdown?: string;
131
+ custom?: Record<string, any>;
132
+ slug?: string;
133
+ pageStatus: ContentStatus;
134
+ pageType: ContentType;
135
+ userId?: number;
136
+ organizationId?: number;
137
+ createdAt: string;
138
+ updatedAt: string;
139
+ }
140
+
141
+ export interface CreateContentRequest {
142
+ page_title: string;
143
+ page_content: string;
144
+ content_markdown?: string;
145
+ custom?: Record<string, any>;
146
+ slug?: string;
147
+ page_status?: ContentStatus;
148
+ page_type?: ContentType;
149
+ }
150
+
151
+ export interface UpdateContentRequest extends Partial<CreateContentRequest> {}
152
+
153
+ export interface ContentQueryParams extends PaginationParams {
154
+ page_status?: ContentStatus;
155
+ page_type?: ContentType;
156
+ search?: string;
157
+ user_id?: number;
158
+ }
159
+
160
+ // Categories
161
+ export interface Category {
162
+ id: number;
163
+ name: string;
164
+ slug: string;
165
+ description?: string;
166
+ parentId?: number;
167
+ organizationId?: number;
168
+ createdAt: string;
169
+ updatedAt: string;
170
+ }
171
+
172
+ export interface CreateCategoryRequest {
173
+ name: string;
174
+ slug?: string;
175
+ description?: string;
176
+ parentId?: number;
177
+ }
178
+
179
+ // Products
180
+ export interface MediaItem {
181
+ media_id: string;
182
+ attachment_id: number;
183
+ file_name: string;
184
+ link: string;
185
+ content_type: string;
186
+ width: number;
187
+ height: number;
188
+ filesize: number;
189
+ r2_key: string;
190
+ site_name: string;
191
+ }
192
+
193
+ export interface Product {
194
+ id: number | string;
195
+ name?: string;
196
+ product?: string;
197
+ description?: string;
198
+ description_markdown?: string;
199
+ price?: number;
200
+ currency?: string;
201
+ sku?: string;
202
+ slug?: string;
203
+ slug_prefix?: string;
204
+ image?: string;
205
+ media?: MediaItem[] | MediaItem[][];
206
+ isActive?: boolean;
207
+ organizationId?: number;
208
+ createdAt?: string;
209
+ updatedAt?: string;
210
+ gateway_product_id_live?: string;
211
+ gateway_product_id_test?: string;
212
+ stripe_product_id_live?: string;
213
+ stripe_product_id_test?: string;
214
+ [key: string]: any;
215
+ }
216
+
217
+ export interface CreateProductRequest {
218
+ name: string;
219
+ description?: string;
220
+ price: number;
221
+ currency?: string;
222
+ sku?: string;
223
+ isActive?: boolean;
224
+ }
225
+
226
+ export interface ProductQueryParams extends PaginationParams {
227
+ organizationId?: number;
228
+ isActive?: boolean;
229
+ search?: string;
230
+ category?: string | string[];
231
+ category_id?: number | string | Array<number | string>;
232
+ }
233
+
234
+ export interface BlogPost {
235
+ id: string | number;
236
+ slug: string;
237
+ slug_prefix?: string;
238
+ page_type?: string;
239
+ title: string;
240
+ content?: string;
241
+ excerpt?: string;
242
+ image?: string;
243
+ published?: boolean;
244
+ created_at?: string;
245
+ updated_at?: string;
246
+ description?: string;
247
+ published_date?: string;
248
+ author?: string;
249
+ tags?: string[];
250
+ [key: string]: any;
251
+ }
252
+
253
+ // Payment Gateways
254
+ export interface PaymentGateway {
255
+ id: number;
256
+ name: string;
257
+ provider: string;
258
+ isActive: boolean;
259
+ configuration: Record<string, any>;
260
+ organizationId?: number;
261
+ createdAt: string;
262
+ updatedAt: string;
263
+ }
264
+
265
+ export interface CreatePaymentGatewayRequest {
266
+ name: string;
267
+ provider: string;
268
+ configuration: Record<string, any>;
269
+ isActive?: boolean;
270
+ }
271
+
272
+ // Webhooks
273
+ export interface Webhook {
274
+ id: string;
275
+ name: string;
276
+ url: string;
277
+ provider: string;
278
+ events: string[];
279
+ isActive: boolean;
280
+ secret?: string;
281
+ organizationId?: number;
282
+ createdAt: string;
283
+ updatedAt: string;
284
+ }
285
+
286
+ export interface CreateWebhookRequest {
287
+ name: string;
288
+ url: string;
289
+ provider: string;
290
+ events: string[];
291
+ isActive?: boolean;
292
+ secret?: string;
293
+ }
294
+
295
+ // Checkout/Stripe
296
+ export type CheckoutMetadataValue =
297
+ | string
298
+ | number
299
+ | boolean
300
+ | null
301
+ | CheckoutMetadataValue[]
302
+ | { [key: string]: CheckoutMetadataValue };
303
+
304
+ export type CheckoutMetadata = Record<string, CheckoutMetadataValue>;
305
+
306
+ export interface CreateCheckoutSessionRequest {
307
+ // Single item checkout (legacy/simple)
308
+ priceId?: string;
309
+ quantity?: number;
310
+
311
+ // Multiple items checkout (recommended)
312
+ line_items?: Array<{
313
+ // Either use existing Stripe price ID
314
+ price?: string;
315
+ quantity: number;
316
+ // Or define price data inline
317
+ price_data?: {
318
+ currency: string;
319
+ product_data: {
320
+ name: string;
321
+ description?: string;
322
+ images?: string[];
323
+ };
324
+ unit_amount: number; // Amount in cents
325
+ };
326
+ }>;
327
+
328
+ // Common fields
329
+ success_url: string; // Required
330
+ cancel_url: string; // Required
331
+ successUrl?: string; // Alternative naming
332
+ cancelUrl?: string; // Alternative naming
333
+ customer_email?: string;
334
+ customerEmail?: string; // Alternative naming
335
+ metadata?: CheckoutMetadata;
336
+ mode?: 'payment' | 'subscription' | 'setup';
337
+ automatic_tax?: {
338
+ enabled: boolean;
339
+ };
340
+ shipping_address_collection?: {
341
+ allowed_countries: string[];
342
+ };
343
+ billing_address_collection?: 'auto' | 'required';
344
+ }
345
+
346
+ export interface CheckoutSession {
347
+ id: string;
348
+ url: string;
349
+ status: string;
350
+ }
351
+
352
+ // Contact Forms
353
+ export interface ContactSubmission {
354
+ id: string;
355
+ name: string;
356
+ email: string;
357
+ subject?: string;
358
+ message: string;
359
+ status: string;
360
+ createdAt: string;
361
+ }
362
+
363
+ export interface CreateContactRequest {
364
+ name: string;
365
+ email: string;
366
+ subject?: string;
367
+ message: string;
368
+ turnstileToken?: string;
369
+ }
370
+
371
+ // Error Types
372
+ export interface ApiError {
373
+ message: string;
374
+ code?: string;
375
+ status?: number;
376
+ details?: any;
377
+ }
378
+
379
+ // SDK Configuration
380
+ export interface PerspectApiConfig {
381
+ baseUrl: string;
382
+ apiKey?: string;
383
+ jwt?: string;
384
+ timeout?: number;
385
+ retries?: number;
386
+ headers?: Record<string, string>;
387
+ }
388
+
389
+ // HTTP Methods
390
+ export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
391
+
392
+ // Request Options
393
+ export interface RequestOptions {
394
+ method?: HttpMethod;
395
+ headers?: Record<string, string>;
396
+ body?: any;
397
+ params?: Record<string, string | number | boolean>;
398
+ timeout?: number;
399
+ }