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.
- package/LICENSE +21 -0
- package/README.md +515 -0
- package/dist/index.d.mts +1770 -0
- package/dist/index.d.ts +1770 -0
- package/dist/index.js +1777 -0
- package/dist/index.mjs +1727 -0
- package/package.json +69 -0
- package/src/client/api-keys-client.ts +103 -0
- package/src/client/auth-client.ts +87 -0
- package/src/client/base-client.ts +100 -0
- package/src/client/categories-client.ts +151 -0
- package/src/client/checkout-client.ts +249 -0
- package/src/client/contact-client.ts +203 -0
- package/src/client/content-client.ts +112 -0
- package/src/client/organizations-client.ts +106 -0
- package/src/client/products-client.ts +247 -0
- package/src/client/sites-client.ts +148 -0
- package/src/client/webhooks-client.ts +199 -0
- package/src/index.ts +74 -0
- package/src/loaders.ts +644 -0
- package/src/perspect-api-client.ts +179 -0
- package/src/types/index.ts +399 -0
- package/src/utils/http-client.ts +268 -0
|
@@ -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
|
+
}
|