diff --git a/.env.sample b/.env.sample index 6ebe82c..076f629 100644 --- a/.env.sample +++ b/.env.sample @@ -1,12 +1,16 @@ +# This environment file holds a dummy plugin from Freemius for testing purposes. # PLUGIN ID -VITE_PLUGIN_ID=0000 +VITE_PLUGIN_ID=311 # PUBLIC KEY -VITE_PUBLIC_KEY="pk_0000" +VITE_PUBLIC_KEY="pk_a42d2ee6de0b31c389d5d11e36211" # PLAN IDs -VITE_PLAN_ONE=0000 -VITE_PLAN_TWO=0001 -VITE_PLAN_THREE=0002 +# Plan Starter +#VITE_PLAN_ONE=0000 +# Plan Professional +VITE_PLAN_TWO=437 +# Plan Business +VITE_PLAN_THREE=20074 # Add a Sandbox Token (optional) -# VITE_SANDBOX_TOKEN="xxxxxxxx" +VITE_SANDBOX_TOKEN="5548f3de8a7e02a838427c549a588644" # Add a Sandbox Context (optional) -# VITE_SANDBOX_CTX="0000000" +VITE_SANDBOX_CTX="1626969480" diff --git a/.idea/prettier.xml b/.idea/prettier.xml index 0c83ac4..54ece71 100644 --- a/.idea/prettier.xml +++ b/.idea/prettier.xml @@ -3,5 +3,6 @@ \ No newline at end of file diff --git a/README.md b/README.md index 24d1ed8..c9c8e2a 100644 --- a/README.md +++ b/README.md @@ -237,7 +237,7 @@ handler.open({ This is useful when you have multiple checkouts related to different plans, billing cycles, licenses, trials etc. -See the [source code of the demo](./src/test.ts) to learn more. +See the [source code of the demo](./src/demo.ts) to learn more. To close the popup programmatically, call the `close` method. diff --git a/index.html b/index.html index e14ef3c..0dd2aac 100644 --- a/index.html +++ b/index.html @@ -1,42 +1,46 @@ - + - - - - - - Freemius Checkout JS - Without jQuery or other dependencies - - -
-

- -

-

- -

-

- -

-

- -

-

- - - -

-

Check Browser DevTool for more information

-
- - + + + + + + + Freemius Checkout JS - Without jQuery or other dependencies + + + +
+

+ +

+

+ +

+

+ Some licenses may not be available for all plans +

+

+ +

+

+ +

+

+ + + +

+

Check Browser DevTool for more information

+
+ + diff --git a/src/demo.ts b/src/demo.ts index 61364f1..e5b1056 100644 --- a/src/demo.ts +++ b/src/demo.ts @@ -86,38 +86,25 @@ document.addEventListener('DOMContentLoaded', () => { }; } - document.querySelector('#plan-1')?.addEventListener('click', (e) => { - e.preventDefault(); - fsCheckout.open({ - plan_id: Number.parseInt( - import.meta.env.VITE_PLAN_ONE as string, - 10 - ), - ...getLicensesAndFrequency(), - ...getEventLoggers(), - }); - }); - document.querySelector('#plan-2')?.addEventListener('click', (e) => { - e.preventDefault(); - fsCheckout.open({ - plan_id: Number.parseInt( - import.meta.env.VITE_PLAN_TWO as string, - 10 - ), - ...getLicensesAndFrequency(), - ...getEventLoggers(), - }); - }); - document.querySelector('#plan-3')?.addEventListener('click', (e) => { - e.preventDefault(); - fsCheckout.open({ - plan_id: Number.parseInt( - import.meta.env.VITE_PLAN_THREE as string, - 10 - ), - ...getLicensesAndFrequency(), - ...getEventLoggers(), - }); + const plans = { + '#plan-1': import.meta.env.VITE_PLAN_ONE as string, + '#plan-2': import.meta.env.VITE_PLAN_TWO as string, + '#plan-3': import.meta.env.VITE_PLAN_THREE as string, + }; + + Object.entries(plans).forEach(([selector, planId]) => { + if (!planId) { + document.querySelector(selector)?.remove(); + } else { + document.querySelector(selector)?.addEventListener('click', (e) => { + e.preventDefault(); + fsCheckout.open({ + plan_id: Number.parseInt(planId, 10), + ...getLicensesAndFrequency(), + ...getEventLoggers(), + }); + }); + } }); console.log( diff --git a/src/index.ts b/src/index.ts index 84305b3..66d38f7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ export { postman } from './lib/services/postman'; export { buildFreemiusQueryFromOptions, - generateUID, + generateGuid, getIsFlashingBrowser, isExitAttempt, MAX_ZINDEX, diff --git a/src/lib/checkout.ts b/src/lib/checkout.ts index 0d8b2f3..31b6753 100644 --- a/src/lib/checkout.ts +++ b/src/lib/checkout.ts @@ -1,4 +1,4 @@ -import { generateUID, isSsr } from './utils/ops'; +import { generateGuid, isSsr } from './utils/ops'; import { Logger } from './services/logger'; import type { PostmanEvents } from './services/postman'; import type { CheckoutOptions } from './types'; @@ -44,7 +44,7 @@ export class Checkout { } this.options = options; - this.guid = generateUID(); + this.guid = generateGuid(); if (isSsr()) { return; diff --git a/src/lib/services/checkout-popup/CheckoutIFrameBuilder.ts b/src/lib/services/checkout-popup/CheckoutIFrameBuilder.ts index bd6edfa..013fb35 100644 --- a/src/lib/services/checkout-popup/CheckoutIFrameBuilder.ts +++ b/src/lib/services/checkout-popup/CheckoutIFrameBuilder.ts @@ -1,5 +1,5 @@ import { CheckoutPopupOptions } from '../../contracts/CheckoutPopupOptions'; -import { isQueryItemInValid, MAX_ZINDEX } from '../../utils/ops'; +import { isQueryItemInvalid, MAX_ZINDEX } from '../../utils/ops'; import { CheckoutIFrame } from './CheckoutIFrame'; import { IStyle } from '../../contracts/IStyle'; @@ -47,7 +47,7 @@ export class CheckoutIFrameBuilder { }; Object.entries(options).forEach(([key, value]) => { - if (!isQueryItemInValid(value)) { + if (!isQueryItemInvalid(value)) { queryParams[key] = value; } }); diff --git a/src/lib/utils/ops.ts b/src/lib/utils/ops.ts index 96dda96..cdbb137 100644 --- a/src/lib/utils/ops.ts +++ b/src/lib/utils/ops.ts @@ -6,24 +6,29 @@ export const MAX_ZINDEX = 2147483647; /** - * Generate a random UID for use in freemius checkout. This is a simple - * implementation and is not as robust as nanoid or shortid, but it gets the - * job done and is very small. - * - * @link https://stackoverflow.com/a/6248722/2754557 - * - * @returns A random UID. + * Generates a random GUID. It has the original implementation of the legacy Freemius Checkout for backward compatibility. */ -export function generateUID() { - // I generate the UID from two parts here - // to ensure the random number provide enough bits. - const firstPart = (Math.random() * 46656) | 0; - const firstPartStr = `000${firstPart.toString(36)}`.slice(-3); - - const secondPart = (Math.random() * 46656) | 0; - const secondPartStr = `000${secondPart.toString(36)}`.slice(-3); +export function generateGuid() { + const _s4 = function () { + return Math.floor((1 + Math.random()) * 0x10000) + .toString(16) + .substring(1); + }; - return firstPartStr + secondPartStr; + return ( + _s4() + + _s4() + + '-' + + _s4() + + '-' + + _s4() + + '-' + + _s4() + + '-' + + _s4() + + _s4() + + _s4() + ); } export function getIsFlashingBrowser(): boolean { @@ -49,7 +54,7 @@ export function getIsFlashingBrowser(): boolean { return isFlashingBrowser; } -export function isQueryItemInValid(item: any): boolean { +export function isQueryItemInvalid(item: any): boolean { return ( typeof item === 'undefined' || typeof item === 'function' || @@ -58,7 +63,7 @@ export function isQueryItemInValid(item: any): boolean { } export function getQueryValueFromItem(item: any): string | null { - if (isQueryItemInValid(item)) { + if (isQueryItemInvalid(item)) { return null; } @@ -89,6 +94,7 @@ export function buildFreemiusQueryFromOptions(options: Record) { Object.keys(options).forEach((key) => { const item = options[key]; const value = getQueryValueFromItem(item); + if (value !== null) { query.push(`${key}=${value}`); }