perspectapi-ts-sdk 5.4.5 → 6.0.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.
@@ -6,7 +6,11 @@ import { BaseV2Client } from './base-v2-client';
6
6
  import type { CachePolicy } from '../../cache/types';
7
7
  import type {
8
8
  V2NewsletterSubscription, V2NewsletterList, V2NewsletterCampaign,
9
- V2PaginationParams, V2List, V2NewsletterTrackingResponse,
9
+ V2PaginationParams, V2List, V2Deleted, V2NewsletterTrackingResponse,
10
+ V2NewsletterListCreateParams, V2NewsletterListUpdateParams,
11
+ V2NewsletterSyncInput, V2NewsletterSyncResult,
12
+ V2NewsletterSubscriptionListMembershipUpdate,
13
+ V2NewsletterImportRequest, V2NewsletterImportResult,
10
14
  } from '../types';
11
15
 
12
16
  export class NewsletterV2Client extends BaseV2Client {
@@ -122,4 +126,84 @@ export class NewsletterV2Client extends BaseV2Client {
122
126
  cachePolicy,
123
127
  );
124
128
  }
129
+
130
+ // --- Admin writes: Lists CRUD ---
131
+
132
+ async createList(
133
+ siteName: string,
134
+ data: V2NewsletterListCreateParams,
135
+ ): Promise<V2NewsletterList> {
136
+ return this.post<V2NewsletterList>(
137
+ this.sitePath(siteName, 'newsletter', 'lists'),
138
+ data,
139
+ );
140
+ }
141
+
142
+ async updateList(
143
+ siteName: string,
144
+ id: string,
145
+ data: V2NewsletterListUpdateParams,
146
+ ): Promise<V2NewsletterList> {
147
+ return this.patchOne<V2NewsletterList>(
148
+ this.sitePath(siteName, 'newsletter', `lists/${id}`),
149
+ data,
150
+ );
151
+ }
152
+
153
+ async deleteList(siteName: string, id: string): Promise<V2Deleted> {
154
+ return this.deleteOne(
155
+ this.sitePath(siteName, 'newsletter', `lists/${id}`),
156
+ );
157
+ }
158
+
159
+ // --- Admin writes: Subscription sync / membership / import ---
160
+
161
+ /**
162
+ * Upsert a subscription by email and (optionally) replace its list
163
+ * memberships. Returns a `newsletter_sync_result` envelope with the
164
+ * outcome (created / updated / resubscribed / already-unsubscribed).
165
+ */
166
+ async syncSubscription(
167
+ siteName: string,
168
+ data: V2NewsletterSyncInput,
169
+ ): Promise<V2NewsletterSyncResult> {
170
+ return this.post<V2NewsletterSyncResult>(
171
+ this.sitePath(siteName, 'newsletter', 'subscriptions/sync'),
172
+ data,
173
+ );
174
+ }
175
+
176
+ /**
177
+ * Add/remove/replace the list memberships for an existing subscription.
178
+ * Returns the refreshed subscription record.
179
+ */
180
+ async updateSubscriptionListMembership(
181
+ siteName: string,
182
+ subscriptionId: string,
183
+ data: V2NewsletterSubscriptionListMembershipUpdate,
184
+ ): Promise<V2NewsletterSubscription> {
185
+ return this.post<V2NewsletterSubscription>(
186
+ this.sitePath(
187
+ siteName,
188
+ 'newsletter',
189
+ `subscriptions/${subscriptionId}/list-membership`,
190
+ ),
191
+ data,
192
+ );
193
+ }
194
+
195
+ /**
196
+ * Bulk import subscriptions. Each row is upserted via the same sync
197
+ * path; `refreshListCounts` is deferred until after all rows are
198
+ * processed on the server.
199
+ */
200
+ async importSubscriptions(
201
+ siteName: string,
202
+ data: V2NewsletterImportRequest,
203
+ ): Promise<V2NewsletterImportResult> {
204
+ return this.post<V2NewsletterImportResult>(
205
+ this.sitePath(siteName, 'newsletter', 'subscriptions/import'),
206
+ data,
207
+ );
208
+ }
125
209
  }
@@ -1,10 +1,20 @@
1
1
  /**
2
2
  * v2 Orders Client (checkout sessions)
3
+ *
4
+ * `create()` initiates a Stripe checkout session and returns the checkout URL.
5
+ * No CSRF token is needed — v2 uses API-key auth only.
3
6
  */
4
7
 
5
8
  import { BaseV2Client } from './base-v2-client';
6
9
  import type { CachePolicy } from '../../cache/types';
7
- import type { V2Order, V2OrderListParams, V2List } from '../types';
10
+ import type {
11
+ V2Order,
12
+ V2OrderListParams,
13
+ V2OrderCreateParams,
14
+ V2OrderCreateResult,
15
+ V2OrderFulfillmentUpdate,
16
+ V2List,
17
+ } from '../types';
8
18
 
9
19
  export class OrdersV2Client extends BaseV2Client {
10
20
 
@@ -19,4 +29,33 @@ export class OrdersV2Client extends BaseV2Client {
19
29
  async get(siteName: string, id: string, cachePolicy?: CachePolicy): Promise<V2Order> {
20
30
  return this.getOne<V2Order>(this.sitePath(siteName, 'orders', id), undefined, cachePolicy);
21
31
  }
32
+
33
+ /**
34
+ * Create a checkout session via Stripe. Returns the session ID and a
35
+ * `checkout_url` that the client should redirect to (or open in a new tab).
36
+ *
37
+ * This replaces the v1 `checkout.createCheckoutSession()` + `getCsrfToken()`
38
+ * dance — v2 is API-key-only and requires no CSRF token.
39
+ */
40
+ async create(
41
+ siteName: string,
42
+ data: V2OrderCreateParams,
43
+ ): Promise<V2OrderCreateResult> {
44
+ return this.post<V2OrderCreateResult>(
45
+ this.sitePath(siteName, 'orders'),
46
+ data,
47
+ );
48
+ }
49
+
50
+ /** Update fulfillment status, tracking number, and/or notes on an order. */
51
+ async updateFulfillment(
52
+ siteName: string,
53
+ id: string,
54
+ data: V2OrderFulfillmentUpdate,
55
+ ): Promise<V2Order> {
56
+ return this.patchOne<V2Order>(
57
+ this.sitePath(siteName, 'orders', `${id}/fulfillment`),
58
+ data,
59
+ );
60
+ }
22
61
  }
@@ -1,9 +1,24 @@
1
1
  /**
2
2
  * v2 Site Users Client
3
+ *
4
+ * Two classes of endpoints:
5
+ * - Admin paths (list/get/update/OTP flows) require an API key. Use the
6
+ * usual `setApiKey(...)` on the main `PerspectApiV2Client` before calling.
7
+ * - `/me*` paths require a site-user JWT (minted by `verifyOtp`). Call
8
+ * `setAuth(jwt)` on the main client before calling these.
3
9
  */
4
10
 
5
11
  import { BaseV2Client } from './base-v2-client';
6
- import type { V2SiteUser, V2SiteUserUpdateParams, V2SiteUserListParams, V2List } from '../types';
12
+ import type {
13
+ V2SiteUser,
14
+ V2SiteUserUpdateParams,
15
+ V2SiteUserMeUpdateParams,
16
+ V2SiteUserListParams,
17
+ V2SiteUserWithProfile,
18
+ V2SiteUserProfile,
19
+ V2List,
20
+ V2Deleted,
21
+ } from '../types';
7
22
 
8
23
  export interface V2OtpRequestResponse {
9
24
  object: 'otp_request';
@@ -17,7 +32,7 @@ export interface V2OtpVerifyResponse extends V2SiteUser {
17
32
 
18
33
  export class SiteUsersV2Client extends BaseV2Client {
19
34
 
20
- // --- OTP Auth ---
35
+ // --- OTP Auth (public, API-key-scoped) ---
21
36
 
22
37
  async requestOtp(
23
38
  siteName: string,
@@ -33,7 +48,7 @@ export class SiteUsersV2Client extends BaseV2Client {
33
48
  return this.post<V2OtpVerifyResponse>(this.sitePath(siteName, 'users', 'verify-otp'), data);
34
49
  }
35
50
 
36
- // --- Admin ---
51
+ // --- Admin (API key) ---
37
52
 
38
53
  async list(siteName: string, params?: V2SiteUserListParams): Promise<V2List<V2SiteUser>> {
39
54
  return this.getList<V2SiteUser>(this.sitePath(siteName, 'users'), params);
@@ -50,4 +65,62 @@ export class SiteUsersV2Client extends BaseV2Client {
50
65
  async update(siteName: string, id: string, data: V2SiteUserUpdateParams): Promise<V2SiteUser> {
51
66
  return this.patchOne<V2SiteUser>(this.sitePath(siteName, 'users', id), data);
52
67
  }
68
+
69
+ // --- Authenticated "me" endpoints (site-user JWT) ---
70
+
71
+ /**
72
+ * Load the currently-authenticated site user's canonical record plus their
73
+ * profile KV map. Requires `client.setAuth(jwt)` to have been called with
74
+ * the token returned from `verifyOtp`.
75
+ */
76
+ async getMe(siteName: string): Promise<V2SiteUserWithProfile> {
77
+ return this.getOne<V2SiteUserWithProfile>(
78
+ this.sitePath(siteName, 'users', 'me'),
79
+ );
80
+ }
81
+
82
+ /** Update the authenticated user's own fields. */
83
+ async updateMe(
84
+ siteName: string,
85
+ data: V2SiteUserMeUpdateParams,
86
+ ): Promise<V2SiteUser> {
87
+ return this.patchOne<V2SiteUser>(
88
+ this.sitePath(siteName, 'users', 'me'),
89
+ data,
90
+ );
91
+ }
92
+
93
+ /** Fetch the profile KV map as a dedicated `site_user_profile` envelope. */
94
+ async getProfile(siteName: string): Promise<V2SiteUserProfile> {
95
+ return this.getOne<V2SiteUserProfile>(
96
+ this.sitePath(siteName, 'users', 'me/profile'),
97
+ );
98
+ }
99
+
100
+ /**
101
+ * Set a single profile key. The value is persisted verbatim — callers wanting
102
+ * structured data should JSON-stringify their value first.
103
+ */
104
+ async setProfileValue(
105
+ siteName: string,
106
+ key: string,
107
+ value: string,
108
+ ): Promise<V2SiteUserProfile> {
109
+ const encoded = encodeURIComponent(key);
110
+ return this.putOne<V2SiteUserProfile>(
111
+ this.sitePath(siteName, 'users', `me/profile/${encoded}`),
112
+ { value },
113
+ );
114
+ }
115
+
116
+ /** Delete a single profile key. */
117
+ async deleteProfileValue(
118
+ siteName: string,
119
+ key: string,
120
+ ): Promise<V2Deleted> {
121
+ const encoded = encodeURIComponent(key);
122
+ return this.deleteOne(
123
+ this.sitePath(siteName, 'users', `me/profile/${encoded}`),
124
+ );
125
+ }
53
126
  }
@@ -0,0 +1,126 @@
1
+ /**
2
+ * v2 Subscriptions Client — lifecycle operations for site user subscriptions.
3
+ *
4
+ * Two classes of endpoints:
5
+ * - /me paths require a site-user JWT (call `setAuth(jwt)` first)
6
+ * - Admin paths require an API key (call `setApiKey(key)` first)
7
+ */
8
+
9
+ import { BaseV2Client } from './base-v2-client';
10
+ import type {
11
+ V2SiteUserSubscription,
12
+ V2SubscriptionPauseParams,
13
+ V2SubscriptionCancelParams,
14
+ V2SubscriptionChangePlanParams,
15
+ V2CancelSubscriptionResult,
16
+ V2List,
17
+ } from '../types';
18
+
19
+ export class SubscriptionsV2Client extends BaseV2Client {
20
+
21
+ // --- Authenticated "me" endpoints (site-user JWT) ---
22
+
23
+ /** List all subscriptions for the authenticated user. */
24
+ async listMySubscriptions(
25
+ siteName: string,
26
+ ): Promise<V2List<V2SiteUserSubscription>> {
27
+ return this.getList<V2SiteUserSubscription>(
28
+ this.sitePath(siteName, 'users', 'me/subscriptions'),
29
+ );
30
+ }
31
+
32
+ /** Pause a subscription. */
33
+ async pauseSubscription(
34
+ siteName: string,
35
+ subId: string,
36
+ params?: V2SubscriptionPauseParams,
37
+ ): Promise<V2SiteUserSubscription> {
38
+ return this.post<V2SiteUserSubscription>(
39
+ this.sitePath(siteName, 'users', `me/subscriptions/${subId}/pause`),
40
+ params ?? {},
41
+ );
42
+ }
43
+
44
+ /** Resume a paused subscription. */
45
+ async resumeSubscription(
46
+ siteName: string,
47
+ subId: string,
48
+ ): Promise<V2SiteUserSubscription> {
49
+ return this.post<V2SiteUserSubscription>(
50
+ this.sitePath(siteName, 'users', `me/subscriptions/${subId}/resume`),
51
+ );
52
+ }
53
+
54
+ /** Cancel a subscription. */
55
+ async cancelSubscription(
56
+ siteName: string,
57
+ subId: string,
58
+ params?: V2SubscriptionCancelParams,
59
+ ): Promise<V2CancelSubscriptionResult> {
60
+ return this.post<V2CancelSubscriptionResult>(
61
+ this.sitePath(siteName, 'users', `me/subscriptions/${subId}/cancel`),
62
+ params ?? {},
63
+ );
64
+ }
65
+
66
+ /** Change the plan (price) of a subscription. */
67
+ async changeSubscriptionPlan(
68
+ siteName: string,
69
+ subId: string,
70
+ params: V2SubscriptionChangePlanParams,
71
+ ): Promise<V2SiteUserSubscription> {
72
+ return this.post<V2SiteUserSubscription>(
73
+ this.sitePath(siteName, 'users', `me/subscriptions/${subId}/change-plan`),
74
+ params,
75
+ );
76
+ }
77
+
78
+ // --- Admin endpoints (API key) ---
79
+
80
+ /** List subscriptions for a specific user (admin). */
81
+ async listUserSubscriptions(
82
+ siteName: string,
83
+ userId: string,
84
+ ): Promise<V2List<V2SiteUserSubscription>> {
85
+ return this.getList<V2SiteUserSubscription>(
86
+ this.sitePath(siteName, 'users', `${userId}/subscriptions`),
87
+ );
88
+ }
89
+
90
+ /** Pause a user's subscription (admin). */
91
+ async pauseUserSubscription(
92
+ siteName: string,
93
+ userId: string,
94
+ subId: string,
95
+ params?: V2SubscriptionPauseParams,
96
+ ): Promise<V2SiteUserSubscription> {
97
+ return this.post<V2SiteUserSubscription>(
98
+ this.sitePath(siteName, 'users', `${userId}/subscriptions/${subId}/pause`),
99
+ params ?? {},
100
+ );
101
+ }
102
+
103
+ /** Resume a user's paused subscription (admin). */
104
+ async resumeUserSubscription(
105
+ siteName: string,
106
+ userId: string,
107
+ subId: string,
108
+ ): Promise<V2SiteUserSubscription> {
109
+ return this.post<V2SiteUserSubscription>(
110
+ this.sitePath(siteName, 'users', `${userId}/subscriptions/${subId}/resume`),
111
+ );
112
+ }
113
+
114
+ /** Cancel a user's subscription (admin). */
115
+ async cancelUserSubscription(
116
+ siteName: string,
117
+ userId: string,
118
+ subId: string,
119
+ params?: V2SubscriptionCancelParams,
120
+ ): Promise<V2CancelSubscriptionResult> {
121
+ return this.post<V2CancelSubscriptionResult>(
122
+ this.sitePath(siteName, 'users', `${userId}/subscriptions/${subId}/cancel`),
123
+ params ?? {},
124
+ );
125
+ }
126
+ }
package/src/v2/index.ts CHANGED
@@ -27,6 +27,8 @@ import { OrganizationsV2Client } from './client/organizations-client';
27
27
  import { SitesV2Client } from './client/sites-client';
28
28
  import { ApiKeysV2Client } from './client/api-keys-client';
29
29
  import { WebhooksV2Client } from './client/webhooks-client';
30
+ import { SubscriptionsV2Client } from './client/subscriptions-client';
31
+ import { CreditsV2Client } from './client/credits-client';
30
32
 
31
33
  export interface PerspectApiV2Config extends PerspectApiConfig {
32
34
  cache?: CacheConfig;
@@ -48,6 +50,8 @@ export class PerspectApiV2Client {
48
50
  readonly sites: SitesV2Client;
49
51
  readonly apiKeys: ApiKeysV2Client;
50
52
  readonly webhooks: WebhooksV2Client;
53
+ readonly subscriptions: SubscriptionsV2Client;
54
+ readonly credits: CreditsV2Client;
51
55
 
52
56
  constructor(config: PerspectApiV2Config) {
53
57
  // Ensure base URL points to /api/v2
@@ -73,6 +77,8 @@ export class PerspectApiV2Client {
73
77
  this.sites = new SitesV2Client(this.http, basePath, cache);
74
78
  this.apiKeys = new ApiKeysV2Client(this.http, basePath, cache);
75
79
  this.webhooks = new WebhooksV2Client(this.http, basePath, cache);
80
+ this.subscriptions = new SubscriptionsV2Client(this.http, basePath, cache);
81
+ this.credits = new CreditsV2Client(this.http, basePath, cache);
76
82
  }
77
83
 
78
84
  /** Update the JWT token for authenticated requests. */
@@ -112,3 +118,5 @@ export { OrganizationsV2Client } from './client/organizations-client';
112
118
  export { SitesV2Client } from './client/sites-client';
113
119
  export { ApiKeysV2Client } from './client/api-keys-client';
114
120
  export { WebhooksV2Client } from './client/webhooks-client';
121
+ export { SubscriptionsV2Client } from './client/subscriptions-client';
122
+ export { CreditsV2Client } from './client/credits-client';