fresh-squeezy 0.1.2 → 0.1.4
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/cli.js +435 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +407 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +108 -1
- package/dist/index.d.ts +108 -1
- package/dist/index.js +406 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -164,6 +164,25 @@ var ISSUE_CODES = {
|
|
|
164
164
|
WEBHOOK_NOT_FOUND: "WEBHOOK_NOT_FOUND",
|
|
165
165
|
WEBHOOK_EVENTS_MISSING: "WEBHOOK_EVENTS_MISSING",
|
|
166
166
|
WEBHOOK_OPTIONAL_EVENTS: "WEBHOOK_OPTIONAL_EVENTS",
|
|
167
|
+
DISCOUNT_NOT_FOUND: "DISCOUNT_NOT_FOUND",
|
|
168
|
+
DISCOUNT_DRAFT: "DISCOUNT_DRAFT",
|
|
169
|
+
DISCOUNT_EXPIRED: "DISCOUNT_EXPIRED",
|
|
170
|
+
DISCOUNT_NOT_STARTED: "DISCOUNT_NOT_STARTED",
|
|
171
|
+
DISCOUNT_REDEMPTIONS_EXHAUSTED: "DISCOUNT_REDEMPTIONS_EXHAUSTED",
|
|
172
|
+
DISCOUNT_INVALID_AMOUNT: "DISCOUNT_INVALID_AMOUNT",
|
|
173
|
+
DISCOUNT_STORE_MISMATCH: "DISCOUNT_STORE_MISMATCH",
|
|
174
|
+
LICENSE_KEY_NOT_FOUND: "LICENSE_KEY_NOT_FOUND",
|
|
175
|
+
LICENSE_KEY_DISABLED: "LICENSE_KEY_DISABLED",
|
|
176
|
+
LICENSE_KEY_EXPIRED: "LICENSE_KEY_EXPIRED",
|
|
177
|
+
LICENSE_KEY_AT_ACTIVATION_LIMIT: "LICENSE_KEY_AT_ACTIVATION_LIMIT",
|
|
178
|
+
LICENSE_KEY_STORE_MISMATCH: "LICENSE_KEY_STORE_MISMATCH",
|
|
179
|
+
PLAN_VARIANT_NOT_FOUND: "PLAN_VARIANT_NOT_FOUND",
|
|
180
|
+
PLAN_NOT_SUBSCRIPTION: "PLAN_NOT_SUBSCRIPTION",
|
|
181
|
+
PLAN_INVALID_INTERVAL: "PLAN_INVALID_INTERVAL",
|
|
182
|
+
PLAN_FREE_PRICE: "PLAN_FREE_PRICE",
|
|
183
|
+
PLAN_TRIAL_INCONSISTENT: "PLAN_TRIAL_INCONSISTENT",
|
|
184
|
+
PLAN_DRAFT: "PLAN_DRAFT",
|
|
185
|
+
PLAN_STORE_MISMATCH: "PLAN_STORE_MISMATCH",
|
|
167
186
|
NETWORK_ERROR: "NETWORK_ERROR",
|
|
168
187
|
UNKNOWN: "UNKNOWN"
|
|
169
188
|
};
|
|
@@ -300,6 +319,9 @@ async function listProducts(http, storeId) {
|
|
|
300
319
|
}
|
|
301
320
|
|
|
302
321
|
// src/resources/variants.ts
|
|
322
|
+
async function getVariant(http, variantId) {
|
|
323
|
+
return http.getResource(`/v1/variants/${variantId}`);
|
|
324
|
+
}
|
|
303
325
|
async function listVariantsForProduct(http, productId) {
|
|
304
326
|
return http.getCollection("/v1/variants", {
|
|
305
327
|
"filter[product_id]": String(productId)
|
|
@@ -521,6 +543,358 @@ function normalizeUrl(raw) {
|
|
|
521
543
|
return raw.replace(/\/+$/, "").toLowerCase();
|
|
522
544
|
}
|
|
523
545
|
|
|
546
|
+
// src/resources/discounts.ts
|
|
547
|
+
async function getDiscount(http, discountId) {
|
|
548
|
+
return http.getResource(`/v1/discounts/${discountId}`);
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
// src/validate/discount.ts
|
|
552
|
+
async function validateDiscount(http, mode, options) {
|
|
553
|
+
const issues = [];
|
|
554
|
+
let discount;
|
|
555
|
+
try {
|
|
556
|
+
discount = await getDiscount(http, options.discountId);
|
|
557
|
+
} catch (err) {
|
|
558
|
+
if (err instanceof FreshSqueezyError && err.status === 404) {
|
|
559
|
+
issues.push(
|
|
560
|
+
issue(ISSUE_CODES.DISCOUNT_NOT_FOUND, "error", `Discount ${options.discountId} not found.`, {
|
|
561
|
+
suggestedFix: "Verify the discount ID in the Lemon Squeezy dashboard.",
|
|
562
|
+
context: { discountId: String(options.discountId) }
|
|
563
|
+
})
|
|
564
|
+
);
|
|
565
|
+
return buildResult("discount", mode, issues);
|
|
566
|
+
}
|
|
567
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
568
|
+
issues.push(issue(ISSUE_CODES.UNKNOWN, "error", message));
|
|
569
|
+
return buildResult("discount", mode, issues);
|
|
570
|
+
}
|
|
571
|
+
const attrs = discount.attributes;
|
|
572
|
+
const expectedStore = String(options.storeId);
|
|
573
|
+
const actualStore = String(attrs.store_id);
|
|
574
|
+
if (expectedStore !== actualStore) {
|
|
575
|
+
issues.push(
|
|
576
|
+
issue(
|
|
577
|
+
ISSUE_CODES.DISCOUNT_STORE_MISMATCH,
|
|
578
|
+
"error",
|
|
579
|
+
`Discount belongs to store ${actualStore}, expected ${expectedStore}.`,
|
|
580
|
+
{
|
|
581
|
+
suggestedFix: "Use the correct store ID or discount ID \u2014 discounts should not cross stores.",
|
|
582
|
+
context: { expectedStoreId: expectedStore, actualStoreId: actualStore }
|
|
583
|
+
}
|
|
584
|
+
)
|
|
585
|
+
);
|
|
586
|
+
}
|
|
587
|
+
if (attrs.status === "draft") {
|
|
588
|
+
issues.push(
|
|
589
|
+
issue(
|
|
590
|
+
ISSUE_CODES.DISCOUNT_DRAFT,
|
|
591
|
+
"warning",
|
|
592
|
+
`Discount "${attrs.name}" is in draft status \u2014 customers cannot redeem it.`,
|
|
593
|
+
{
|
|
594
|
+
suggestedFix: "Publish the discount in the Lemon Squeezy dashboard before sharing the code.",
|
|
595
|
+
context: { name: attrs.name, code: attrs.code }
|
|
596
|
+
}
|
|
597
|
+
)
|
|
598
|
+
);
|
|
599
|
+
}
|
|
600
|
+
const now = /* @__PURE__ */ new Date();
|
|
601
|
+
if (attrs.expires_at && new Date(attrs.expires_at) < now) {
|
|
602
|
+
issues.push(
|
|
603
|
+
issue(
|
|
604
|
+
ISSUE_CODES.DISCOUNT_EXPIRED,
|
|
605
|
+
"error",
|
|
606
|
+
`Discount "${attrs.name}" expired at ${attrs.expires_at}.`,
|
|
607
|
+
{
|
|
608
|
+
suggestedFix: "Extend the expiration date or create a new discount.",
|
|
609
|
+
context: { name: attrs.name, expiresAt: attrs.expires_at }
|
|
610
|
+
}
|
|
611
|
+
)
|
|
612
|
+
);
|
|
613
|
+
}
|
|
614
|
+
if (attrs.starts_at && new Date(attrs.starts_at) > now) {
|
|
615
|
+
issues.push(
|
|
616
|
+
issue(
|
|
617
|
+
ISSUE_CODES.DISCOUNT_NOT_STARTED,
|
|
618
|
+
"warning",
|
|
619
|
+
`Discount "${attrs.name}" starts at ${attrs.starts_at} \u2014 not yet active.`,
|
|
620
|
+
{
|
|
621
|
+
suggestedFix: "Wait for the start date or adjust it in the dashboard.",
|
|
622
|
+
context: { name: attrs.name, startsAt: attrs.starts_at }
|
|
623
|
+
}
|
|
624
|
+
)
|
|
625
|
+
);
|
|
626
|
+
}
|
|
627
|
+
if (attrs.is_limited_redemptions && attrs.max_redemptions <= 0) {
|
|
628
|
+
issues.push(
|
|
629
|
+
issue(
|
|
630
|
+
ISSUE_CODES.DISCOUNT_REDEMPTIONS_EXHAUSTED,
|
|
631
|
+
"warning",
|
|
632
|
+
`Discount "${attrs.name}" has limited redemptions with max_redemptions \u2264 0.`,
|
|
633
|
+
{
|
|
634
|
+
suggestedFix: "Increase max_redemptions or disable the redemption limit.",
|
|
635
|
+
context: { name: attrs.name, maxRedemptions: attrs.max_redemptions }
|
|
636
|
+
}
|
|
637
|
+
)
|
|
638
|
+
);
|
|
639
|
+
}
|
|
640
|
+
if (attrs.amount <= 0) {
|
|
641
|
+
issues.push(
|
|
642
|
+
issue(
|
|
643
|
+
ISSUE_CODES.DISCOUNT_INVALID_AMOUNT,
|
|
644
|
+
"error",
|
|
645
|
+
`Discount "${attrs.name}" has amount ${attrs.amount} \u2014 must be positive.`,
|
|
646
|
+
{
|
|
647
|
+
suggestedFix: "Set a positive discount amount in the dashboard.",
|
|
648
|
+
context: { name: attrs.name, amount: attrs.amount }
|
|
649
|
+
}
|
|
650
|
+
)
|
|
651
|
+
);
|
|
652
|
+
} else if (attrs.amount_type === "percent" && attrs.amount > 100) {
|
|
653
|
+
issues.push(
|
|
654
|
+
issue(
|
|
655
|
+
ISSUE_CODES.DISCOUNT_INVALID_AMOUNT,
|
|
656
|
+
"error",
|
|
657
|
+
`Discount "${attrs.name}" is ${attrs.amount}% \u2014 percent discounts cannot exceed 100%.`,
|
|
658
|
+
{
|
|
659
|
+
suggestedFix: "Set the discount to 100% or less.",
|
|
660
|
+
context: { name: attrs.name, amount: attrs.amount, amountType: attrs.amount_type }
|
|
661
|
+
}
|
|
662
|
+
)
|
|
663
|
+
);
|
|
664
|
+
}
|
|
665
|
+
return buildResult("discount", mode, issues, attrs);
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
// src/resources/licenseKeys.ts
|
|
669
|
+
async function getLicenseKey(http, licenseKeyId) {
|
|
670
|
+
return http.getResource(`/v1/license-keys/${licenseKeyId}`);
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
// src/validate/licenseKey.ts
|
|
674
|
+
async function validateLicenseKey(http, mode, options) {
|
|
675
|
+
const issues = [];
|
|
676
|
+
let licenseKey;
|
|
677
|
+
try {
|
|
678
|
+
licenseKey = await getLicenseKey(http, options.licenseKeyId);
|
|
679
|
+
} catch (err) {
|
|
680
|
+
if (err instanceof FreshSqueezyError && err.status === 404) {
|
|
681
|
+
issues.push(
|
|
682
|
+
issue(
|
|
683
|
+
ISSUE_CODES.LICENSE_KEY_NOT_FOUND,
|
|
684
|
+
"error",
|
|
685
|
+
`License key ${options.licenseKeyId} not found.`,
|
|
686
|
+
{
|
|
687
|
+
suggestedFix: "Verify the license key ID in the Lemon Squeezy dashboard.",
|
|
688
|
+
context: { licenseKeyId: String(options.licenseKeyId) }
|
|
689
|
+
}
|
|
690
|
+
)
|
|
691
|
+
);
|
|
692
|
+
return buildResult("licenseKey", mode, issues);
|
|
693
|
+
}
|
|
694
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
695
|
+
issues.push(issue(ISSUE_CODES.UNKNOWN, "error", message));
|
|
696
|
+
return buildResult("licenseKey", mode, issues);
|
|
697
|
+
}
|
|
698
|
+
const attrs = licenseKey.attributes;
|
|
699
|
+
const expectedStore = String(options.storeId);
|
|
700
|
+
const actualStore = String(attrs.store_id);
|
|
701
|
+
if (expectedStore !== actualStore) {
|
|
702
|
+
issues.push(
|
|
703
|
+
issue(
|
|
704
|
+
ISSUE_CODES.LICENSE_KEY_STORE_MISMATCH,
|
|
705
|
+
"error",
|
|
706
|
+
`License key belongs to store ${actualStore}, expected ${expectedStore}.`,
|
|
707
|
+
{
|
|
708
|
+
suggestedFix: "Use the correct store ID or license key ID \u2014 keys should not cross stores.",
|
|
709
|
+
context: { expectedStoreId: expectedStore, actualStoreId: actualStore }
|
|
710
|
+
}
|
|
711
|
+
)
|
|
712
|
+
);
|
|
713
|
+
}
|
|
714
|
+
if (attrs.disabled) {
|
|
715
|
+
issues.push(
|
|
716
|
+
issue(
|
|
717
|
+
ISSUE_CODES.LICENSE_KEY_DISABLED,
|
|
718
|
+
"error",
|
|
719
|
+
`License key ${attrs.key_short} is disabled.`,
|
|
720
|
+
{
|
|
721
|
+
suggestedFix: "Re-enable the license key in the Lemon Squeezy dashboard.",
|
|
722
|
+
context: { keyShort: attrs.key_short }
|
|
723
|
+
}
|
|
724
|
+
)
|
|
725
|
+
);
|
|
726
|
+
}
|
|
727
|
+
if (attrs.expires_at && new Date(attrs.expires_at) < /* @__PURE__ */ new Date()) {
|
|
728
|
+
issues.push(
|
|
729
|
+
issue(
|
|
730
|
+
ISSUE_CODES.LICENSE_KEY_EXPIRED,
|
|
731
|
+
"error",
|
|
732
|
+
`License key ${attrs.key_short} expired at ${attrs.expires_at}.`,
|
|
733
|
+
{
|
|
734
|
+
suggestedFix: "Extend the expiration date or issue a new license key.",
|
|
735
|
+
context: { keyShort: attrs.key_short, expiresAt: attrs.expires_at }
|
|
736
|
+
}
|
|
737
|
+
)
|
|
738
|
+
);
|
|
739
|
+
}
|
|
740
|
+
if (attrs.activation_limit !== null && attrs.instances_count >= attrs.activation_limit) {
|
|
741
|
+
issues.push(
|
|
742
|
+
issue(
|
|
743
|
+
ISSUE_CODES.LICENSE_KEY_AT_ACTIVATION_LIMIT,
|
|
744
|
+
"warning",
|
|
745
|
+
`License key ${attrs.key_short} has reached its activation limit (${attrs.instances_count}/${attrs.activation_limit}).`,
|
|
746
|
+
{
|
|
747
|
+
suggestedFix: "Increase the activation limit or deactivate unused instances.",
|
|
748
|
+
context: {
|
|
749
|
+
keyShort: attrs.key_short,
|
|
750
|
+
instancesCount: attrs.instances_count,
|
|
751
|
+
activationLimit: attrs.activation_limit
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
)
|
|
755
|
+
);
|
|
756
|
+
}
|
|
757
|
+
return buildResult("licenseKey", mode, issues, attrs);
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
// src/validate/subscriptionPlan.ts
|
|
761
|
+
var VALID_INTERVALS = /* @__PURE__ */ new Set(["day", "week", "month", "year"]);
|
|
762
|
+
async function validateSubscriptionPlan(http, mode, options) {
|
|
763
|
+
const issues = [];
|
|
764
|
+
let variant;
|
|
765
|
+
try {
|
|
766
|
+
variant = await getVariant(http, options.variantId);
|
|
767
|
+
} catch (err) {
|
|
768
|
+
if (err instanceof FreshSqueezyError && err.status === 404) {
|
|
769
|
+
issues.push(
|
|
770
|
+
issue(
|
|
771
|
+
ISSUE_CODES.PLAN_VARIANT_NOT_FOUND,
|
|
772
|
+
"error",
|
|
773
|
+
`Variant ${options.variantId} not found.`,
|
|
774
|
+
{
|
|
775
|
+
suggestedFix: "Verify the variant ID in the Lemon Squeezy dashboard.",
|
|
776
|
+
context: { variantId: String(options.variantId) }
|
|
777
|
+
}
|
|
778
|
+
)
|
|
779
|
+
);
|
|
780
|
+
return buildResult("subscriptionPlan", mode, issues);
|
|
781
|
+
}
|
|
782
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
783
|
+
issues.push(issue(ISSUE_CODES.UNKNOWN, "error", message));
|
|
784
|
+
return buildResult("subscriptionPlan", mode, issues);
|
|
785
|
+
}
|
|
786
|
+
const attrs = variant.attributes;
|
|
787
|
+
if (!attrs.is_subscription) {
|
|
788
|
+
issues.push(
|
|
789
|
+
issue(
|
|
790
|
+
ISSUE_CODES.PLAN_NOT_SUBSCRIPTION,
|
|
791
|
+
"error",
|
|
792
|
+
`Variant ${options.variantId} is not a subscription variant (is_subscription is false).`,
|
|
793
|
+
{
|
|
794
|
+
suggestedFix: "Use a variant that has subscription billing enabled, or use the regular variant validator.",
|
|
795
|
+
context: { variantId: String(options.variantId) }
|
|
796
|
+
}
|
|
797
|
+
)
|
|
798
|
+
);
|
|
799
|
+
}
|
|
800
|
+
if (!attrs.interval || !VALID_INTERVALS.has(attrs.interval)) {
|
|
801
|
+
issues.push(
|
|
802
|
+
issue(
|
|
803
|
+
ISSUE_CODES.PLAN_INVALID_INTERVAL,
|
|
804
|
+
"error",
|
|
805
|
+
`Subscription variant has invalid interval: "${attrs.interval ?? "missing"}". Expected one of: day, week, month, year.`,
|
|
806
|
+
{
|
|
807
|
+
suggestedFix: "Set a valid billing interval in the variant configuration.",
|
|
808
|
+
context: { interval: attrs.interval ?? null }
|
|
809
|
+
}
|
|
810
|
+
)
|
|
811
|
+
);
|
|
812
|
+
}
|
|
813
|
+
if (attrs.interval_count === null || attrs.interval_count <= 0) {
|
|
814
|
+
issues.push(
|
|
815
|
+
issue(
|
|
816
|
+
ISSUE_CODES.PLAN_INVALID_INTERVAL,
|
|
817
|
+
"error",
|
|
818
|
+
`Subscription variant has invalid interval_count: ${attrs.interval_count}. Must be a positive integer.`,
|
|
819
|
+
{
|
|
820
|
+
suggestedFix: "Set interval_count to a positive value (e.g. 1 for monthly, 2 for biweekly).",
|
|
821
|
+
context: { intervalCount: attrs.interval_count }
|
|
822
|
+
}
|
|
823
|
+
)
|
|
824
|
+
);
|
|
825
|
+
}
|
|
826
|
+
if (attrs.price === 0 && attrs.is_subscription) {
|
|
827
|
+
issues.push(
|
|
828
|
+
issue(
|
|
829
|
+
ISSUE_CODES.PLAN_FREE_PRICE,
|
|
830
|
+
"warning",
|
|
831
|
+
`Subscription variant has a price of 0 \u2014 this is almost always a misconfiguration for paid plans.`,
|
|
832
|
+
{
|
|
833
|
+
suggestedFix: "Set the variant price to the intended amount in cents, or confirm this is intentionally free.",
|
|
834
|
+
context: { price: attrs.price }
|
|
835
|
+
}
|
|
836
|
+
)
|
|
837
|
+
);
|
|
838
|
+
}
|
|
839
|
+
if (attrs.has_free_trial && (!attrs.trial_interval || (attrs.trial_interval_count ?? 0) <= 0)) {
|
|
840
|
+
issues.push(
|
|
841
|
+
issue(
|
|
842
|
+
ISSUE_CODES.PLAN_TRIAL_INCONSISTENT,
|
|
843
|
+
"warning",
|
|
844
|
+
`Subscription variant has free trial enabled but trial interval is misconfigured (interval: "${attrs.trial_interval ?? "missing"}", count: ${attrs.trial_interval_count ?? 0}).`,
|
|
845
|
+
{
|
|
846
|
+
suggestedFix: "Set a valid trial interval and count, or disable the free trial.",
|
|
847
|
+
context: {
|
|
848
|
+
trialInterval: attrs.trial_interval ?? null,
|
|
849
|
+
trialIntervalCount: attrs.trial_interval_count ?? null
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
)
|
|
853
|
+
);
|
|
854
|
+
}
|
|
855
|
+
if (attrs.status === "draft") {
|
|
856
|
+
issues.push(
|
|
857
|
+
issue(
|
|
858
|
+
ISSUE_CODES.PLAN_DRAFT,
|
|
859
|
+
"warning",
|
|
860
|
+
`Subscription variant is in draft status \u2014 customers cannot subscribe.`,
|
|
861
|
+
{
|
|
862
|
+
suggestedFix: "Publish the variant in the Lemon Squeezy dashboard.",
|
|
863
|
+
context: { status: attrs.status }
|
|
864
|
+
}
|
|
865
|
+
)
|
|
866
|
+
);
|
|
867
|
+
}
|
|
868
|
+
try {
|
|
869
|
+
const product = await getProduct(http, attrs.product_id);
|
|
870
|
+
const expectedStore = String(options.storeId);
|
|
871
|
+
const actualStore = String(product.attributes.store_id);
|
|
872
|
+
if (expectedStore !== actualStore) {
|
|
873
|
+
issues.push(
|
|
874
|
+
issue(
|
|
875
|
+
ISSUE_CODES.PLAN_STORE_MISMATCH,
|
|
876
|
+
"error",
|
|
877
|
+
`Subscription variant belongs to store ${actualStore} (via product ${attrs.product_id}), expected ${expectedStore}.`,
|
|
878
|
+
{
|
|
879
|
+
suggestedFix: "Use the correct store ID or variant ID \u2014 plans should not cross stores.",
|
|
880
|
+
context: { expectedStoreId: expectedStore, actualStoreId: actualStore, productId: String(attrs.product_id) }
|
|
881
|
+
}
|
|
882
|
+
)
|
|
883
|
+
);
|
|
884
|
+
}
|
|
885
|
+
} catch {
|
|
886
|
+
}
|
|
887
|
+
const summary = {
|
|
888
|
+
variantId: variant.id,
|
|
889
|
+
interval: attrs.interval,
|
|
890
|
+
intervalCount: attrs.interval_count,
|
|
891
|
+
price: attrs.price,
|
|
892
|
+
hasFreeTrial: attrs.has_free_trial,
|
|
893
|
+
status: attrs.status
|
|
894
|
+
};
|
|
895
|
+
return buildResult("subscriptionPlan", mode, issues, summary);
|
|
896
|
+
}
|
|
897
|
+
|
|
524
898
|
// src/validate/doctor.ts
|
|
525
899
|
async function doctor(http, mode, options = {}) {
|
|
526
900
|
const results = [];
|
|
@@ -548,6 +922,30 @@ async function doctor(http, mode, options = {}) {
|
|
|
548
922
|
})
|
|
549
923
|
);
|
|
550
924
|
}
|
|
925
|
+
if (options.storeId !== void 0 && options.discountId !== void 0) {
|
|
926
|
+
results.push(
|
|
927
|
+
await validateDiscount(http, mode, {
|
|
928
|
+
storeId: options.storeId,
|
|
929
|
+
discountId: options.discountId
|
|
930
|
+
})
|
|
931
|
+
);
|
|
932
|
+
}
|
|
933
|
+
if (options.storeId !== void 0 && options.licenseKeyId !== void 0) {
|
|
934
|
+
results.push(
|
|
935
|
+
await validateLicenseKey(http, mode, {
|
|
936
|
+
storeId: options.storeId,
|
|
937
|
+
licenseKeyId: options.licenseKeyId
|
|
938
|
+
})
|
|
939
|
+
);
|
|
940
|
+
}
|
|
941
|
+
if (options.storeId !== void 0 && options.variantId !== void 0) {
|
|
942
|
+
results.push(
|
|
943
|
+
await validateSubscriptionPlan(http, mode, {
|
|
944
|
+
storeId: options.storeId,
|
|
945
|
+
variantId: options.variantId
|
|
946
|
+
})
|
|
947
|
+
);
|
|
948
|
+
}
|
|
551
949
|
const ok = results.every((result) => result.ok);
|
|
552
950
|
return { ok, mode, results };
|
|
553
951
|
}
|
|
@@ -563,10 +961,16 @@ function createFreshSqueezy(config = {}) {
|
|
|
563
961
|
validateStore: (storeId) => validateStore(http, resolved.mode, storeId),
|
|
564
962
|
validateProduct: (options) => validateProduct(http, resolved.mode, options),
|
|
565
963
|
validateWebhook: (options) => validateWebhook(http, resolved.mode, options),
|
|
964
|
+
validateDiscount: (options) => validateDiscount(http, resolved.mode, options),
|
|
965
|
+
validateLicenseKey: (options) => validateLicenseKey(http, resolved.mode, options),
|
|
966
|
+
validateSubscriptionPlan: (options) => validateSubscriptionPlan(http, resolved.mode, options),
|
|
566
967
|
doctor: (options) => doctor(http, resolved.mode, {
|
|
567
968
|
storeId: options?.storeId ?? resolved.storeId,
|
|
568
969
|
productId: options?.productId,
|
|
569
|
-
webhookUrl: options?.webhookUrl
|
|
970
|
+
webhookUrl: options?.webhookUrl,
|
|
971
|
+
discountId: options?.discountId,
|
|
972
|
+
licenseKeyId: options?.licenseKeyId,
|
|
973
|
+
variantId: options?.variantId
|
|
570
974
|
})
|
|
571
975
|
};
|
|
572
976
|
}
|
|
@@ -584,6 +988,7 @@ export {
|
|
|
584
988
|
getAuthenticatedUser,
|
|
585
989
|
getProduct,
|
|
586
990
|
getStore,
|
|
991
|
+
getVariant,
|
|
587
992
|
isOk,
|
|
588
993
|
issue,
|
|
589
994
|
listProducts,
|