pocketsflow 1.2.1 → 2.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.
package/README.md CHANGED
@@ -83,6 +83,11 @@ const updated = await pocketsflow.products.update('product_id', {
83
83
 
84
84
  // Delete a product
85
85
  await pocketsflow.products.delete('product_id');
86
+
87
+ // Copy a catalog item (a one-time product or a subscription offer —
88
+ // whichever owns the id). `{ testMode: false }` copies a test-mode offer
89
+ // into live mode; the copy starts unpublished in live mode.
90
+ const copy = await pocketsflow.products.copy('product_id', { testMode: false });
86
91
  ```
87
92
 
88
93
  ### Product Variants
@@ -125,10 +130,33 @@ const customers = await pocketsflow.customers.list({
125
130
  sortOrder: 'desc',
126
131
  });
127
132
 
133
+ // Only buyers of one product or subscription; each customer lists every
134
+ // product they bought in `products`
135
+ const buyers = await pocketsflow.customers.list({ productId: 'product_id' });
136
+ buyers[0].products; // [{ _id: 'product_id', name: 'My course' }, ...]
137
+
128
138
  // Get a customer
129
139
  const customer = await pocketsflow.customers.get('customer_id');
130
140
  ```
131
141
 
142
+ ### Email Subscribers & Product Audiences
143
+
144
+ ```typescript
145
+ // One audience per product or subscription you sell
146
+ const audiences = await pocketsflow.newsletters.audiences.list();
147
+ // [{ productId, name, kind: 'product', subscribers: 120, customers: 140 }, ...]
148
+
149
+ // Add a product's buyers to your email list (omit productId for every buyer)
150
+ const result = await pocketsflow.newsletters.audiences.sync({ productId: 'product_id' });
151
+ // { customers: 140, added: 18, updated: 2, unsubscribed: 1 }
152
+
153
+ // Your email subscribers, optionally only one product audience
154
+ const subscribers = await pocketsflow.newsletters.subscribers.list({
155
+ productId: 'product_id',
156
+ });
157
+ const subscriber = await pocketsflow.newsletters.subscribers.get('subscriber_id');
158
+ ```
159
+
132
160
  ### Reviews
133
161
 
134
162
  ```typescript
package/dist/index.d.mts CHANGED
@@ -47,6 +47,20 @@ interface ProductFile {
47
47
  url: string;
48
48
  size?: number;
49
49
  }
50
+ /**
51
+ * Optional params for `products.copy` (POST /products/copy/{id}).
52
+ *
53
+ * The endpoint duplicates one of your catalog items — a one-time product or
54
+ * a subscription offer, whichever owns the id. Omit `testMode` to copy
55
+ * within the source's own mode; send `{ testMode: false }` to copy a
56
+ * test-mode offer into live mode ("Copy to live"). The copy gets a
57
+ * deduplicated "Name (Copy)" name and starts unpublished when copied into
58
+ * live mode.
59
+ */
60
+ interface CopyCatalogItemParams {
61
+ /** Target mode of the copy. Omit to copy within the source's own mode. */
62
+ testMode?: boolean;
63
+ }
50
64
  interface CreateProductParams {
51
65
  /** Product name (required) */
52
66
  name: string;
@@ -154,6 +168,16 @@ interface Customer {
154
168
  totalSpent: number;
155
169
  testMode: boolean;
156
170
  createdAt: string;
171
+ /**
172
+ * Every product and subscription this buyer has bought (any purchase, not
173
+ * just the first). Returned by `customers.list()`.
174
+ */
175
+ products?: CustomerProduct[];
176
+ }
177
+ /** A product or subscription a customer bought. */
178
+ interface CustomerProduct {
179
+ _id: string;
180
+ name: string;
157
181
  }
158
182
  interface ListCustomersParams {
159
183
  email?: string;
@@ -163,6 +187,48 @@ interface ListCustomersParams {
163
187
  limit?: number;
164
188
  offset?: number;
165
189
  }
190
+ /** A contact on your email list (not a subscription membership). */
191
+ interface EmailSubscriber {
192
+ _id: string;
193
+ userId: string;
194
+ email: string;
195
+ name?: string;
196
+ status: 'active' | 'unsubscribed';
197
+ tags: string[];
198
+ /** Products and subscriptions this contact bought — their product audiences. */
199
+ productIds?: string[];
200
+ createdAt?: string;
201
+ updatedAt?: string;
202
+ }
203
+ interface ListEmailSubscribersParams {
204
+ /** Only contacts in this product audience (a product or subscription ID). */
205
+ productId?: string;
206
+ }
207
+ /** Everyone who bought one product or subscription, as an email audience. */
208
+ interface ProductAudience {
209
+ /** Product or subscription ID. */
210
+ productId: string;
211
+ name: string;
212
+ kind: 'product' | 'subscription';
213
+ /** Contacts already on your list in this audience. */
214
+ subscribers: number;
215
+ /** Buyers of this product, on your list or not. */
216
+ customers: number;
217
+ }
218
+ interface SyncAudienceParams {
219
+ /** Product or subscription ID. Omit to add every buyer. */
220
+ productId?: string;
221
+ }
222
+ interface AudienceSyncResult {
223
+ /** Buyers found. */
224
+ customers: number;
225
+ /** New contacts added to your list. */
226
+ added: number;
227
+ /** Existing contacts newly linked to the product. */
228
+ updated: number;
229
+ /** Buyers who had unsubscribed: linked, but never emailed. */
230
+ unsubscribed: number;
231
+ }
166
232
  interface Review {
167
233
  _id: string;
168
234
  productId: string;
@@ -458,6 +524,8 @@ declare class Pocketsflow {
458
524
  users: UsersResource;
459
525
  checkout: CheckoutResource;
460
526
  refunds: RefundsResource;
527
+ /** Your email list: subscribers and product audiences. */
528
+ newsletters: NewslettersResource;
461
529
  constructor(config: PocketsflowConfig);
462
530
  request<T>(method: string, path: string, options?: {
463
531
  body?: any;
@@ -479,6 +547,17 @@ declare class ProductsResource {
479
547
  delete(id: string): Promise<{
480
548
  message: string;
481
549
  }>;
550
+ /**
551
+ * Copy a catalog item (POC-917): duplicates one of your one-time products
552
+ * OR a subscription offer — whichever owns the id.
553
+ *
554
+ * Send `{ testMode: false }` to copy a test-mode offer into live mode
555
+ * ("Copy to live"); omit params to copy within the source's own mode.
556
+ * The copy gets a deduplicated "Name (Copy)" name and starts unpublished
557
+ * when copied into live mode. A copied one-time product fires the
558
+ * `product.created` webhook against the copy's own mode.
559
+ */
560
+ copy(id: string, params?: CopyCatalogItemParams): Promise<Product | SubscriptionOffer>;
482
561
  }
483
562
  declare class VariantsResource {
484
563
  private client;
@@ -615,5 +694,31 @@ declare class RefundsResource {
615
694
  /** Create a refund */
616
695
  create(params: CreateRefundParams): Promise<Refund>;
617
696
  }
697
+ declare class NewsletterSubscribersResource {
698
+ private client;
699
+ constructor(client: Pocketsflow);
700
+ /** List your email subscribers, optionally only one product audience */
701
+ list(params?: ListEmailSubscribersParams): Promise<EmailSubscriber[]>;
702
+ /** Get an email subscriber by ID */
703
+ get(id: string): Promise<EmailSubscriber>;
704
+ }
705
+ declare class AudiencesResource {
706
+ private client;
707
+ constructor(client: Pocketsflow);
708
+ /** List your product audiences: one per product or subscription you sell */
709
+ list(): Promise<ProductAudience[]>;
710
+ /**
711
+ * Add a product's buyers to your email list (or every buyer, without a
712
+ * productId). Throws a 403 `PocketsflowError` when it would exceed your
713
+ * plan's subscriber limit.
714
+ */
715
+ sync(params?: SyncAudienceParams): Promise<AudienceSyncResult>;
716
+ }
717
+ /** Your email list: subscribers and product audiences. */
718
+ declare class NewslettersResource {
719
+ subscribers: NewsletterSubscribersResource;
720
+ audiences: AudiencesResource;
721
+ constructor(client: Pocketsflow);
722
+ }
618
723
 
619
- export { type ApiError, type CheckoutSession, type CreateCheckoutParams, type CreateDiscountParams, type CreateProductParams, type CreateRefundParams, type CreateSubscriptionOfferParams, type CreateUpsellParams, type CreateVariantParams, type CreateWebhookParams, type Customer, type DateRangeParams, type Discount, type ListCustomersParams, type ListOrdersParams, type ListReviewsParams, type ListSubscriptionsParams, type Order, type OrdersResponse, type PaginatedResponse, type PaginationParams, Pocketsflow, type PocketsflowConfig, PocketsflowError, type Product, type ProductFile, type ProductVariant, type Refund, type Review, type Subscription, type SubscriptionOffer, type UpdateDiscountParams, type UpdateProductParams, type UpdateUpsellParams, type UpdateUserParams, type UpdateWebhookParams, type Upsell, type UpsellsResponse, type User, type Webhook, type WebhookEvent };
724
+ export { type ApiError, type AudienceSyncResult, type CheckoutSession, type CreateCheckoutParams, type CreateDiscountParams, type CreateProductParams, type CreateRefundParams, type CreateSubscriptionOfferParams, type CreateUpsellParams, type CreateVariantParams, type CreateWebhookParams, type Customer, type CustomerProduct, type DateRangeParams, type Discount, type EmailSubscriber, type ListCustomersParams, type ListEmailSubscribersParams, type ListOrdersParams, type ListReviewsParams, type ListSubscriptionsParams, type Order, type OrdersResponse, type PaginatedResponse, type PaginationParams, Pocketsflow, type PocketsflowConfig, PocketsflowError, type Product, type ProductAudience, type ProductFile, type ProductVariant, type Refund, type Review, type Subscription, type SubscriptionOffer, type SyncAudienceParams, type UpdateDiscountParams, type UpdateProductParams, type UpdateUpsellParams, type UpdateUserParams, type UpdateWebhookParams, type Upsell, type UpsellsResponse, type User, type Webhook, type WebhookEvent };
package/dist/index.d.ts CHANGED
@@ -47,6 +47,20 @@ interface ProductFile {
47
47
  url: string;
48
48
  size?: number;
49
49
  }
50
+ /**
51
+ * Optional params for `products.copy` (POST /products/copy/{id}).
52
+ *
53
+ * The endpoint duplicates one of your catalog items — a one-time product or
54
+ * a subscription offer, whichever owns the id. Omit `testMode` to copy
55
+ * within the source's own mode; send `{ testMode: false }` to copy a
56
+ * test-mode offer into live mode ("Copy to live"). The copy gets a
57
+ * deduplicated "Name (Copy)" name and starts unpublished when copied into
58
+ * live mode.
59
+ */
60
+ interface CopyCatalogItemParams {
61
+ /** Target mode of the copy. Omit to copy within the source's own mode. */
62
+ testMode?: boolean;
63
+ }
50
64
  interface CreateProductParams {
51
65
  /** Product name (required) */
52
66
  name: string;
@@ -154,6 +168,16 @@ interface Customer {
154
168
  totalSpent: number;
155
169
  testMode: boolean;
156
170
  createdAt: string;
171
+ /**
172
+ * Every product and subscription this buyer has bought (any purchase, not
173
+ * just the first). Returned by `customers.list()`.
174
+ */
175
+ products?: CustomerProduct[];
176
+ }
177
+ /** A product or subscription a customer bought. */
178
+ interface CustomerProduct {
179
+ _id: string;
180
+ name: string;
157
181
  }
158
182
  interface ListCustomersParams {
159
183
  email?: string;
@@ -163,6 +187,48 @@ interface ListCustomersParams {
163
187
  limit?: number;
164
188
  offset?: number;
165
189
  }
190
+ /** A contact on your email list (not a subscription membership). */
191
+ interface EmailSubscriber {
192
+ _id: string;
193
+ userId: string;
194
+ email: string;
195
+ name?: string;
196
+ status: 'active' | 'unsubscribed';
197
+ tags: string[];
198
+ /** Products and subscriptions this contact bought — their product audiences. */
199
+ productIds?: string[];
200
+ createdAt?: string;
201
+ updatedAt?: string;
202
+ }
203
+ interface ListEmailSubscribersParams {
204
+ /** Only contacts in this product audience (a product or subscription ID). */
205
+ productId?: string;
206
+ }
207
+ /** Everyone who bought one product or subscription, as an email audience. */
208
+ interface ProductAudience {
209
+ /** Product or subscription ID. */
210
+ productId: string;
211
+ name: string;
212
+ kind: 'product' | 'subscription';
213
+ /** Contacts already on your list in this audience. */
214
+ subscribers: number;
215
+ /** Buyers of this product, on your list or not. */
216
+ customers: number;
217
+ }
218
+ interface SyncAudienceParams {
219
+ /** Product or subscription ID. Omit to add every buyer. */
220
+ productId?: string;
221
+ }
222
+ interface AudienceSyncResult {
223
+ /** Buyers found. */
224
+ customers: number;
225
+ /** New contacts added to your list. */
226
+ added: number;
227
+ /** Existing contacts newly linked to the product. */
228
+ updated: number;
229
+ /** Buyers who had unsubscribed: linked, but never emailed. */
230
+ unsubscribed: number;
231
+ }
166
232
  interface Review {
167
233
  _id: string;
168
234
  productId: string;
@@ -458,6 +524,8 @@ declare class Pocketsflow {
458
524
  users: UsersResource;
459
525
  checkout: CheckoutResource;
460
526
  refunds: RefundsResource;
527
+ /** Your email list: subscribers and product audiences. */
528
+ newsletters: NewslettersResource;
461
529
  constructor(config: PocketsflowConfig);
462
530
  request<T>(method: string, path: string, options?: {
463
531
  body?: any;
@@ -479,6 +547,17 @@ declare class ProductsResource {
479
547
  delete(id: string): Promise<{
480
548
  message: string;
481
549
  }>;
550
+ /**
551
+ * Copy a catalog item (POC-917): duplicates one of your one-time products
552
+ * OR a subscription offer — whichever owns the id.
553
+ *
554
+ * Send `{ testMode: false }` to copy a test-mode offer into live mode
555
+ * ("Copy to live"); omit params to copy within the source's own mode.
556
+ * The copy gets a deduplicated "Name (Copy)" name and starts unpublished
557
+ * when copied into live mode. A copied one-time product fires the
558
+ * `product.created` webhook against the copy's own mode.
559
+ */
560
+ copy(id: string, params?: CopyCatalogItemParams): Promise<Product | SubscriptionOffer>;
482
561
  }
483
562
  declare class VariantsResource {
484
563
  private client;
@@ -615,5 +694,31 @@ declare class RefundsResource {
615
694
  /** Create a refund */
616
695
  create(params: CreateRefundParams): Promise<Refund>;
617
696
  }
697
+ declare class NewsletterSubscribersResource {
698
+ private client;
699
+ constructor(client: Pocketsflow);
700
+ /** List your email subscribers, optionally only one product audience */
701
+ list(params?: ListEmailSubscribersParams): Promise<EmailSubscriber[]>;
702
+ /** Get an email subscriber by ID */
703
+ get(id: string): Promise<EmailSubscriber>;
704
+ }
705
+ declare class AudiencesResource {
706
+ private client;
707
+ constructor(client: Pocketsflow);
708
+ /** List your product audiences: one per product or subscription you sell */
709
+ list(): Promise<ProductAudience[]>;
710
+ /**
711
+ * Add a product's buyers to your email list (or every buyer, without a
712
+ * productId). Throws a 403 `PocketsflowError` when it would exceed your
713
+ * plan's subscriber limit.
714
+ */
715
+ sync(params?: SyncAudienceParams): Promise<AudienceSyncResult>;
716
+ }
717
+ /** Your email list: subscribers and product audiences. */
718
+ declare class NewslettersResource {
719
+ subscribers: NewsletterSubscribersResource;
720
+ audiences: AudiencesResource;
721
+ constructor(client: Pocketsflow);
722
+ }
618
723
 
619
- export { type ApiError, type CheckoutSession, type CreateCheckoutParams, type CreateDiscountParams, type CreateProductParams, type CreateRefundParams, type CreateSubscriptionOfferParams, type CreateUpsellParams, type CreateVariantParams, type CreateWebhookParams, type Customer, type DateRangeParams, type Discount, type ListCustomersParams, type ListOrdersParams, type ListReviewsParams, type ListSubscriptionsParams, type Order, type OrdersResponse, type PaginatedResponse, type PaginationParams, Pocketsflow, type PocketsflowConfig, PocketsflowError, type Product, type ProductFile, type ProductVariant, type Refund, type Review, type Subscription, type SubscriptionOffer, type UpdateDiscountParams, type UpdateProductParams, type UpdateUpsellParams, type UpdateUserParams, type UpdateWebhookParams, type Upsell, type UpsellsResponse, type User, type Webhook, type WebhookEvent };
724
+ export { type ApiError, type AudienceSyncResult, type CheckoutSession, type CreateCheckoutParams, type CreateDiscountParams, type CreateProductParams, type CreateRefundParams, type CreateSubscriptionOfferParams, type CreateUpsellParams, type CreateVariantParams, type CreateWebhookParams, type Customer, type CustomerProduct, type DateRangeParams, type Discount, type EmailSubscriber, type ListCustomersParams, type ListEmailSubscribersParams, type ListOrdersParams, type ListReviewsParams, type ListSubscriptionsParams, type Order, type OrdersResponse, type PaginatedResponse, type PaginationParams, Pocketsflow, type PocketsflowConfig, PocketsflowError, type Product, type ProductAudience, type ProductFile, type ProductVariant, type Refund, type Review, type Subscription, type SubscriptionOffer, type SyncAudienceParams, type UpdateDiscountParams, type UpdateProductParams, type UpdateUpsellParams, type UpdateUserParams, type UpdateWebhookParams, type Upsell, type UpsellsResponse, type User, type Webhook, type WebhookEvent };
package/dist/index.js CHANGED
@@ -59,6 +59,7 @@ var Pocketsflow = class {
59
59
  this.users = new UsersResource(this);
60
60
  this.checkout = new CheckoutResource(this);
61
61
  this.refunds = new RefundsResource(this);
62
+ this.newsletters = new NewslettersResource(this);
62
63
  }
63
64
  async request(method, path, options = {}) {
64
65
  const url = new URL(path, this.baseUrl);
@@ -137,6 +138,23 @@ var ProductsResource = class {
137
138
  async delete(id) {
138
139
  return this.client.request("DELETE", `/products/${id}`);
139
140
  }
141
+ /**
142
+ * Copy a catalog item (POC-917): duplicates one of your one-time products
143
+ * OR a subscription offer — whichever owns the id.
144
+ *
145
+ * Send `{ testMode: false }` to copy a test-mode offer into live mode
146
+ * ("Copy to live"); omit params to copy within the source's own mode.
147
+ * The copy gets a deduplicated "Name (Copy)" name and starts unpublished
148
+ * when copied into live mode. A copied one-time product fires the
149
+ * `product.created` webhook against the copy's own mode.
150
+ */
151
+ async copy(id, params = {}) {
152
+ return this.client.request(
153
+ "POST",
154
+ `/products/copy/${id}`,
155
+ { body: params }
156
+ );
157
+ }
140
158
  };
141
159
  var VariantsResource = class {
142
160
  constructor(client) {
@@ -348,6 +366,46 @@ var RefundsResource = class {
348
366
  return this.client.request("POST", "/refunds", { body: params });
349
367
  }
350
368
  };
369
+ var NewsletterSubscribersResource = class {
370
+ constructor(client) {
371
+ this.client = client;
372
+ }
373
+ /** List your email subscribers, optionally only one product audience */
374
+ async list(params = {}) {
375
+ return this.client.request("GET", "/newsletters/subscribers", {
376
+ params
377
+ });
378
+ }
379
+ /** Get an email subscriber by ID */
380
+ async get(id) {
381
+ return this.client.request("GET", `/newsletters/subscribers/${id}`);
382
+ }
383
+ };
384
+ var AudiencesResource = class {
385
+ constructor(client) {
386
+ this.client = client;
387
+ }
388
+ /** List your product audiences: one per product or subscription you sell */
389
+ async list() {
390
+ return this.client.request("GET", "/newsletters/audiences");
391
+ }
392
+ /**
393
+ * Add a product's buyers to your email list (or every buyer, without a
394
+ * productId). Throws a 403 `PocketsflowError` when it would exceed your
395
+ * plan's subscriber limit.
396
+ */
397
+ async sync(params = {}) {
398
+ return this.client.request("POST", "/newsletters/audiences/sync", {
399
+ body: params
400
+ });
401
+ }
402
+ };
403
+ var NewslettersResource = class {
404
+ constructor(client) {
405
+ this.subscribers = new NewsletterSubscribersResource(client);
406
+ this.audiences = new AudiencesResource(client);
407
+ }
408
+ };
351
409
  // Annotate the CommonJS export names for ESM import in node:
352
410
  0 && (module.exports = {
353
411
  Pocketsflow,
package/dist/index.mjs CHANGED
@@ -32,6 +32,7 @@ var Pocketsflow = class {
32
32
  this.users = new UsersResource(this);
33
33
  this.checkout = new CheckoutResource(this);
34
34
  this.refunds = new RefundsResource(this);
35
+ this.newsletters = new NewslettersResource(this);
35
36
  }
36
37
  async request(method, path, options = {}) {
37
38
  const url = new URL(path, this.baseUrl);
@@ -110,6 +111,23 @@ var ProductsResource = class {
110
111
  async delete(id) {
111
112
  return this.client.request("DELETE", `/products/${id}`);
112
113
  }
114
+ /**
115
+ * Copy a catalog item (POC-917): duplicates one of your one-time products
116
+ * OR a subscription offer — whichever owns the id.
117
+ *
118
+ * Send `{ testMode: false }` to copy a test-mode offer into live mode
119
+ * ("Copy to live"); omit params to copy within the source's own mode.
120
+ * The copy gets a deduplicated "Name (Copy)" name and starts unpublished
121
+ * when copied into live mode. A copied one-time product fires the
122
+ * `product.created` webhook against the copy's own mode.
123
+ */
124
+ async copy(id, params = {}) {
125
+ return this.client.request(
126
+ "POST",
127
+ `/products/copy/${id}`,
128
+ { body: params }
129
+ );
130
+ }
113
131
  };
114
132
  var VariantsResource = class {
115
133
  constructor(client) {
@@ -321,6 +339,46 @@ var RefundsResource = class {
321
339
  return this.client.request("POST", "/refunds", { body: params });
322
340
  }
323
341
  };
342
+ var NewsletterSubscribersResource = class {
343
+ constructor(client) {
344
+ this.client = client;
345
+ }
346
+ /** List your email subscribers, optionally only one product audience */
347
+ async list(params = {}) {
348
+ return this.client.request("GET", "/newsletters/subscribers", {
349
+ params
350
+ });
351
+ }
352
+ /** Get an email subscriber by ID */
353
+ async get(id) {
354
+ return this.client.request("GET", `/newsletters/subscribers/${id}`);
355
+ }
356
+ };
357
+ var AudiencesResource = class {
358
+ constructor(client) {
359
+ this.client = client;
360
+ }
361
+ /** List your product audiences: one per product or subscription you sell */
362
+ async list() {
363
+ return this.client.request("GET", "/newsletters/audiences");
364
+ }
365
+ /**
366
+ * Add a product's buyers to your email list (or every buyer, without a
367
+ * productId). Throws a 403 `PocketsflowError` when it would exceed your
368
+ * plan's subscriber limit.
369
+ */
370
+ async sync(params = {}) {
371
+ return this.client.request("POST", "/newsletters/audiences/sync", {
372
+ body: params
373
+ });
374
+ }
375
+ };
376
+ var NewslettersResource = class {
377
+ constructor(client) {
378
+ this.subscribers = new NewsletterSubscribersResource(client);
379
+ this.audiences = new AudiencesResource(client);
380
+ }
381
+ };
324
382
  export {
325
383
  Pocketsflow,
326
384
  PocketsflowError
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pocketsflow",
3
- "version": "1.2.1",
3
+ "version": "2.0.0",
4
4
  "description": "Official Pocketsflow SDK for Node.js and TypeScript",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",