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.cjs
CHANGED
|
@@ -33,6 +33,7 @@ __export(src_exports, {
|
|
|
33
33
|
getAuthenticatedUser: () => getAuthenticatedUser,
|
|
34
34
|
getProduct: () => getProduct,
|
|
35
35
|
getStore: () => getStore,
|
|
36
|
+
getVariant: () => getVariant,
|
|
36
37
|
isOk: () => isOk,
|
|
37
38
|
issue: () => issue,
|
|
38
39
|
listProducts: () => listProducts,
|
|
@@ -213,6 +214,25 @@ var ISSUE_CODES = {
|
|
|
213
214
|
WEBHOOK_NOT_FOUND: "WEBHOOK_NOT_FOUND",
|
|
214
215
|
WEBHOOK_EVENTS_MISSING: "WEBHOOK_EVENTS_MISSING",
|
|
215
216
|
WEBHOOK_OPTIONAL_EVENTS: "WEBHOOK_OPTIONAL_EVENTS",
|
|
217
|
+
DISCOUNT_NOT_FOUND: "DISCOUNT_NOT_FOUND",
|
|
218
|
+
DISCOUNT_DRAFT: "DISCOUNT_DRAFT",
|
|
219
|
+
DISCOUNT_EXPIRED: "DISCOUNT_EXPIRED",
|
|
220
|
+
DISCOUNT_NOT_STARTED: "DISCOUNT_NOT_STARTED",
|
|
221
|
+
DISCOUNT_REDEMPTIONS_EXHAUSTED: "DISCOUNT_REDEMPTIONS_EXHAUSTED",
|
|
222
|
+
DISCOUNT_INVALID_AMOUNT: "DISCOUNT_INVALID_AMOUNT",
|
|
223
|
+
DISCOUNT_STORE_MISMATCH: "DISCOUNT_STORE_MISMATCH",
|
|
224
|
+
LICENSE_KEY_NOT_FOUND: "LICENSE_KEY_NOT_FOUND",
|
|
225
|
+
LICENSE_KEY_DISABLED: "LICENSE_KEY_DISABLED",
|
|
226
|
+
LICENSE_KEY_EXPIRED: "LICENSE_KEY_EXPIRED",
|
|
227
|
+
LICENSE_KEY_AT_ACTIVATION_LIMIT: "LICENSE_KEY_AT_ACTIVATION_LIMIT",
|
|
228
|
+
LICENSE_KEY_STORE_MISMATCH: "LICENSE_KEY_STORE_MISMATCH",
|
|
229
|
+
PLAN_VARIANT_NOT_FOUND: "PLAN_VARIANT_NOT_FOUND",
|
|
230
|
+
PLAN_NOT_SUBSCRIPTION: "PLAN_NOT_SUBSCRIPTION",
|
|
231
|
+
PLAN_INVALID_INTERVAL: "PLAN_INVALID_INTERVAL",
|
|
232
|
+
PLAN_FREE_PRICE: "PLAN_FREE_PRICE",
|
|
233
|
+
PLAN_TRIAL_INCONSISTENT: "PLAN_TRIAL_INCONSISTENT",
|
|
234
|
+
PLAN_DRAFT: "PLAN_DRAFT",
|
|
235
|
+
PLAN_STORE_MISMATCH: "PLAN_STORE_MISMATCH",
|
|
216
236
|
NETWORK_ERROR: "NETWORK_ERROR",
|
|
217
237
|
UNKNOWN: "UNKNOWN"
|
|
218
238
|
};
|
|
@@ -349,6 +369,9 @@ async function listProducts(http, storeId) {
|
|
|
349
369
|
}
|
|
350
370
|
|
|
351
371
|
// src/resources/variants.ts
|
|
372
|
+
async function getVariant(http, variantId) {
|
|
373
|
+
return http.getResource(`/v1/variants/${variantId}`);
|
|
374
|
+
}
|
|
352
375
|
async function listVariantsForProduct(http, productId) {
|
|
353
376
|
return http.getCollection("/v1/variants", {
|
|
354
377
|
"filter[product_id]": String(productId)
|
|
@@ -570,6 +593,358 @@ function normalizeUrl(raw) {
|
|
|
570
593
|
return raw.replace(/\/+$/, "").toLowerCase();
|
|
571
594
|
}
|
|
572
595
|
|
|
596
|
+
// src/resources/discounts.ts
|
|
597
|
+
async function getDiscount(http, discountId) {
|
|
598
|
+
return http.getResource(`/v1/discounts/${discountId}`);
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
// src/validate/discount.ts
|
|
602
|
+
async function validateDiscount(http, mode, options) {
|
|
603
|
+
const issues = [];
|
|
604
|
+
let discount;
|
|
605
|
+
try {
|
|
606
|
+
discount = await getDiscount(http, options.discountId);
|
|
607
|
+
} catch (err) {
|
|
608
|
+
if (err instanceof FreshSqueezyError && err.status === 404) {
|
|
609
|
+
issues.push(
|
|
610
|
+
issue(ISSUE_CODES.DISCOUNT_NOT_FOUND, "error", `Discount ${options.discountId} not found.`, {
|
|
611
|
+
suggestedFix: "Verify the discount ID in the Lemon Squeezy dashboard.",
|
|
612
|
+
context: { discountId: String(options.discountId) }
|
|
613
|
+
})
|
|
614
|
+
);
|
|
615
|
+
return buildResult("discount", mode, issues);
|
|
616
|
+
}
|
|
617
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
618
|
+
issues.push(issue(ISSUE_CODES.UNKNOWN, "error", message));
|
|
619
|
+
return buildResult("discount", mode, issues);
|
|
620
|
+
}
|
|
621
|
+
const attrs = discount.attributes;
|
|
622
|
+
const expectedStore = String(options.storeId);
|
|
623
|
+
const actualStore = String(attrs.store_id);
|
|
624
|
+
if (expectedStore !== actualStore) {
|
|
625
|
+
issues.push(
|
|
626
|
+
issue(
|
|
627
|
+
ISSUE_CODES.DISCOUNT_STORE_MISMATCH,
|
|
628
|
+
"error",
|
|
629
|
+
`Discount belongs to store ${actualStore}, expected ${expectedStore}.`,
|
|
630
|
+
{
|
|
631
|
+
suggestedFix: "Use the correct store ID or discount ID \u2014 discounts should not cross stores.",
|
|
632
|
+
context: { expectedStoreId: expectedStore, actualStoreId: actualStore }
|
|
633
|
+
}
|
|
634
|
+
)
|
|
635
|
+
);
|
|
636
|
+
}
|
|
637
|
+
if (attrs.status === "draft") {
|
|
638
|
+
issues.push(
|
|
639
|
+
issue(
|
|
640
|
+
ISSUE_CODES.DISCOUNT_DRAFT,
|
|
641
|
+
"warning",
|
|
642
|
+
`Discount "${attrs.name}" is in draft status \u2014 customers cannot redeem it.`,
|
|
643
|
+
{
|
|
644
|
+
suggestedFix: "Publish the discount in the Lemon Squeezy dashboard before sharing the code.",
|
|
645
|
+
context: { name: attrs.name, code: attrs.code }
|
|
646
|
+
}
|
|
647
|
+
)
|
|
648
|
+
);
|
|
649
|
+
}
|
|
650
|
+
const now = /* @__PURE__ */ new Date();
|
|
651
|
+
if (attrs.expires_at && new Date(attrs.expires_at) < now) {
|
|
652
|
+
issues.push(
|
|
653
|
+
issue(
|
|
654
|
+
ISSUE_CODES.DISCOUNT_EXPIRED,
|
|
655
|
+
"error",
|
|
656
|
+
`Discount "${attrs.name}" expired at ${attrs.expires_at}.`,
|
|
657
|
+
{
|
|
658
|
+
suggestedFix: "Extend the expiration date or create a new discount.",
|
|
659
|
+
context: { name: attrs.name, expiresAt: attrs.expires_at }
|
|
660
|
+
}
|
|
661
|
+
)
|
|
662
|
+
);
|
|
663
|
+
}
|
|
664
|
+
if (attrs.starts_at && new Date(attrs.starts_at) > now) {
|
|
665
|
+
issues.push(
|
|
666
|
+
issue(
|
|
667
|
+
ISSUE_CODES.DISCOUNT_NOT_STARTED,
|
|
668
|
+
"warning",
|
|
669
|
+
`Discount "${attrs.name}" starts at ${attrs.starts_at} \u2014 not yet active.`,
|
|
670
|
+
{
|
|
671
|
+
suggestedFix: "Wait for the start date or adjust it in the dashboard.",
|
|
672
|
+
context: { name: attrs.name, startsAt: attrs.starts_at }
|
|
673
|
+
}
|
|
674
|
+
)
|
|
675
|
+
);
|
|
676
|
+
}
|
|
677
|
+
if (attrs.is_limited_redemptions && attrs.max_redemptions <= 0) {
|
|
678
|
+
issues.push(
|
|
679
|
+
issue(
|
|
680
|
+
ISSUE_CODES.DISCOUNT_REDEMPTIONS_EXHAUSTED,
|
|
681
|
+
"warning",
|
|
682
|
+
`Discount "${attrs.name}" has limited redemptions with max_redemptions \u2264 0.`,
|
|
683
|
+
{
|
|
684
|
+
suggestedFix: "Increase max_redemptions or disable the redemption limit.",
|
|
685
|
+
context: { name: attrs.name, maxRedemptions: attrs.max_redemptions }
|
|
686
|
+
}
|
|
687
|
+
)
|
|
688
|
+
);
|
|
689
|
+
}
|
|
690
|
+
if (attrs.amount <= 0) {
|
|
691
|
+
issues.push(
|
|
692
|
+
issue(
|
|
693
|
+
ISSUE_CODES.DISCOUNT_INVALID_AMOUNT,
|
|
694
|
+
"error",
|
|
695
|
+
`Discount "${attrs.name}" has amount ${attrs.amount} \u2014 must be positive.`,
|
|
696
|
+
{
|
|
697
|
+
suggestedFix: "Set a positive discount amount in the dashboard.",
|
|
698
|
+
context: { name: attrs.name, amount: attrs.amount }
|
|
699
|
+
}
|
|
700
|
+
)
|
|
701
|
+
);
|
|
702
|
+
} else if (attrs.amount_type === "percent" && attrs.amount > 100) {
|
|
703
|
+
issues.push(
|
|
704
|
+
issue(
|
|
705
|
+
ISSUE_CODES.DISCOUNT_INVALID_AMOUNT,
|
|
706
|
+
"error",
|
|
707
|
+
`Discount "${attrs.name}" is ${attrs.amount}% \u2014 percent discounts cannot exceed 100%.`,
|
|
708
|
+
{
|
|
709
|
+
suggestedFix: "Set the discount to 100% or less.",
|
|
710
|
+
context: { name: attrs.name, amount: attrs.amount, amountType: attrs.amount_type }
|
|
711
|
+
}
|
|
712
|
+
)
|
|
713
|
+
);
|
|
714
|
+
}
|
|
715
|
+
return buildResult("discount", mode, issues, attrs);
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
// src/resources/licenseKeys.ts
|
|
719
|
+
async function getLicenseKey(http, licenseKeyId) {
|
|
720
|
+
return http.getResource(`/v1/license-keys/${licenseKeyId}`);
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
// src/validate/licenseKey.ts
|
|
724
|
+
async function validateLicenseKey(http, mode, options) {
|
|
725
|
+
const issues = [];
|
|
726
|
+
let licenseKey;
|
|
727
|
+
try {
|
|
728
|
+
licenseKey = await getLicenseKey(http, options.licenseKeyId);
|
|
729
|
+
} catch (err) {
|
|
730
|
+
if (err instanceof FreshSqueezyError && err.status === 404) {
|
|
731
|
+
issues.push(
|
|
732
|
+
issue(
|
|
733
|
+
ISSUE_CODES.LICENSE_KEY_NOT_FOUND,
|
|
734
|
+
"error",
|
|
735
|
+
`License key ${options.licenseKeyId} not found.`,
|
|
736
|
+
{
|
|
737
|
+
suggestedFix: "Verify the license key ID in the Lemon Squeezy dashboard.",
|
|
738
|
+
context: { licenseKeyId: String(options.licenseKeyId) }
|
|
739
|
+
}
|
|
740
|
+
)
|
|
741
|
+
);
|
|
742
|
+
return buildResult("licenseKey", mode, issues);
|
|
743
|
+
}
|
|
744
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
745
|
+
issues.push(issue(ISSUE_CODES.UNKNOWN, "error", message));
|
|
746
|
+
return buildResult("licenseKey", mode, issues);
|
|
747
|
+
}
|
|
748
|
+
const attrs = licenseKey.attributes;
|
|
749
|
+
const expectedStore = String(options.storeId);
|
|
750
|
+
const actualStore = String(attrs.store_id);
|
|
751
|
+
if (expectedStore !== actualStore) {
|
|
752
|
+
issues.push(
|
|
753
|
+
issue(
|
|
754
|
+
ISSUE_CODES.LICENSE_KEY_STORE_MISMATCH,
|
|
755
|
+
"error",
|
|
756
|
+
`License key belongs to store ${actualStore}, expected ${expectedStore}.`,
|
|
757
|
+
{
|
|
758
|
+
suggestedFix: "Use the correct store ID or license key ID \u2014 keys should not cross stores.",
|
|
759
|
+
context: { expectedStoreId: expectedStore, actualStoreId: actualStore }
|
|
760
|
+
}
|
|
761
|
+
)
|
|
762
|
+
);
|
|
763
|
+
}
|
|
764
|
+
if (attrs.disabled) {
|
|
765
|
+
issues.push(
|
|
766
|
+
issue(
|
|
767
|
+
ISSUE_CODES.LICENSE_KEY_DISABLED,
|
|
768
|
+
"error",
|
|
769
|
+
`License key ${attrs.key_short} is disabled.`,
|
|
770
|
+
{
|
|
771
|
+
suggestedFix: "Re-enable the license key in the Lemon Squeezy dashboard.",
|
|
772
|
+
context: { keyShort: attrs.key_short }
|
|
773
|
+
}
|
|
774
|
+
)
|
|
775
|
+
);
|
|
776
|
+
}
|
|
777
|
+
if (attrs.expires_at && new Date(attrs.expires_at) < /* @__PURE__ */ new Date()) {
|
|
778
|
+
issues.push(
|
|
779
|
+
issue(
|
|
780
|
+
ISSUE_CODES.LICENSE_KEY_EXPIRED,
|
|
781
|
+
"error",
|
|
782
|
+
`License key ${attrs.key_short} expired at ${attrs.expires_at}.`,
|
|
783
|
+
{
|
|
784
|
+
suggestedFix: "Extend the expiration date or issue a new license key.",
|
|
785
|
+
context: { keyShort: attrs.key_short, expiresAt: attrs.expires_at }
|
|
786
|
+
}
|
|
787
|
+
)
|
|
788
|
+
);
|
|
789
|
+
}
|
|
790
|
+
if (attrs.activation_limit !== null && attrs.instances_count >= attrs.activation_limit) {
|
|
791
|
+
issues.push(
|
|
792
|
+
issue(
|
|
793
|
+
ISSUE_CODES.LICENSE_KEY_AT_ACTIVATION_LIMIT,
|
|
794
|
+
"warning",
|
|
795
|
+
`License key ${attrs.key_short} has reached its activation limit (${attrs.instances_count}/${attrs.activation_limit}).`,
|
|
796
|
+
{
|
|
797
|
+
suggestedFix: "Increase the activation limit or deactivate unused instances.",
|
|
798
|
+
context: {
|
|
799
|
+
keyShort: attrs.key_short,
|
|
800
|
+
instancesCount: attrs.instances_count,
|
|
801
|
+
activationLimit: attrs.activation_limit
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
)
|
|
805
|
+
);
|
|
806
|
+
}
|
|
807
|
+
return buildResult("licenseKey", mode, issues, attrs);
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
// src/validate/subscriptionPlan.ts
|
|
811
|
+
var VALID_INTERVALS = /* @__PURE__ */ new Set(["day", "week", "month", "year"]);
|
|
812
|
+
async function validateSubscriptionPlan(http, mode, options) {
|
|
813
|
+
const issues = [];
|
|
814
|
+
let variant;
|
|
815
|
+
try {
|
|
816
|
+
variant = await getVariant(http, options.variantId);
|
|
817
|
+
} catch (err) {
|
|
818
|
+
if (err instanceof FreshSqueezyError && err.status === 404) {
|
|
819
|
+
issues.push(
|
|
820
|
+
issue(
|
|
821
|
+
ISSUE_CODES.PLAN_VARIANT_NOT_FOUND,
|
|
822
|
+
"error",
|
|
823
|
+
`Variant ${options.variantId} not found.`,
|
|
824
|
+
{
|
|
825
|
+
suggestedFix: "Verify the variant ID in the Lemon Squeezy dashboard.",
|
|
826
|
+
context: { variantId: String(options.variantId) }
|
|
827
|
+
}
|
|
828
|
+
)
|
|
829
|
+
);
|
|
830
|
+
return buildResult("subscriptionPlan", mode, issues);
|
|
831
|
+
}
|
|
832
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
833
|
+
issues.push(issue(ISSUE_CODES.UNKNOWN, "error", message));
|
|
834
|
+
return buildResult("subscriptionPlan", mode, issues);
|
|
835
|
+
}
|
|
836
|
+
const attrs = variant.attributes;
|
|
837
|
+
if (!attrs.is_subscription) {
|
|
838
|
+
issues.push(
|
|
839
|
+
issue(
|
|
840
|
+
ISSUE_CODES.PLAN_NOT_SUBSCRIPTION,
|
|
841
|
+
"error",
|
|
842
|
+
`Variant ${options.variantId} is not a subscription variant (is_subscription is false).`,
|
|
843
|
+
{
|
|
844
|
+
suggestedFix: "Use a variant that has subscription billing enabled, or use the regular variant validator.",
|
|
845
|
+
context: { variantId: String(options.variantId) }
|
|
846
|
+
}
|
|
847
|
+
)
|
|
848
|
+
);
|
|
849
|
+
}
|
|
850
|
+
if (!attrs.interval || !VALID_INTERVALS.has(attrs.interval)) {
|
|
851
|
+
issues.push(
|
|
852
|
+
issue(
|
|
853
|
+
ISSUE_CODES.PLAN_INVALID_INTERVAL,
|
|
854
|
+
"error",
|
|
855
|
+
`Subscription variant has invalid interval: "${attrs.interval ?? "missing"}". Expected one of: day, week, month, year.`,
|
|
856
|
+
{
|
|
857
|
+
suggestedFix: "Set a valid billing interval in the variant configuration.",
|
|
858
|
+
context: { interval: attrs.interval ?? null }
|
|
859
|
+
}
|
|
860
|
+
)
|
|
861
|
+
);
|
|
862
|
+
}
|
|
863
|
+
if (attrs.interval_count === null || attrs.interval_count <= 0) {
|
|
864
|
+
issues.push(
|
|
865
|
+
issue(
|
|
866
|
+
ISSUE_CODES.PLAN_INVALID_INTERVAL,
|
|
867
|
+
"error",
|
|
868
|
+
`Subscription variant has invalid interval_count: ${attrs.interval_count}. Must be a positive integer.`,
|
|
869
|
+
{
|
|
870
|
+
suggestedFix: "Set interval_count to a positive value (e.g. 1 for monthly, 2 for biweekly).",
|
|
871
|
+
context: { intervalCount: attrs.interval_count }
|
|
872
|
+
}
|
|
873
|
+
)
|
|
874
|
+
);
|
|
875
|
+
}
|
|
876
|
+
if (attrs.price === 0 && attrs.is_subscription) {
|
|
877
|
+
issues.push(
|
|
878
|
+
issue(
|
|
879
|
+
ISSUE_CODES.PLAN_FREE_PRICE,
|
|
880
|
+
"warning",
|
|
881
|
+
`Subscription variant has a price of 0 \u2014 this is almost always a misconfiguration for paid plans.`,
|
|
882
|
+
{
|
|
883
|
+
suggestedFix: "Set the variant price to the intended amount in cents, or confirm this is intentionally free.",
|
|
884
|
+
context: { price: attrs.price }
|
|
885
|
+
}
|
|
886
|
+
)
|
|
887
|
+
);
|
|
888
|
+
}
|
|
889
|
+
if (attrs.has_free_trial && (!attrs.trial_interval || (attrs.trial_interval_count ?? 0) <= 0)) {
|
|
890
|
+
issues.push(
|
|
891
|
+
issue(
|
|
892
|
+
ISSUE_CODES.PLAN_TRIAL_INCONSISTENT,
|
|
893
|
+
"warning",
|
|
894
|
+
`Subscription variant has free trial enabled but trial interval is misconfigured (interval: "${attrs.trial_interval ?? "missing"}", count: ${attrs.trial_interval_count ?? 0}).`,
|
|
895
|
+
{
|
|
896
|
+
suggestedFix: "Set a valid trial interval and count, or disable the free trial.",
|
|
897
|
+
context: {
|
|
898
|
+
trialInterval: attrs.trial_interval ?? null,
|
|
899
|
+
trialIntervalCount: attrs.trial_interval_count ?? null
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
)
|
|
903
|
+
);
|
|
904
|
+
}
|
|
905
|
+
if (attrs.status === "draft") {
|
|
906
|
+
issues.push(
|
|
907
|
+
issue(
|
|
908
|
+
ISSUE_CODES.PLAN_DRAFT,
|
|
909
|
+
"warning",
|
|
910
|
+
`Subscription variant is in draft status \u2014 customers cannot subscribe.`,
|
|
911
|
+
{
|
|
912
|
+
suggestedFix: "Publish the variant in the Lemon Squeezy dashboard.",
|
|
913
|
+
context: { status: attrs.status }
|
|
914
|
+
}
|
|
915
|
+
)
|
|
916
|
+
);
|
|
917
|
+
}
|
|
918
|
+
try {
|
|
919
|
+
const product = await getProduct(http, attrs.product_id);
|
|
920
|
+
const expectedStore = String(options.storeId);
|
|
921
|
+
const actualStore = String(product.attributes.store_id);
|
|
922
|
+
if (expectedStore !== actualStore) {
|
|
923
|
+
issues.push(
|
|
924
|
+
issue(
|
|
925
|
+
ISSUE_CODES.PLAN_STORE_MISMATCH,
|
|
926
|
+
"error",
|
|
927
|
+
`Subscription variant belongs to store ${actualStore} (via product ${attrs.product_id}), expected ${expectedStore}.`,
|
|
928
|
+
{
|
|
929
|
+
suggestedFix: "Use the correct store ID or variant ID \u2014 plans should not cross stores.",
|
|
930
|
+
context: { expectedStoreId: expectedStore, actualStoreId: actualStore, productId: String(attrs.product_id) }
|
|
931
|
+
}
|
|
932
|
+
)
|
|
933
|
+
);
|
|
934
|
+
}
|
|
935
|
+
} catch {
|
|
936
|
+
}
|
|
937
|
+
const summary = {
|
|
938
|
+
variantId: variant.id,
|
|
939
|
+
interval: attrs.interval,
|
|
940
|
+
intervalCount: attrs.interval_count,
|
|
941
|
+
price: attrs.price,
|
|
942
|
+
hasFreeTrial: attrs.has_free_trial,
|
|
943
|
+
status: attrs.status
|
|
944
|
+
};
|
|
945
|
+
return buildResult("subscriptionPlan", mode, issues, summary);
|
|
946
|
+
}
|
|
947
|
+
|
|
573
948
|
// src/validate/doctor.ts
|
|
574
949
|
async function doctor(http, mode, options = {}) {
|
|
575
950
|
const results = [];
|
|
@@ -597,6 +972,30 @@ async function doctor(http, mode, options = {}) {
|
|
|
597
972
|
})
|
|
598
973
|
);
|
|
599
974
|
}
|
|
975
|
+
if (options.storeId !== void 0 && options.discountId !== void 0) {
|
|
976
|
+
results.push(
|
|
977
|
+
await validateDiscount(http, mode, {
|
|
978
|
+
storeId: options.storeId,
|
|
979
|
+
discountId: options.discountId
|
|
980
|
+
})
|
|
981
|
+
);
|
|
982
|
+
}
|
|
983
|
+
if (options.storeId !== void 0 && options.licenseKeyId !== void 0) {
|
|
984
|
+
results.push(
|
|
985
|
+
await validateLicenseKey(http, mode, {
|
|
986
|
+
storeId: options.storeId,
|
|
987
|
+
licenseKeyId: options.licenseKeyId
|
|
988
|
+
})
|
|
989
|
+
);
|
|
990
|
+
}
|
|
991
|
+
if (options.storeId !== void 0 && options.variantId !== void 0) {
|
|
992
|
+
results.push(
|
|
993
|
+
await validateSubscriptionPlan(http, mode, {
|
|
994
|
+
storeId: options.storeId,
|
|
995
|
+
variantId: options.variantId
|
|
996
|
+
})
|
|
997
|
+
);
|
|
998
|
+
}
|
|
600
999
|
const ok = results.every((result) => result.ok);
|
|
601
1000
|
return { ok, mode, results };
|
|
602
1001
|
}
|
|
@@ -612,10 +1011,16 @@ function createFreshSqueezy(config = {}) {
|
|
|
612
1011
|
validateStore: (storeId) => validateStore(http, resolved.mode, storeId),
|
|
613
1012
|
validateProduct: (options) => validateProduct(http, resolved.mode, options),
|
|
614
1013
|
validateWebhook: (options) => validateWebhook(http, resolved.mode, options),
|
|
1014
|
+
validateDiscount: (options) => validateDiscount(http, resolved.mode, options),
|
|
1015
|
+
validateLicenseKey: (options) => validateLicenseKey(http, resolved.mode, options),
|
|
1016
|
+
validateSubscriptionPlan: (options) => validateSubscriptionPlan(http, resolved.mode, options),
|
|
615
1017
|
doctor: (options) => doctor(http, resolved.mode, {
|
|
616
1018
|
storeId: options?.storeId ?? resolved.storeId,
|
|
617
1019
|
productId: options?.productId,
|
|
618
|
-
webhookUrl: options?.webhookUrl
|
|
1020
|
+
webhookUrl: options?.webhookUrl,
|
|
1021
|
+
discountId: options?.discountId,
|
|
1022
|
+
licenseKeyId: options?.licenseKeyId,
|
|
1023
|
+
variantId: options?.variantId
|
|
619
1024
|
})
|
|
620
1025
|
};
|
|
621
1026
|
}
|
|
@@ -634,6 +1039,7 @@ function createFreshSqueezy(config = {}) {
|
|
|
634
1039
|
getAuthenticatedUser,
|
|
635
1040
|
getProduct,
|
|
636
1041
|
getStore,
|
|
1042
|
+
getVariant,
|
|
637
1043
|
isOk,
|
|
638
1044
|
issue,
|
|
639
1045
|
listProducts,
|