fresh-squeezy 0.2.0 → 0.3.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/dist/index.cjs CHANGED
@@ -32,81 +32,24 @@ __export(src_exports, {
32
32
  SUPPORTED_RESOURCES: () => SUPPORTED_RESOURCES,
33
33
  buildResult: () => buildResult,
34
34
  buildSubscriptionItemUpdateBody: () => buildSubscriptionItemUpdateBody,
35
- cancelSubscription: () => cancelSubscription,
36
35
  checkDiscount: () => checkDiscount,
37
36
  checkLicenseKey: () => checkLicenseKey,
38
37
  checkProduct: () => checkProduct,
39
38
  checkSubscriptionPlan: () => checkSubscriptionPlan,
40
- createCheckout: () => createCheckout,
41
- createCustomer: () => createCustomer,
42
- createDiscount: () => createDiscount,
43
39
  createFreshSqueezy: () => createFreshSqueezy,
44
- createUsageRecord: () => createUsageRecord,
45
- createWebhook: () => createWebhook,
46
- deleteDiscount: () => deleteDiscount,
47
- deleteWebhook: () => deleteWebhook,
48
40
  doctor: () => doctor,
49
41
  fetchActualMode: () => fetchActualMode,
50
42
  findResourceVerb: () => findResourceVerb,
51
- generateOrderInvoice: () => generateOrderInvoice,
52
- generateSubscriptionInvoice: () => generateSubscriptionInvoice,
53
- getAffiliate: () => getAffiliate,
54
- getAuthenticatedUser: () => getAuthenticatedUser,
55
- getCheckout: () => getCheckout,
56
- getCustomer: () => getCustomer,
57
- getDiscount: () => getDiscount,
58
- getDiscountRedemption: () => getDiscountRedemption,
59
- getFile: () => getFile,
60
- getLicenseKey: () => getLicenseKey,
61
- getLicenseKeyInstance: () => getLicenseKeyInstance,
62
- getOrder: () => getOrder,
63
- getOrderItem: () => getOrderItem,
64
- getPrice: () => getPrice,
65
- getProduct: () => getProduct,
66
- getStore: () => getStore,
67
- getSubscription: () => getSubscription,
68
- getSubscriptionInvoice: () => getSubscriptionInvoice,
69
- getSubscriptionItem: () => getSubscriptionItem,
70
- getSubscriptionItemCurrentUsage: () => getSubscriptionItemCurrentUsage,
71
- getUsageRecord: () => getUsageRecord,
72
- getVariant: () => getVariant,
73
- getWebhook: () => getWebhook,
74
43
  invokeOp: () => invokeOp,
75
44
  isOk: () => isOk,
76
45
  issue: () => issue,
77
- listAffiliatesForStore: () => listAffiliatesForStore,
78
- listCheckoutsForStore: () => listCheckoutsForStore,
79
- listCustomersForStore: () => listCustomersForStore,
80
- listDiscountRedemptionsForDiscount: () => listDiscountRedemptionsForDiscount,
81
- listDiscountsForStore: () => listDiscountsForStore,
82
- listFilesForVariant: () => listFilesForVariant,
83
- listLicenseKeyInstancesForLicenseKey: () => listLicenseKeyInstancesForLicenseKey,
84
- listLicenseKeysForStore: () => listLicenseKeysForStore,
85
- listOrderItemsForOrder: () => listOrderItemsForOrder,
86
- listOrdersForStore: () => listOrdersForStore,
87
- listPricesForVariant: () => listPricesForVariant,
88
- listProducts: () => listProducts,
89
46
  listRegisteredResources: () => listRegisteredResources,
90
47
  listRegisteredVerbs: () => listRegisteredVerbs,
91
- listStores: () => listStores,
92
- listSubscriptionInvoicesForSubscription: () => listSubscriptionInvoicesForSubscription,
93
- listSubscriptionItemsForSubscription: () => listSubscriptionItemsForSubscription,
94
- listSubscriptionsForStore: () => listSubscriptionsForStore,
95
- listUsageRecordsForSubscriptionItem: () => listUsageRecordsForSubscriptionItem,
96
- listVariantsForProduct: () => listVariantsForProduct,
97
- listWebhooksForStore: () => listWebhooksForStore,
98
48
  normalizeResourceName: () => normalizeResourceName,
99
- refundOrder: () => refundOrder,
100
- refundSubscriptionInvoice: () => refundSubscriptionInvoice,
101
49
  resolveActualMode: () => resolveActualMode,
102
50
  resolveConfig: () => resolveConfig,
103
51
  resourceRegistry: () => resourceRegistry,
104
52
  sameWebhookUrl: () => sameWebhookUrl,
105
- updateCustomer: () => updateCustomer,
106
- updateLicenseKey: () => updateLicenseKey,
107
- updateSubscription: () => updateSubscription,
108
- updateSubscriptionItem: () => updateSubscriptionItem,
109
- updateWebhook: () => updateWebhook,
110
53
  validateConnection: () => validateConnection,
111
54
  validateDiscount: () => validateDiscount,
112
55
  validateLicenseKey: () => validateLicenseKey,
@@ -211,597 +154,95 @@ var normalizeMode = (value) => {
211
154
  });
212
155
  };
213
156
 
214
- // src/core/equality.ts
215
- var sameWebhookUrl = (a, b) => {
216
- return normalizeWebhookUrl(a) === normalizeWebhookUrl(b);
217
- };
218
- var normalizeWebhookUrl = (raw) => {
219
- return raw.replace(/\/+$/, "").toLowerCase();
220
- };
221
-
222
- // src/core/mode.ts
223
- var resolveActualMode = (testMode) => {
224
- if (testMode === true) return "test";
225
- if (testMode === false) return "live";
226
- return void 0;
227
- };
228
-
229
- // src/resources/affiliates.ts
230
- var getAffiliate = async (http, affiliateId) => {
231
- return http.getResource(`/v1/affiliates/${affiliateId}`);
232
- };
233
- var listAffiliatesForStore = async (http, storeId) => {
234
- return http.paginate("/v1/affiliates", {
235
- "filter[store_id]": String(storeId)
236
- });
237
- };
238
-
239
- // src/resources/checkouts.ts
240
- var getCheckout = async (http, checkoutId) => {
241
- return http.getResource(`/v1/checkouts/${checkoutId}`);
242
- };
243
- var listCheckoutsForStore = async (http, storeId) => {
244
- return http.paginate("/v1/checkouts", {
245
- "filter[store_id]": String(storeId)
246
- });
247
- };
248
- var createCheckout = async (http, body) => {
249
- return http.postResource("/v1/checkouts", body);
250
- };
251
-
252
- // src/resources/customers.ts
253
- var getCustomer = async (http, customerId) => {
254
- return http.getResource(`/v1/customers/${customerId}`);
255
- };
256
- var listCustomersForStore = async (http, storeId) => {
257
- return http.paginate("/v1/customers", {
258
- "filter[store_id]": String(storeId)
259
- });
260
- };
261
- var createCustomer = async (http, body) => {
262
- return http.postResource("/v1/customers", body);
263
- };
264
- var updateCustomer = async (http, customerId, body) => {
265
- return http.patchResource(`/v1/customers/${customerId}`, body);
266
- };
267
-
268
- // src/resources/discountRedemptions.ts
269
- var getDiscountRedemption = async (http, discountRedemptionId) => {
270
- return http.getResource(
271
- `/v1/discount-redemptions/${discountRedemptionId}`
272
- );
273
- };
274
- var listDiscountRedemptionsForDiscount = async (http, discountId) => {
275
- return http.paginate("/v1/discount-redemptions", {
276
- "filter[discount_id]": String(discountId)
277
- });
278
- };
279
-
280
- // src/resources/discounts.ts
281
- var getDiscount = async (http, discountId) => {
282
- return http.getResource(`/v1/discounts/${discountId}`);
283
- };
284
- var listDiscountsForStore = async (http, storeId) => {
285
- return http.paginate("/v1/discounts", {
286
- "filter[store_id]": String(storeId)
287
- });
288
- };
289
- var createDiscount = async (http, body) => {
290
- return http.postResource("/v1/discounts", body);
291
- };
292
- var deleteDiscount = async (http, discountId) => {
293
- await http.deleteResource(`/v1/discounts/${discountId}`);
294
- };
295
-
296
- // src/resources/files.ts
297
- var getFile = async (http, fileId) => {
298
- return http.getResource(`/v1/files/${fileId}`);
299
- };
300
- var listFilesForVariant = async (http, variantId) => {
301
- return http.paginate("/v1/files", {
302
- "filter[variant_id]": String(variantId)
303
- });
304
- };
305
-
306
- // src/resources/licenseKeyInstances.ts
307
- var getLicenseKeyInstance = async (http, licenseKeyInstanceId) => {
308
- return http.getResource(
309
- `/v1/license-key-instances/${licenseKeyInstanceId}`
310
- );
311
- };
312
- var listLicenseKeyInstancesForLicenseKey = async (http, licenseKeyId) => {
313
- return http.paginate("/v1/license-key-instances", {
314
- "filter[license_key_id]": String(licenseKeyId)
315
- });
316
- };
317
-
318
- // src/resources/licenseKeys.ts
319
- var getLicenseKey = async (http, licenseKeyId) => {
320
- return http.getResource(`/v1/license-keys/${licenseKeyId}`);
321
- };
322
- var listLicenseKeysForStore = async (http, storeId) => {
323
- return http.paginate("/v1/license-keys", {
324
- "filter[store_id]": String(storeId)
325
- });
326
- };
327
- var updateLicenseKey = async (http, licenseKeyId, body) => {
328
- return http.patchResource(`/v1/license-keys/${licenseKeyId}`, body);
329
- };
330
-
331
- // src/resources/orderItems.ts
332
- var getOrderItem = async (http, orderItemId) => {
333
- return http.getResource(`/v1/order-items/${orderItemId}`);
334
- };
335
- var listOrderItemsForOrder = async (http, orderId) => {
336
- return http.paginate("/v1/order-items", {
337
- "filter[order_id]": String(orderId)
338
- });
339
- };
340
-
341
- // src/resources/orders.ts
342
- var getOrder = async (http, orderId) => {
343
- return http.getResource(`/v1/orders/${orderId}`);
344
- };
345
- var listOrdersForStore = async (http, storeId) => {
346
- return http.paginate("/v1/orders", {
347
- "filter[store_id]": String(storeId)
348
- });
349
- };
350
- var refundOrder = async (http, orderId, body) => {
351
- return http.postResource(`/v1/orders/${orderId}/refund`, body ?? {});
352
- };
353
- var generateOrderInvoice = async (http, orderId, body) => {
354
- return http.request({
355
- method: "POST",
356
- path: `/v1/orders/${orderId}/generate-invoice`,
357
- body: body ?? {}
358
- });
359
- };
360
-
361
- // src/resources/prices.ts
362
- var getPrice = async (http, priceId) => {
363
- return http.getResource(`/v1/prices/${priceId}`);
364
- };
365
- var listPricesForVariant = async (http, variantId) => {
366
- return http.paginate("/v1/prices", {
367
- "filter[variant_id]": String(variantId)
368
- });
369
- };
370
-
371
- // src/resources/products.ts
372
- var getProduct = async (http, productId) => {
373
- return http.getResource(`/v1/products/${productId}`);
374
- };
375
- var listProducts = async (http, storeId) => {
376
- return http.paginate("/v1/products", {
377
- "filter[store_id]": String(storeId)
378
- });
157
+ // src/resources/attributes.ts
158
+ var buildSubscriptionItemUpdateBody = (subscriptionItemId, attributes) => {
159
+ return {
160
+ data: {
161
+ type: "subscription-items",
162
+ id: String(subscriptionItemId),
163
+ attributes
164
+ }
165
+ };
379
166
  };
380
167
 
381
168
  // src/resources/registry.ts
382
- var resourceRegistry = [
383
- // users
384
- { resource: "user", verb: "get", docsPath: "users/retrieve-user", body: "none", idRole: "none" },
385
- // stores (read-only)
386
- { resource: "store", verb: "get", docsPath: "stores/retrieve-store", body: "none", idRole: "id" },
387
- {
388
- resource: "store",
389
- verb: "list",
390
- docsPath: "stores/list-all-stores",
391
- body: "none",
392
- idRole: "none"
393
- },
394
- // products (read-only)
395
- {
396
- resource: "product",
397
- verb: "get",
398
- docsPath: "products/retrieve-product",
399
- body: "none",
400
- idRole: "id"
401
- },
402
- {
403
- resource: "product",
404
- verb: "list",
405
- docsPath: "products/list-all-products",
406
- body: "none",
407
- idRole: "store"
408
- },
409
- // variants (read-only)
410
- {
411
- resource: "variant",
412
- verb: "get",
413
- docsPath: "variants/retrieve-variant",
414
- body: "none",
415
- idRole: "id"
416
- },
417
- {
418
- resource: "variant",
419
- verb: "list",
420
- docsPath: "variants/list-all-variants",
421
- body: "none",
422
- idRole: "parent"
423
- },
424
- // prices (read-only)
425
- { resource: "price", verb: "get", docsPath: "prices/retrieve-price", body: "none", idRole: "id" },
426
- {
427
- resource: "price",
428
- verb: "list",
429
- docsPath: "prices/list-all-prices",
430
- body: "none",
431
- idRole: "parent"
432
- },
433
- // files (read-only)
434
- { resource: "file", verb: "get", docsPath: "files/retrieve-file", body: "none", idRole: "id" },
435
- {
436
- resource: "file",
437
- verb: "list",
438
- docsPath: "files/list-all-files",
439
- body: "none",
440
- idRole: "parent"
441
- },
442
- // customers
443
- {
444
- resource: "customer",
445
- verb: "get",
446
- docsPath: "customers/retrieve-customer",
447
- body: "none",
448
- idRole: "id"
449
- },
450
- {
451
- resource: "customer",
452
- verb: "list",
453
- docsPath: "customers/list-all-customers",
454
- body: "none",
455
- idRole: "store"
456
- },
457
- {
458
- resource: "customer",
459
- verb: "create",
460
- docsPath: "customers/create-customer",
461
- body: "required",
462
- idRole: "none"
463
- },
464
- {
465
- resource: "customer",
466
- verb: "update",
467
- docsPath: "customers/update-customer",
468
- body: "required",
469
- idRole: "id"
470
- },
471
- // orders
472
- { resource: "order", verb: "get", docsPath: "orders/retrieve-order", body: "none", idRole: "id" },
473
- {
474
- resource: "order",
475
- verb: "list",
476
- docsPath: "orders/list-all-orders",
477
- body: "none",
478
- idRole: "store"
479
- },
480
- {
481
- resource: "order",
482
- verb: "refund",
483
- docsPath: "orders/issue-refund",
484
- body: "optional",
485
- destructive: true,
486
- idRole: "id"
487
- },
488
- {
489
- resource: "order",
490
- verb: "generate-invoice",
491
- docsPath: "orders/generate-order-invoice",
492
- body: "optional",
493
- idRole: "id"
494
- },
495
- // order-items (read-only)
496
- {
497
- resource: "order-item",
498
- verb: "get",
499
- docsPath: "order-items/retrieve-order-item",
500
- body: "none",
501
- idRole: "id"
502
- },
503
- {
504
- resource: "order-item",
505
- verb: "list",
506
- docsPath: "order-items/list-all-order-items",
507
- body: "none",
508
- idRole: "parent"
509
- },
510
- // subscriptions
511
- {
512
- resource: "subscription",
513
- verb: "get",
514
- docsPath: "subscriptions/retrieve-subscription",
515
- body: "none",
516
- idRole: "id"
517
- },
518
- {
519
- resource: "subscription",
520
- verb: "list",
521
- docsPath: "subscriptions/list-all-subscriptions",
522
- body: "none",
523
- idRole: "store"
524
- },
525
- {
526
- resource: "subscription",
527
- verb: "update",
528
- docsPath: "subscriptions/update-subscription",
529
- body: "required",
530
- idRole: "id"
531
- },
532
- {
533
- resource: "subscription",
534
- verb: "cancel",
535
- docsPath: "subscriptions/cancel-subscription",
536
- body: "none",
537
- destructive: true,
538
- idRole: "id"
539
- },
540
- // subscription-items
541
- {
542
- resource: "subscription-item",
543
- verb: "get",
544
- docsPath: "subscription-items/retrieve-subscription-item",
545
- body: "none",
546
- idRole: "id"
547
- },
548
- {
549
- resource: "subscription-item",
550
- verb: "list",
551
- docsPath: "subscription-items/list-all-subscription-items",
552
- body: "none",
553
- idRole: "parent"
554
- },
555
- {
556
- resource: "subscription-item",
557
- verb: "update",
558
- docsPath: "subscription-items/update-subscription-item",
559
- body: "required",
560
- idRole: "id"
561
- },
562
- {
563
- resource: "subscription-item",
564
- verb: "current-usage",
565
- docsPath: "subscription-items/retrieve-subscription-item-current-usage",
566
- body: "none",
567
- idRole: "id"
568
- },
569
- // subscription-invoices
570
- {
571
- resource: "subscription-invoice",
572
- verb: "get",
573
- docsPath: "subscription-invoices/retrieve-subscription-invoice",
574
- body: "none",
575
- idRole: "id"
576
- },
577
- {
578
- resource: "subscription-invoice",
579
- verb: "list",
580
- docsPath: "subscription-invoices/list-all-subscription-invoices",
581
- body: "none",
582
- idRole: "parent"
583
- },
584
- {
585
- resource: "subscription-invoice",
586
- verb: "refund",
587
- docsPath: "subscription-invoices/issue-refund",
588
- body: "optional",
589
- destructive: true,
590
- idRole: "id"
591
- },
592
- {
593
- resource: "subscription-invoice",
594
- verb: "generate-invoice",
595
- docsPath: "subscription-invoices/generate-subscription-invoice",
169
+ var VERB_RULES = {
170
+ get: { method: "GET", path: "/{id}", docs: "retrieve-{r}", body: "none" },
171
+ list: { method: "GET", path: "", docs: "list-all-{r}s", body: "none" },
172
+ create: { method: "POST", path: "", docs: "create-{r}", body: "required" },
173
+ update: { method: "PATCH", path: "/{id}", docs: "update-{r}", body: "required" },
174
+ delete: { method: "DELETE", path: "/{id}", docs: "delete-{r}", body: "none", destructive: true },
175
+ cancel: { method: "DELETE", path: "/{id}", docs: "cancel-{r}", body: "none", destructive: true },
176
+ refund: {
177
+ method: "POST",
178
+ path: "/{id}/refund",
179
+ docs: "issue-refund",
596
180
  body: "optional",
597
- idRole: "id"
598
- },
599
- // usage-records
600
- {
601
- resource: "usage-record",
602
- verb: "get",
603
- docsPath: "usage-records/retrieve-usage-record",
604
- body: "none",
605
- idRole: "id"
606
- },
607
- {
608
- resource: "usage-record",
609
- verb: "list",
610
- docsPath: "usage-records/list-all-usage-records",
611
- body: "none",
612
- idRole: "parent"
613
- },
614
- {
615
- resource: "usage-record",
616
- verb: "create",
617
- docsPath: "usage-records/create-usage-record",
618
- body: "required",
619
- idRole: "none"
620
- },
621
- // discounts
622
- {
623
- resource: "discount",
624
- verb: "get",
625
- docsPath: "discounts/retrieve-discount",
626
- body: "none",
627
- idRole: "id"
628
- },
629
- {
630
- resource: "discount",
631
- verb: "list",
632
- docsPath: "discounts/list-all-discounts",
633
- body: "none",
634
- idRole: "store"
635
- },
636
- {
637
- resource: "discount",
638
- verb: "create",
639
- docsPath: "discounts/create-discount",
640
- body: "required",
641
- idRole: "none"
642
- },
643
- {
644
- resource: "discount",
645
- verb: "delete",
646
- docsPath: "discounts/delete-discount",
647
- body: "none",
648
- destructive: true,
649
- idRole: "id"
650
- },
651
- // discount-redemptions (read-only)
652
- {
653
- resource: "discount-redemption",
654
- verb: "get",
655
- docsPath: "discount-redemptions/retrieve-discount-redemption",
656
- body: "none",
657
- idRole: "id"
658
- },
659
- {
660
- resource: "discount-redemption",
661
- verb: "list",
662
- docsPath: "discount-redemptions/list-all-discount-redemptions",
663
- body: "none",
664
- idRole: "parent"
665
- },
666
- // license-keys
667
- {
668
- resource: "license-key",
669
- verb: "get",
670
- docsPath: "license-keys/retrieve-license-key",
671
- body: "none",
672
- idRole: "id"
673
- },
674
- {
675
- resource: "license-key",
676
- verb: "list",
677
- docsPath: "license-keys/list-all-license-keys",
678
- body: "none",
679
- idRole: "store"
680
- },
681
- {
682
- resource: "license-key",
683
- verb: "update",
684
- docsPath: "license-keys/update-license-key",
685
- body: "required",
686
- idRole: "id"
687
- },
688
- // license-key-instances (read-only)
689
- {
690
- resource: "license-key-instance",
691
- verb: "get",
692
- docsPath: "license-key-instances/retrieve-license-key-instance",
693
- body: "none",
694
- idRole: "id"
695
- },
696
- {
697
- resource: "license-key-instance",
698
- verb: "list",
699
- docsPath: "license-key-instances/list-all-license-key-instances",
700
- body: "none",
701
- idRole: "parent"
702
- },
703
- // checkouts
704
- {
705
- resource: "checkout",
706
- verb: "get",
707
- docsPath: "checkouts/retrieve-checkout",
708
- body: "none",
709
- idRole: "id"
181
+ destructive: true
710
182
  },
711
- {
712
- resource: "checkout",
713
- verb: "list",
714
- docsPath: "checkouts/list-all-checkouts",
715
- body: "none",
716
- idRole: "store"
717
- },
718
- {
719
- resource: "checkout",
720
- verb: "create",
721
- docsPath: "checkouts/create-checkout",
722
- body: "required",
723
- idRole: "none"
724
- },
725
- // webhooks
726
- {
727
- resource: "webhook",
728
- verb: "get",
729
- docsPath: "webhooks/retrieve-webhook",
730
- body: "none",
731
- idRole: "id"
732
- },
733
- {
734
- resource: "webhook",
735
- verb: "list",
736
- docsPath: "webhooks/list-all-webhooks",
737
- body: "none",
738
- idRole: "store"
739
- },
740
- {
741
- resource: "webhook",
742
- verb: "create",
743
- docsPath: "webhooks/create-webhook",
744
- body: "required",
745
- idRole: "none"
746
- },
747
- {
748
- resource: "webhook",
749
- verb: "update",
750
- docsPath: "webhooks/update-webhook",
751
- body: "required",
752
- idRole: "id"
753
- },
754
- {
755
- resource: "webhook",
756
- verb: "delete",
757
- docsPath: "webhooks/delete-webhook",
758
- body: "none",
759
- destructive: true,
760
- idRole: "id"
761
- },
762
- // affiliates (read-only)
763
- {
764
- resource: "affiliate",
765
- verb: "get",
766
- docsPath: "affiliates/retrieve-affiliate",
767
- body: "none",
768
- idRole: "id"
769
- },
770
- {
771
- resource: "affiliate",
772
- verb: "list",
773
- docsPath: "affiliates/list-all-affiliates",
774
- body: "none",
775
- idRole: "store"
183
+ "generate-invoice": {
184
+ method: "POST",
185
+ path: "/{id}/generate-invoice",
186
+ docs: "generate-{r}-invoice",
187
+ body: "optional"
188
+ },
189
+ "current-usage": {
190
+ method: "GET",
191
+ path: "/{id}/current-usage",
192
+ docs: "retrieve-{r}-current-usage",
193
+ body: "none"
776
194
  }
195
+ };
196
+ var RESOURCES = [
197
+ ["user", ["get"]],
198
+ ["store", ["get", "list"]],
199
+ ["product", ["get", "list"], "store"],
200
+ ["variant", ["get", "list"], "product"],
201
+ ["price", ["get", "list"], "variant"],
202
+ ["file", ["get", "list"], "variant"],
203
+ ["customer", ["get", "list", "create", "update"], "store"],
204
+ ["order", ["get", "list", "refund", "generate-invoice"], "store"],
205
+ ["order-item", ["get", "list"], "order"],
206
+ ["subscription", ["get", "list", "update", "cancel"], "store"],
207
+ ["subscription-item", ["get", "list", "update", "current-usage"], "subscription"],
208
+ ["subscription-invoice", ["get", "list", "refund", "generate-invoice"], "subscription"],
209
+ ["usage-record", ["get", "list", "create"], "subscription-item"],
210
+ ["discount", ["get", "list", "create", "delete"], "store"],
211
+ ["discount-redemption", ["get", "list"], "discount"],
212
+ ["license-key", ["get", "list", "update"], "store"],
213
+ ["license-key-instance", ["get", "list"], "license-key"],
214
+ ["checkout", ["get", "list", "create"], "store"],
215
+ ["webhook", ["get", "list", "create", "update", "delete"], "store"],
216
+ ["affiliate", ["get", "list"], "store"]
777
217
  ];
778
- var RESOURCE_ALIASES = {
779
- products: "product",
780
- stores: "store",
781
- customers: "customer",
782
- orders: "order",
783
- "order-items": "order-item",
784
- subscriptions: "subscription",
785
- "subscription-items": "subscription-item",
786
- "subscription-invoices": "subscription-invoice",
787
- "usage-records": "usage-record",
788
- discounts: "discount",
789
- "discount-redemptions": "discount-redemption",
790
- "license-keys": "license-key",
791
- "license-key-instances": "license-key-instance",
792
- checkouts: "checkout",
793
- webhooks: "webhook",
794
- affiliates: "affiliate",
795
- variants: "variant",
796
- prices: "price",
797
- files: "file",
798
- users: "user"
218
+ var DOCS_PATH_EXCEPTIONS = {
219
+ "subscription-invoice:generate-invoice": "subscription-invoices/generate-subscription-invoice"
220
+ };
221
+ var USER_ME_PATH = "/v1/users/me";
222
+ var listIdRole = (listScope) => {
223
+ if (!listScope) return "none";
224
+ return listScope === "store" ? "store" : "parent";
225
+ };
226
+ var toSpec = (resource, verb, listScope) => {
227
+ const rule = VERB_RULES[verb];
228
+ const docsPath = DOCS_PATH_EXCEPTIONS[`${resource}:${verb}`] ?? `${resource}s/${rule.docs.replaceAll("{r}", resource)}`;
229
+ let idRole = rule.path.includes("{id}") ? "id" : "none";
230
+ if (verb === "list") idRole = listIdRole(listScope);
231
+ if (resource === "user") idRole = "none";
232
+ return {
233
+ resource,
234
+ verb,
235
+ docsPath,
236
+ body: rule.body,
237
+ ...rule.destructive ? { destructive: true } : {},
238
+ idRole
239
+ };
799
240
  };
241
+ var resourceRegistry = RESOURCES.flatMap(
242
+ ([resource, verbs, listScope]) => verbs.map((verb) => toSpec(resource, verb, listScope))
243
+ );
800
244
  var normalizeResourceName = (resource) => {
801
245
  const normalized = resource.replace(/_/g, "-").toLowerCase();
802
- if (RESOURCE_ALIASES[normalized]) {
803
- return RESOURCE_ALIASES[normalized];
804
- }
805
246
  if (normalized.endsWith("s") && normalized !== "status") {
806
247
  return normalized.slice(0, -1);
807
248
  }
@@ -818,280 +259,11 @@ var listRegisteredVerbs = (resource) => {
818
259
  const key = normalizeResourceName(resource);
819
260
  return resourceRegistry.filter((entry) => entry.resource === key).map((entry) => entry.verb).sort();
820
261
  };
821
-
822
- // src/resources/stores.ts
823
- var getStore = async (http, storeId) => {
824
- return http.getResource(`/v1/stores/${storeId}`);
825
- };
826
- var listStores = async (http) => {
827
- return http.paginate("/v1/stores");
828
- };
829
-
830
- // src/resources/subscriptionInvoices.ts
831
- var getSubscriptionInvoice = async (http, subscriptionInvoiceId) => {
832
- return http.getResource(
833
- `/v1/subscription-invoices/${subscriptionInvoiceId}`
834
- );
835
- };
836
- var listSubscriptionInvoicesForSubscription = async (http, subscriptionId) => {
837
- return http.paginate("/v1/subscription-invoices", {
838
- "filter[subscription_id]": String(subscriptionId)
839
- });
840
- };
841
- var refundSubscriptionInvoice = async (http, subscriptionInvoiceId, body) => {
842
- return http.postResource(
843
- `/v1/subscription-invoices/${subscriptionInvoiceId}/refund`,
844
- body ?? {}
845
- );
846
- };
847
- var generateSubscriptionInvoice = async (http, subscriptionInvoiceId, body) => {
848
- return http.request({
849
- method: "POST",
850
- path: `/v1/subscription-invoices/${subscriptionInvoiceId}/generate-invoice`,
851
- body: body ?? {}
852
- });
853
- };
854
-
855
- // src/resources/subscriptionItems.ts
856
- var getSubscriptionItem = async (http, subscriptionItemId) => {
857
- return http.getResource(
858
- `/v1/subscription-items/${subscriptionItemId}`
859
- );
860
- };
861
- var listSubscriptionItemsForSubscription = async (http, subscriptionId) => {
862
- return http.paginate("/v1/subscription-items", {
863
- "filter[subscription_id]": String(subscriptionId)
864
- });
865
- };
866
- var buildSubscriptionItemUpdateBody = (subscriptionItemId, attributes) => {
867
- return {
868
- data: {
869
- type: "subscription-items",
870
- id: String(subscriptionItemId),
871
- attributes
872
- }
873
- };
874
- };
875
- var updateSubscriptionItem = async (http, subscriptionItemId, body) => {
876
- return http.patchResource(
877
- `/v1/subscription-items/${subscriptionItemId}`,
878
- body
879
- );
880
- };
881
- var getSubscriptionItemCurrentUsage = async (http, subscriptionItemId) => {
882
- return http.request({
883
- path: `/v1/subscription-items/${subscriptionItemId}/current-usage`
884
- });
885
- };
886
-
887
- // src/resources/subscriptions.ts
888
- var getSubscription = async (http, subscriptionId) => {
889
- return http.getResource(`/v1/subscriptions/${subscriptionId}`);
890
- };
891
- var listSubscriptionsForStore = async (http, storeId) => {
892
- return http.paginate("/v1/subscriptions", {
893
- "filter[store_id]": String(storeId)
894
- });
895
- };
896
- var updateSubscription = async (http, subscriptionId, body) => {
897
- return http.patchResource(`/v1/subscriptions/${subscriptionId}`, body);
898
- };
899
- var cancelSubscription = async (http, subscriptionId) => {
900
- const doc = await http.request({
901
- method: "DELETE",
902
- path: `/v1/subscriptions/${subscriptionId}`
903
- });
904
- return doc?.data;
905
- };
906
-
907
- // src/resources/usageRecords.ts
908
- var getUsageRecord = async (http, usageRecordId) => {
909
- return http.getResource(`/v1/usage-records/${usageRecordId}`);
910
- };
911
- var listUsageRecordsForSubscriptionItem = async (http, subscriptionItemId) => {
912
- return http.paginate("/v1/usage-records", {
913
- "filter[subscription_item_id]": String(subscriptionItemId)
914
- });
915
- };
916
- var createUsageRecord = async (http, body) => {
917
- return http.postResource("/v1/usage-records", body);
918
- };
919
-
920
- // src/resources/users.ts
921
- var getAuthenticatedUser = async (http) => {
922
- return http.request({ path: "/v1/users/me" });
923
- };
924
-
925
- // src/resources/variants.ts
926
- var getVariant = async (http, variantId) => {
927
- return http.getResource(`/v1/variants/${variantId}`);
928
- };
929
- var listVariantsForProduct = async (http, productId) => {
930
- return http.paginate("/v1/variants", {
931
- "filter[product_id]": String(productId)
932
- });
933
- };
934
-
935
- // src/resources/webhooks.ts
936
- var getWebhook = async (http, webhookId) => {
937
- return http.getResource(`/v1/webhooks/${webhookId}`);
938
- };
939
- var listWebhooksForStore = async (http, storeId) => {
940
- return http.paginate("/v1/webhooks", {
941
- "filter[store_id]": String(storeId)
942
- });
943
- };
944
- var createWebhook = async (http, body) => {
945
- return http.postResource("/v1/webhooks", body);
946
- };
947
- var updateWebhook = async (http, webhookId, body) => {
948
- return http.patchResource(`/v1/webhooks/${webhookId}`, body);
949
- };
950
- var deleteWebhook = async (http, webhookId) => {
951
- await http.deleteResource(`/v1/webhooks/${webhookId}`);
952
- };
953
-
954
- // src/resources/invokeOp.ts
955
- var invokeOp = async (http, resource, verb, args = {}) => {
956
- const spec = findResourceVerb(resource, verb);
957
- if (!spec) {
958
- throw new FreshSqueezyError({
959
- code: "UNKNOWN_OP",
960
- message: `Unknown or unsupported op: ${verb} ${resource}. Run \`fresh-squeezy ops --list\`.`
961
- });
962
- }
963
- const key = `${spec.resource}:${spec.verb}`;
964
- switch (key) {
965
- case "user:get": {
966
- const doc = await getAuthenticatedUser(http);
967
- return doc.data;
968
- }
969
- case "store:get":
970
- return getStore(http, requireId(args, "store"));
971
- case "store:list":
972
- return listStores(http);
973
- case "product:get":
974
- return getProduct(http, requireId(args, "product"));
975
- case "product:list":
976
- return listProducts(http, requireStore(args));
977
- case "variant:get":
978
- return getVariant(http, requireId(args, "variant"));
979
- case "variant:list":
980
- return listVariantsForProduct(http, requireParent(args, "product"));
981
- case "price:get":
982
- return getPrice(http, requireId(args, "price"));
983
- case "price:list":
984
- return listPricesForVariant(http, requireParent(args, "variant"));
985
- case "file:get":
986
- return getFile(http, requireId(args, "file"));
987
- case "file:list":
988
- return listFilesForVariant(http, requireParent(args, "variant"));
989
- case "customer:get":
990
- return getCustomer(http, requireId(args, "customer"));
991
- case "customer:list":
992
- return listCustomersForStore(http, requireStore(args));
993
- case "customer:create":
994
- return createCustomer(http, requireBody(args));
995
- case "customer:update":
996
- return updateCustomer(http, requireId(args, "customer"), requireBody(args));
997
- case "order:get":
998
- return getOrder(http, requireId(args, "order"));
999
- case "order:list":
1000
- return listOrdersForStore(http, requireStore(args));
1001
- case "order:refund":
1002
- return refundOrder(http, requireId(args, "order"), args.body);
1003
- case "order:generate-invoice":
1004
- return generateOrderInvoice(http, requireId(args, "order"), args.body);
1005
- case "order-item:get":
1006
- return getOrderItem(http, requireId(args, "order-item"));
1007
- case "order-item:list":
1008
- return listOrderItemsForOrder(http, requireParent(args, "order"));
1009
- case "subscription:get":
1010
- return getSubscription(http, requireId(args, "subscription"));
1011
- case "subscription:list":
1012
- return listSubscriptionsForStore(http, requireStore(args));
1013
- case "subscription:update":
1014
- return updateSubscription(http, requireId(args, "subscription"), requireBody(args));
1015
- case "subscription:cancel":
1016
- return cancelSubscription(http, requireId(args, "subscription"));
1017
- case "subscription-item:get":
1018
- return getSubscriptionItem(http, requireId(args, "subscription-item"));
1019
- case "subscription-item:list":
1020
- return listSubscriptionItemsForSubscription(http, requireParent(args, "subscription"));
1021
- case "subscription-item:update":
1022
- return updateSubscriptionItem(http, requireId(args, "subscription-item"), requireBody(args));
1023
- case "subscription-item:current-usage":
1024
- return getSubscriptionItemCurrentUsage(http, requireId(args, "subscription-item"));
1025
- case "subscription-invoice:get":
1026
- return getSubscriptionInvoice(http, requireId(args, "subscription-invoice"));
1027
- case "subscription-invoice:list":
1028
- return listSubscriptionInvoicesForSubscription(http, requireParent(args, "subscription"));
1029
- case "subscription-invoice:refund":
1030
- return refundSubscriptionInvoice(http, requireId(args, "subscription-invoice"), args.body);
1031
- case "subscription-invoice:generate-invoice":
1032
- return generateSubscriptionInvoice(http, requireId(args, "subscription-invoice"), args.body);
1033
- case "usage-record:get":
1034
- return getUsageRecord(http, requireId(args, "usage-record"));
1035
- case "usage-record:list":
1036
- return listUsageRecordsForSubscriptionItem(http, requireParent(args, "subscription-item"));
1037
- case "usage-record:create":
1038
- return createUsageRecord(http, requireBody(args));
1039
- case "discount:get":
1040
- return getDiscount(http, requireId(args, "discount"));
1041
- case "discount:list":
1042
- return listDiscountsForStore(http, requireStore(args));
1043
- case "discount:create":
1044
- return createDiscount(http, requireBody(args));
1045
- case "discount:delete":
1046
- await deleteDiscount(http, requireId(args, "discount"));
1047
- return void 0;
1048
- case "discount-redemption:get":
1049
- return getDiscountRedemption(http, requireId(args, "discount-redemption"));
1050
- case "discount-redemption:list":
1051
- return listDiscountRedemptionsForDiscount(http, requireParent(args, "discount"));
1052
- case "license-key:get":
1053
- return getLicenseKey(http, requireId(args, "license-key"));
1054
- case "license-key:list":
1055
- return listLicenseKeysForStore(http, requireStore(args));
1056
- case "license-key:update":
1057
- return updateLicenseKey(http, requireId(args, "license-key"), requireBody(args));
1058
- case "license-key-instance:get":
1059
- return getLicenseKeyInstance(http, requireId(args, "license-key-instance"));
1060
- case "license-key-instance:list":
1061
- return listLicenseKeyInstancesForLicenseKey(http, requireParent(args, "license-key"));
1062
- case "checkout:get":
1063
- return getCheckout(http, requireId(args, "checkout"));
1064
- case "checkout:list":
1065
- return listCheckoutsForStore(http, requireStore(args));
1066
- case "checkout:create":
1067
- return createCheckout(http, requireBody(args));
1068
- case "webhook:get":
1069
- return getWebhook(http, requireId(args, "webhook"));
1070
- case "webhook:list":
1071
- return listWebhooksForStore(http, requireStore(args));
1072
- case "webhook:create":
1073
- return createWebhook(http, requireBody(args));
1074
- case "webhook:update":
1075
- return updateWebhook(http, requireId(args, "webhook"), requireBody(args));
1076
- case "webhook:delete":
1077
- await deleteWebhook(http, requireId(args, "webhook"));
1078
- return void 0;
1079
- case "affiliate:get":
1080
- return getAffiliate(http, requireId(args, "affiliate"));
1081
- case "affiliate:list":
1082
- return listAffiliatesForStore(http, requireStore(args));
1083
- default:
1084
- throw new FreshSqueezyError({
1085
- code: "UNKNOWN_OP",
1086
- message: `Op registered but not wired: ${key}`
1087
- });
1088
- }
1089
- };
1090
- var requireId = (args, label) => {
262
+ var requireId = (args, spec) => {
1091
263
  if (args.id === void 0 || args.id === "") {
1092
264
  throw new FreshSqueezyError({
1093
265
  code: "MISSING_ARG",
1094
- message: `--id is required for this ${label} operation.`
266
+ message: `--id is required for this ${spec.resource} operation.`
1095
267
  });
1096
268
  }
1097
269
  return args.id;
@@ -1105,11 +277,11 @@ var requireStore = (args) => {
1105
277
  }
1106
278
  return args.storeId;
1107
279
  };
1108
- var requireParent = (args, label) => {
280
+ var requireParent = (args, parent) => {
1109
281
  if (args.parentId === void 0 || args.parentId === "") {
1110
282
  throw new FreshSqueezyError({
1111
283
  code: "MISSING_ARG",
1112
- message: `--parent-id (${label} id) is required for this list operation.`
284
+ message: `--parent-id (${parent} id) is required for this list operation.`
1113
285
  });
1114
286
  }
1115
287
  return args.parentId;
@@ -1123,8 +295,44 @@ var requireBody = (args) => {
1123
295
  }
1124
296
  return args.body;
1125
297
  };
298
+ var listFilter = (spec, args) => {
299
+ const listScope = RESOURCES.find(([resource]) => resource === spec.resource)?.[2];
300
+ if (!listScope) return void 0;
301
+ const scopeId = listScope === "store" ? requireStore(args) : requireParent(args, listScope);
302
+ return { [`filter[${listScope.replace(/-/g, "_")}_id]`]: String(scopeId) };
303
+ };
304
+ var requestBody = (rule, args) => {
305
+ if (rule.body === "required") return requireBody(args);
306
+ if (rule.body === "optional") return args.body ?? {};
307
+ return void 0;
308
+ };
309
+ var invokeOp = async (http, resource, verb, args = {}) => {
310
+ const spec = findResourceVerb(resource, verb);
311
+ if (!spec) {
312
+ throw new FreshSqueezyError({
313
+ code: "UNKNOWN_OP",
314
+ message: `Unknown or unsupported op: ${verb} ${resource}. Run \`fresh-squeezy ops --list\`.`
315
+ });
316
+ }
317
+ if (spec.resource === "user") {
318
+ const doc2 = await http.request({ path: USER_ME_PATH });
319
+ return doc2.data;
320
+ }
321
+ const collectionPath = `/v1/${spec.resource}s`;
322
+ if (spec.verb === "list") {
323
+ return http.paginate(collectionPath, listFilter(spec, args));
324
+ }
325
+ const rule = VERB_RULES[spec.verb];
326
+ const path = collectionPath + rule.path.replace("{id}", () => String(requireId(args, spec)));
327
+ const doc = await http.request({
328
+ method: rule.method,
329
+ path,
330
+ body: requestBody(rule, args)
331
+ });
332
+ return doc?.data ?? doc;
333
+ };
1126
334
 
1127
- // src/validate/rules.ts
335
+ // src/validate/issues.ts
1128
336
  var ISSUE_CODES = {
1129
337
  AUTH_FAILED: "AUTH_FAILED",
1130
338
  MODE_MISMATCH: "MODE_MISMATCH",
@@ -1248,11 +456,19 @@ var checkStoreOwnership = (check) => {
1248
456
  };
1249
457
 
1250
458
  // src/validate/connection.ts
459
+ var resolveActualMode = (testMode) => {
460
+ if (testMode === true) return "test";
461
+ if (testMode === false) return "live";
462
+ return void 0;
463
+ };
464
+ var fetchUserDocument = (http) => {
465
+ return http.request({ path: "/v1/users/me" });
466
+ };
1251
467
  var validateConnection = async (http, mode) => {
1252
468
  const fetched = await probeCollection(
1253
469
  async () => {
1254
- const userDoc2 = await getAuthenticatedUser(http);
1255
- const stores2 = await listStores(http);
470
+ const userDoc2 = await fetchUserDocument(http);
471
+ const stores2 = await http.paginate("/v1/stores");
1256
472
  return { userDoc: userDoc2, stores: stores2 };
1257
473
  },
1258
474
  {
@@ -1302,7 +518,7 @@ var validateConnection = async (http, mode) => {
1302
518
  return buildResult("connection", mode, issues, summary);
1303
519
  };
1304
520
  var fetchActualMode = async (http) => {
1305
- const doc = await getAuthenticatedUser(http);
521
+ const doc = await fetchUserDocument(http);
1306
522
  return resolveActualMode(doc.meta?.test_mode);
1307
523
  };
1308
524
 
@@ -1312,12 +528,15 @@ var validateDiscount = async (http, mode, options) => {
1312
528
  label: `discount ${options.discountId}`,
1313
529
  id: String(options.discountId)
1314
530
  };
1315
- const fetched = await probeFetch(() => getDiscount(http, options.discountId), {
1316
- notFoundCode: ISSUE_CODES.DISCOUNT_NOT_FOUND,
1317
- notFoundMessage: `Discount ${options.discountId} not found.`,
1318
- notFoundFix: "Verify the discount ID in the Lemon Squeezy dashboard.",
1319
- notFoundContext: { discountId: String(options.discountId) }
1320
- });
531
+ const fetched = await probeFetch(
532
+ () => http.getResource(`/v1/discounts/${options.discountId}`),
533
+ {
534
+ notFoundCode: ISSUE_CODES.DISCOUNT_NOT_FOUND,
535
+ notFoundMessage: `Discount ${options.discountId} not found.`,
536
+ notFoundFix: "Verify the discount ID in the Lemon Squeezy dashboard.",
537
+ notFoundContext: { discountId: String(options.discountId) }
538
+ }
539
+ );
1321
540
  if (!fetched.ok) {
1322
541
  return buildResult("discount", mode, [fetched.issue], void 0, target);
1323
542
  }
@@ -1424,12 +643,15 @@ var validateLicenseKey = async (http, mode, options) => {
1424
643
  label: `license key ${options.licenseKeyId}`,
1425
644
  id: String(options.licenseKeyId)
1426
645
  };
1427
- const fetched = await probeFetch(() => getLicenseKey(http, options.licenseKeyId), {
1428
- notFoundCode: ISSUE_CODES.LICENSE_KEY_NOT_FOUND,
1429
- notFoundMessage: `License key ${options.licenseKeyId} not found.`,
1430
- notFoundFix: "Verify the license key ID in the Lemon Squeezy dashboard.",
1431
- notFoundContext: { licenseKeyId: String(options.licenseKeyId) }
1432
- });
646
+ const fetched = await probeFetch(
647
+ () => http.getResource(`/v1/license-keys/${options.licenseKeyId}`),
648
+ {
649
+ notFoundCode: ISSUE_CODES.LICENSE_KEY_NOT_FOUND,
650
+ notFoundMessage: `License key ${options.licenseKeyId} not found.`,
651
+ notFoundFix: "Verify the license key ID in the Lemon Squeezy dashboard.",
652
+ notFoundContext: { licenseKeyId: String(options.licenseKeyId) }
653
+ }
654
+ );
1433
655
  if (!fetched.ok) {
1434
656
  return buildResult(
1435
657
  "licenseKey",
@@ -1511,19 +733,24 @@ var validateProduct = async (http, mode, options) => {
1511
733
  label: `product ${options.productId}`,
1512
734
  id: String(options.productId)
1513
735
  };
1514
- const fetched = await probeFetch(() => getProduct(http, options.productId), {
1515
- notFoundCode: ISSUE_CODES.PRODUCT_NOT_FOUND,
1516
- notFoundMessage: `Product ${options.productId} not found.`,
1517
- notFoundFix: "Verify the product ID in the Lemon Squeezy dashboard.",
1518
- notFoundContext: { productId: String(options.productId) }
1519
- });
736
+ const fetched = await probeFetch(
737
+ () => http.getResource(`/v1/products/${options.productId}`),
738
+ {
739
+ notFoundCode: ISSUE_CODES.PRODUCT_NOT_FOUND,
740
+ notFoundMessage: `Product ${options.productId} not found.`,
741
+ notFoundFix: "Verify the product ID in the Lemon Squeezy dashboard.",
742
+ notFoundContext: { productId: String(options.productId) }
743
+ }
744
+ );
1520
745
  if (!fetched.ok) {
1521
746
  return buildResult("product", mode, [fetched.issue], void 0, target);
1522
747
  }
1523
748
  const attrs = fetched.resource.attributes;
1524
749
  issues.push(...checkProduct(attrs, { expectedStoreId: options.expectedStoreId }));
1525
750
  const variantsProbed = await probeCollection(
1526
- () => listVariantsForProduct(http, options.productId)
751
+ () => http.paginate("/v1/variants", {
752
+ "filter[product_id]": String(options.productId)
753
+ })
1527
754
  );
1528
755
  if (!variantsProbed.ok) {
1529
756
  issues.push({ ...variantsProbed.issue, severity: "warning" });
@@ -1592,12 +819,15 @@ var checkProduct = (attrs, options = {}) => {
1592
819
  // src/validate/store.ts
1593
820
  var validateStore = async (http, mode, storeId) => {
1594
821
  const target = { label: `store ${storeId}`, id: String(storeId) };
1595
- const fetched = await probeFetch(() => getStore(http, storeId), {
1596
- notFoundCode: ISSUE_CODES.STORE_NOT_FOUND,
1597
- notFoundMessage: `Store ${storeId} not found with the current API key.`,
1598
- notFoundFix: "Check the store ID and confirm the API key belongs to the account that owns it.",
1599
- notFoundContext: { storeId: String(storeId) }
1600
- });
822
+ const fetched = await probeFetch(
823
+ () => http.getResource(`/v1/stores/${storeId}`),
824
+ {
825
+ notFoundCode: ISSUE_CODES.STORE_NOT_FOUND,
826
+ notFoundMessage: `Store ${storeId} not found with the current API key.`,
827
+ notFoundFix: "Check the store ID and confirm the API key belongs to the account that owns it.",
828
+ notFoundContext: { storeId: String(storeId) }
829
+ }
830
+ );
1601
831
  if (!fetched.ok) {
1602
832
  return buildResult("store", mode, [fetched.issue], void 0, target);
1603
833
  }
@@ -1615,7 +845,7 @@ var validateSubscriptionPlan = async (http, mode, options) => {
1615
845
  id: String(options.variantId)
1616
846
  };
1617
847
  const fetched = await probeFetch(
1618
- () => getVariant(http, options.variantId),
848
+ () => http.getResource(`/v1/variants/${options.variantId}`),
1619
849
  {
1620
850
  notFoundCode: ISSUE_CODES.PLAN_VARIANT_NOT_FOUND,
1621
851
  notFoundMessage: `Variant ${options.variantId} not found.`,
@@ -1635,10 +865,13 @@ var validateSubscriptionPlan = async (http, mode, options) => {
1635
865
  const variant = fetched.resource;
1636
866
  const attrs = variant.attributes;
1637
867
  const issues = checkSubscriptionPlan(attrs, { variantId: options.variantId });
1638
- const productProbed = await probeFetch(() => getProduct(http, attrs.product_id), {
1639
- notFoundCode: ISSUE_CODES.PRODUCT_NOT_FOUND,
1640
- notFoundMessage: `Product ${attrs.product_id} not found.`
1641
- });
868
+ const productProbed = await probeFetch(
869
+ () => http.getResource(`/v1/products/${attrs.product_id}`),
870
+ {
871
+ notFoundCode: ISSUE_CODES.PRODUCT_NOT_FOUND,
872
+ notFoundMessage: `Product ${attrs.product_id} not found.`
873
+ }
874
+ );
1642
875
  if (productProbed.ok) {
1643
876
  const mismatch = checkStoreOwnership({
1644
877
  expectedStoreId: options.storeId,
@@ -1777,7 +1010,7 @@ var ACKNOWLEDGED_CHANGELOG_ENTRIES = [
1777
1010
  {
1778
1011
  date: "2025-06-11",
1779
1012
  summary: "Added payment_processor attribute to Subscription objects.",
1780
- handledBy: "Surfaced as SubscriptionAttributes.payment_processor in src/resources/subscriptions.ts."
1013
+ handledBy: "Surfaced as SubscriptionAttributes.payment_processor in src/resources/attributes.ts."
1781
1014
  },
1782
1015
  {
1783
1016
  date: "2025-01-21",
@@ -1787,12 +1020,12 @@ var ACKNOWLEDGED_CHANGELOG_ENTRIES = [
1787
1020
  {
1788
1021
  date: "2024-12-06",
1789
1022
  summary: "Added quantity parameter to OrderItem objects.",
1790
- handledBy: "OrderItemAttributes.quantity (src/resources/orderItems.ts)."
1023
+ handledBy: "OrderItemAttributes.quantity (src/resources/attributes.ts)."
1791
1024
  },
1792
1025
  {
1793
1026
  date: "2024-09-10",
1794
1027
  summary: "Added fraudulent Order status.",
1795
- handledBy: "OrderAttributes.status union includes 'fraudulent' (src/resources/orders.ts)."
1028
+ handledBy: "OrderAttributes.status union includes 'fraudulent' (src/resources/attributes.ts)."
1796
1029
  },
1797
1030
  {
1798
1031
  date: "2024-09-04",
@@ -1807,7 +1040,7 @@ var ACKNOWLEDGED_CHANGELOG_ENTRIES = [
1807
1040
  {
1808
1041
  date: "2024-06-09",
1809
1042
  summary: "Added links property to Variant objects.",
1810
- handledBy: "VariantAttributes.links (src/resources/variants.ts)."
1043
+ handledBy: "VariantAttributes.links (src/resources/attributes.ts)."
1811
1044
  },
1812
1045
  {
1813
1046
  date: "2024-05-20",
@@ -1827,7 +1060,7 @@ var ACKNOWLEDGED_CHANGELOG_ENTRIES = [
1827
1060
  {
1828
1061
  date: "2024-02-20",
1829
1062
  summary: "Added urls.update_customer_portal to Subscription objects.",
1830
- handledBy: "SubscriptionUrls.update_customer_portal (src/resources/subscriptions.ts)."
1063
+ handledBy: "SubscriptionUrls.update_customer_portal (src/resources/attributes.ts)."
1831
1064
  },
1832
1065
  {
1833
1066
  date: "2024-02-12",
@@ -1877,9 +1110,19 @@ var ACKNOWLEDGED_CHANGELOG_ENTRIES = [
1877
1110
  ];
1878
1111
 
1879
1112
  // src/validate/webhook.ts
1113
+ var sameWebhookUrl = (a, b) => {
1114
+ return normalizeWebhookUrl(a) === normalizeWebhookUrl(b);
1115
+ };
1116
+ var normalizeWebhookUrl = (raw) => {
1117
+ return raw.replace(/\/+$/, "").toLowerCase();
1118
+ };
1880
1119
  var validateWebhook = async (http, mode, options) => {
1881
1120
  const target = { label: options.url, url: options.url };
1882
- const fetched = await probeCollection(() => listWebhooksForStore(http, options.storeId));
1121
+ const fetched = await probeCollection(
1122
+ () => http.paginate("/v1/webhooks", {
1123
+ "filter[store_id]": String(options.storeId)
1124
+ })
1125
+ );
1883
1126
  if (!fetched.ok) {
1884
1127
  return buildResult("webhook", mode, [fetched.issue], void 0, target);
1885
1128
  }
@@ -2064,46 +1307,6 @@ var HttpClient = class {
2064
1307
  const doc = await this.request({ path });
2065
1308
  return doc.data;
2066
1309
  }
2067
- /**
2068
- * POST a JSON:API document and return the created `data` resource.
2069
- *
2070
- * @param path - API path starting with `/v1/...`.
2071
- * @param body - JSON:API create document.
2072
- * @returns The created resource.
2073
- */
2074
- async postResource(path, body) {
2075
- const doc = await this.request({ method: "POST", path, body });
2076
- return doc.data;
2077
- }
2078
- /**
2079
- * PATCH a JSON:API document and return the updated `data` resource.
2080
- *
2081
- * @param path - API path starting with `/v1/...`.
2082
- * @param body - JSON:API update document.
2083
- * @returns The updated resource.
2084
- */
2085
- async patchResource(path, body) {
2086
- const doc = await this.request({ method: "PATCH", path, body });
2087
- return doc.data;
2088
- }
2089
- /**
2090
- * DELETE a resource. Lemon Squeezy often returns an empty body on success.
2091
- *
2092
- * @param path - API path starting with `/v1/...`.
2093
- * @returns Nothing — single void return, not a multi-field bag.
2094
- */
2095
- async deleteResource(path) {
2096
- await this.request({ method: "DELETE", path });
2097
- }
2098
- /**
2099
- * Fetch a single page of a JSON:API collection. Most callers want
2100
- * `paginate()` instead — this method is kept for one-shot lookups where
2101
- * the caller knows the result fits in a single page.
2102
- */
2103
- async getCollection(path, query) {
2104
- const doc = await this.request({ path, query });
2105
- return doc.data;
2106
- }
2107
1310
  /**
2108
1311
  * Walk a JSON:API collection across every page and concatenate the
2109
1312
  * results. Lemon Squeezy returns 25 items per page by default; without
@@ -2298,81 +1501,24 @@ var createFreshSqueezy = (config = {}) => {
2298
1501
  SUPPORTED_RESOURCES,
2299
1502
  buildResult,
2300
1503
  buildSubscriptionItemUpdateBody,
2301
- cancelSubscription,
2302
1504
  checkDiscount,
2303
1505
  checkLicenseKey,
2304
1506
  checkProduct,
2305
1507
  checkSubscriptionPlan,
2306
- createCheckout,
2307
- createCustomer,
2308
- createDiscount,
2309
1508
  createFreshSqueezy,
2310
- createUsageRecord,
2311
- createWebhook,
2312
- deleteDiscount,
2313
- deleteWebhook,
2314
1509
  doctor,
2315
1510
  fetchActualMode,
2316
1511
  findResourceVerb,
2317
- generateOrderInvoice,
2318
- generateSubscriptionInvoice,
2319
- getAffiliate,
2320
- getAuthenticatedUser,
2321
- getCheckout,
2322
- getCustomer,
2323
- getDiscount,
2324
- getDiscountRedemption,
2325
- getFile,
2326
- getLicenseKey,
2327
- getLicenseKeyInstance,
2328
- getOrder,
2329
- getOrderItem,
2330
- getPrice,
2331
- getProduct,
2332
- getStore,
2333
- getSubscription,
2334
- getSubscriptionInvoice,
2335
- getSubscriptionItem,
2336
- getSubscriptionItemCurrentUsage,
2337
- getUsageRecord,
2338
- getVariant,
2339
- getWebhook,
2340
1512
  invokeOp,
2341
1513
  isOk,
2342
1514
  issue,
2343
- listAffiliatesForStore,
2344
- listCheckoutsForStore,
2345
- listCustomersForStore,
2346
- listDiscountRedemptionsForDiscount,
2347
- listDiscountsForStore,
2348
- listFilesForVariant,
2349
- listLicenseKeyInstancesForLicenseKey,
2350
- listLicenseKeysForStore,
2351
- listOrderItemsForOrder,
2352
- listOrdersForStore,
2353
- listPricesForVariant,
2354
- listProducts,
2355
1515
  listRegisteredResources,
2356
1516
  listRegisteredVerbs,
2357
- listStores,
2358
- listSubscriptionInvoicesForSubscription,
2359
- listSubscriptionItemsForSubscription,
2360
- listSubscriptionsForStore,
2361
- listUsageRecordsForSubscriptionItem,
2362
- listVariantsForProduct,
2363
- listWebhooksForStore,
2364
1517
  normalizeResourceName,
2365
- refundOrder,
2366
- refundSubscriptionInvoice,
2367
1518
  resolveActualMode,
2368
1519
  resolveConfig,
2369
1520
  resourceRegistry,
2370
1521
  sameWebhookUrl,
2371
- updateCustomer,
2372
- updateLicenseKey,
2373
- updateSubscription,
2374
- updateSubscriptionItem,
2375
- updateWebhook,
2376
1522
  validateConnection,
2377
1523
  validateDiscount,
2378
1524
  validateLicenseKey,