@sesamy/sesamy-js 1.54.0 → 1.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -174,6 +174,7 @@ These are the available configuration options, with their default values:
174
174
  domain: null, // Optional: custom Auth0 domain (e.g., 'auth.example.com')
175
175
  domains: [] // Optional: array of auth domain strings for multi-domain setups
176
176
  },
177
+ enablePaywallSettingsUrlFallback: false, // Optional: enable fallback to sesamy-paywall settings-url
177
178
  content: [
178
179
  {
179
180
  type: 'article',
@@ -1101,6 +1102,10 @@ Creates a checkout session with Sesamy. This function initializes a checkout pro
1101
1102
  - sourceId (string, optional): Source identifier.
1102
1103
  - \_ga, \_gid, \_fbp, \_fbc (strings, optional): Analytics tracking cookies.
1103
1104
  - referralEmail (string, optional): Email of the referrer.
1105
+ - payerEmail (string, optional): Email of the payer (person paying for the purchase).
1106
+ - requireAddress (boolean, optional): If true, requires the customer to provide an address during checkout.
1107
+ - giftMode (boolean, optional): If true, enables gift mode for the checkout.
1108
+ - metaData (Record<string, string>, optional): Custom metadata to store with the checkout (e.g., { "campaign": "summer2024", "source": "mobile" }).
1104
1109
 
1105
1110
  ### Returns
1106
1111
 
@@ -1161,52 +1166,38 @@ const checkout = await sesamy.checkouts.create({
1161
1166
  ],
1162
1167
  email: 'customer@example.com',
1163
1168
  redirectUrl: 'https://yoursite.com/checkout-complete',
1169
+ requireAddress: true,
1170
+ metaData: {
1171
+ campaignId: 'summer_2024',
1172
+ source: 'mobile_app',
1173
+ },
1164
1174
  });
1165
1175
 
1166
1176
  // Redirect to checkout
1167
1177
  window.location.href = checkout.checkoutUrl;
1168
1178
  ```
1169
1179
 
1170
- Advanced example with multiple items and tracking:
1180
+ Advanced example with gift mode and payer email:
1171
1181
 
1172
1182
  ```javascript
1173
1183
  const checkout = await sesamy.checkouts.create({
1174
1184
  items: [
1175
1185
  {
1176
- sku: 'premium_annual',
1177
- purchaseOptionId: 'po_456',
1178
- price: 99.99,
1179
- currency: 'USD',
1180
- },
1181
- {
1182
- sku: 'addon_feature',
1183
- price: 9.99,
1186
+ sku: 'premium_gift',
1187
+ purchaseOptionId: 'po_gift',
1188
+ price: 49.99,
1184
1189
  currency: 'USD',
1185
1190
  },
1186
1191
  ],
1187
- email: 'customer@example.com',
1188
- givenName: 'John',
1189
- familyName: 'Doe',
1190
- phoneNumber: '+1234567890',
1191
- address: {
1192
- street: '123 Main St',
1193
- city: 'San Francisco',
1194
- zip: '94102',
1195
- country: 'US',
1196
- },
1192
+ email: 'recipient@example.com',
1193
+ payerEmail: 'sender@example.com',
1197
1194
  redirectUrl: 'https://yoursite.com/checkout-complete',
1195
+ giftMode: true,
1198
1196
  language: 'en',
1199
- attribution: {
1200
- utmSource: 'email',
1201
- utmMedium: 'newsletter',
1202
- utmCampaign: 'summer_sale_2024',
1197
+ metaData: {
1198
+ giftMessage: 'Happy Birthday!',
1199
+ giftFrom: 'John',
1203
1200
  },
1204
- requestedDiscountCodes: ['WELCOME10', 'EARLYBIRD'],
1205
- paymentMethodsFilter: [{ provider: 'stripe', methods: ['card'] }, { provider: 'klarna' }],
1206
- });
1207
-
1208
- window.location.href = checkout.checkoutUrl;
1209
- ```
1210
1201
 
1211
1202
  ### Additional Notes
1212
1203
 
@@ -1246,6 +1237,10 @@ Updates an existing checkout session with Sesamy. You can update customer inform
1246
1237
  - paymentMethodsFilter (Array of objects, optional): Updated payment method filters.
1247
1238
  - requestedDiscountCodes (Array of strings, optional): Updated discount codes to apply.
1248
1239
  - attribution (object, optional): Updated attribution and tracking data.
1240
+ - payerEmail (string, optional): Updated payer email.
1241
+ - requireAddress (boolean, optional): Updated address requirement.
1242
+ - giftMode (boolean, optional): Updated gift mode status.
1243
+ - metaData (Record<string, string>, optional): Updated metadata.
1249
1244
 
1250
1245
  ### Returns
1251
1246
 
@@ -1624,6 +1619,8 @@ console.log('Article title:', title);
1624
1619
 
1625
1620
  The content configuration is defined within the `Config` json. The following properties are available:
1626
1621
 
1622
+ ### Content Node Properties
1623
+
1627
1624
  - `article` (object): Defines the selector for the article element itself.
1628
1625
  - `image` (object): Specifies the selector and attribute for extracting article images.
1629
1626
  - `title` (object): Specifies the selector and attribute for extracting the article title.
@@ -1638,6 +1635,56 @@ Each field object contains the following properties:
1638
1635
  - `selector` (string): A CSS selector to target elements on the page.
1639
1636
  - `attribute` (string, optional): The attribute to retrieve from the selected element. If not specified, the text content of the element is used.
1640
1637
 
1638
+ ### Feature Flags
1639
+
1640
+ #### `enablePaywallSettingsUrlFallback`
1641
+
1642
+ **Type:** `boolean`
1643
+ **Default:** `false`
1644
+
1645
+ When enabled, this feature flag allows the content module to fall back to checking for a `settings-url` attribute on `<sesamy-paywall>` elements when no `paywallUrl` is found through the standard detection methods (meta tags or article attributes).
1646
+
1647
+ **Use Case:** This is useful for pages that use the `<sesamy-paywall>` custom element but don't explicitly set the paywall URL in meta tags or on the article element. The paywall component may have a `settings-url` attribute that points to the paywall configuration.
1648
+
1649
+ **Priority Order:**
1650
+
1651
+ 1. Article element `paywall-url` attribute
1652
+ 2. Content configuration `paywallUrl` property
1653
+ 3. Meta tags (`sesamy:paywall-url`, `og:paywall-url`, etc.)
1654
+ 4. **If `enablePaywallSettingsUrlFallback` is true:** `<sesamy-paywall settings-url="...">` attribute
1655
+
1656
+ **Example:**
1657
+
1658
+ ```javascript
1659
+ // Enable the fallback feature
1660
+ {
1661
+ clientId: "demo",
1662
+ enablePaywallSettingsUrlFallback: true,
1663
+ content: [
1664
+ {
1665
+ type: 'article',
1666
+ selectors: {
1667
+ article: { selector: 'sesamy-article' }
1668
+ }
1669
+ }
1670
+ ]
1671
+ }
1672
+ ```
1673
+
1674
+ ```html
1675
+ <!-- Page with sesamy-paywall element -->
1676
+ <sesamy-paywall settings-url="https://example.com/api/paywalls/123"></sesamy-paywall>
1677
+ <sesamy-article item-src="https://example.com/article/456">
1678
+ <!-- Article content -->
1679
+ </sesamy-article>
1680
+
1681
+ <script>
1682
+ // The content.get() method will now find the paywall URL from the sesamy-paywall element
1683
+ const article = window.sesamy.content.get('sesamy-article');
1684
+ console.log(article.paywallUrl); // "https://example.com/api/paywalls/123"
1685
+ </script>
1686
+ ```
1687
+
1641
1688
  ### Example Configuration
1642
1689
 
1643
1690
  Below is an example configuration for the content module:
@@ -1732,6 +1779,161 @@ console.log(articles);
1732
1779
 
1733
1780
  In this example, `content.list()` will return an array of articles extracted from the page based on the configured selectors. Each article object contains fields such as title, excerpt, image, price, currency, URL, and ID.
1734
1781
 
1782
+ #### `get(articleElementOrSelector: Element | string)`
1783
+
1784
+ Extracts article data from a specific element on the page.
1785
+
1786
+ ### Parameters
1787
+
1788
+ - `articleElementOrSelector` (Element | string): Either a DOM element or a CSS selector string identifying the article element.
1789
+
1790
+ ### Returns
1791
+
1792
+ - `Article | null`: An article object containing the extracted data, or `null` if the element is not found.
1793
+
1794
+ The returned article object contains the following properties:
1795
+
1796
+ - `title` (string, optional): The title of the article.
1797
+ - `excerpt` (string, optional): The article's excerpt.
1798
+ - `image` (string, optional): The source URL of the article's image.
1799
+ - `price` (number, optional): The price of the article.
1800
+ - `currency` (string, optional): The currency of the article price.
1801
+ - `url` (string, optional): The URL of the article.
1802
+ - `id` (string, optional): The article's unique ID.
1803
+ - `pass` (string, optional): Comma-separated list of passes required for access.
1804
+ - `paywallUrl` (string, optional): URL to the paywall configuration.
1805
+ - `accessLevel` ('public' | 'logged-in' | 'entitlement', optional): The access level required for the content.
1806
+ - `selector` (string): The CSS selector for the article element.
1807
+ - `element` (Element): The original DOM element for the article.
1808
+ - `hasAccess` (boolean, optional): Whether the user has access to the content. Set by `hasAccess()` method.
1809
+ - `entitlement` (Entitlement, optional): The entitlement object if access is granted via entitlement. Set by `hasAccess()` method.
1810
+
1811
+ ### Example Usage
1812
+
1813
+ ```js
1814
+ // Get article data by CSS selector
1815
+ const article = window.sesamy.content.get('article.premium-content');
1816
+ console.log('Article:', article);
1817
+
1818
+ // Get article data by DOM element
1819
+ const element = document.querySelector('.my-article');
1820
+ const article = window.sesamy.content.get(element);
1821
+ console.log('Article:', article);
1822
+ ```
1823
+
1824
+ #### `hasAccess(articleElementOrSelector: Element | string)`
1825
+
1826
+ Checks if the current user has access to the specified article. This method intelligently determines the access requirements based on the article's paywall configuration and decorates the article with access status and entitlement information.
1827
+
1828
+ ### Parameters
1829
+
1830
+ - `articleElementOrSelector` (Element | string): Either a DOM element or a CSS selector string identifying the article element.
1831
+
1832
+ ### Returns
1833
+
1834
+ - `Promise<Article>`: A promise that resolves to the article object decorated with access information:
1835
+ - `hasAccess` (boolean): `true` if the user has access, `false` otherwise
1836
+ - `entitlement` (Entitlement, optional): The entitlement object if access is granted via entitlement
1837
+ - All other article properties (title, url, etc.)
1838
+
1839
+ ### Behavior
1840
+
1841
+ 1. **Paywall-based Access**: If the article has a `paywallUrl`, the method fetches the paywall configuration to determine the access type based on the paywall template:
1842
+ - **Login Paywall** (`template: 'LOGIN'`): Sets `accessLevel` to `'logged-in'`, checks if the user is authenticated, and sets `hasAccess` accordingly.
1843
+ - **Entitlement Paywall** (`template: 'BOXES'`): Sets `accessLevel` to `'entitlement'`, checks for entitlement, and sets both `hasAccess` and `entitlement`.
1844
+
1845
+ 2. **Standard Entitlement Check**: If no `paywallUrl` is specified, the method uses the article's `url` and `pass` properties to check for entitlement access, setting both `hasAccess` and `entitlement`.
1846
+
1847
+ ### Example Usage
1848
+
1849
+ ```js
1850
+ // Check access for an article
1851
+ const article = await window.sesamy.content.hasAccess('.premium-article');
1852
+
1853
+ if (article.hasAccess) {
1854
+ console.log('User has access to:', article.title);
1855
+ if (article.entitlement) {
1856
+ console.log('Via entitlement:', article.entitlement.id);
1857
+ }
1858
+ // Show premium content
1859
+ } else {
1860
+ console.log('User does not have access');
1861
+ // Show paywall or login prompt
1862
+ }
1863
+
1864
+ // Use with async/await
1865
+ async function checkArticleAccess() {
1866
+ try {
1867
+ const article = await window.sesamy.content.hasAccess('article#main');
1868
+
1869
+ if (article.hasAccess) {
1870
+ // Unlock or display content
1871
+ console.log('Access granted to article:', article.url);
1872
+
1873
+ // Access entitlement details if available
1874
+ if (article.entitlement) {
1875
+ console.log('Entitlement type:', article.entitlement.type);
1876
+ console.log('Entitlement SKU:', article.entitlement.sku);
1877
+ }
1878
+ } else {
1879
+ // Redirect to paywall
1880
+ console.log('Access denied');
1881
+ }
1882
+ } catch (error) {
1883
+ console.error('Error checking access:', error);
1884
+ }
1885
+ }
1886
+ ```
1887
+
1888
+ #### `unlock(articleElementOrSelector: Element | string, lockedContentSelector?: string)`
1889
+
1890
+ Retrieves and unlocks premium content for an article that the user has entitlement access to.
1891
+
1892
+ ### Parameters
1893
+
1894
+ - `articleElementOrSelector` (Element | string): Either a DOM element or a CSS selector string identifying the article element.
1895
+ - `lockedContentSelector` (string, optional): A CSS selector for the specific locked content to retrieve. If not provided, uses the parent element of the article.
1896
+
1897
+ ### Returns
1898
+
1899
+ - `Promise<string>`: A promise that resolves to the unlocked HTML content.
1900
+
1901
+ ### Throws
1902
+
1903
+ - Error if the article element cannot be found.
1904
+ - Error if the article doesn't have a URL.
1905
+ - Error if the user doesn't have access to the content.
1906
+ - Error if the access token cannot be retrieved.
1907
+
1908
+ ### Example Usage
1909
+
1910
+ ```js
1911
+ // Unlock content and replace the locked element
1912
+ async function unlockArticle() {
1913
+ try {
1914
+ const unlockedContent = await window.sesamy.content.unlock('.premium-article');
1915
+
1916
+ // Replace the locked content with the unlocked content
1917
+ const article = document.querySelector('.premium-article');
1918
+ if (article && article.parentElement) {
1919
+ article.parentElement.innerHTML = unlockedContent;
1920
+ }
1921
+ } catch (error) {
1922
+ console.error('Failed to unlock content:', error);
1923
+ }
1924
+ }
1925
+
1926
+ // Unlock specific content within an article
1927
+ async function unlockSpecificContent() {
1928
+ const unlockedContent = await window.sesamy.content.unlock('article.premium', '.locked-section');
1929
+
1930
+ const lockedSection = document.querySelector('.locked-section');
1931
+ if (lockedSection) {
1932
+ lockedSection.innerHTML = unlockedContent;
1933
+ }
1934
+ }
1935
+ ```
1936
+
1735
1937
  ### Flags API
1736
1938
 
1737
1939
  The Flags API allows for client-side feature flag management. These flags are stored in the browser's localStorage and can be used to enable or disable features for specific users.
@@ -2636,3 +2838,55 @@ The Events API can be used for various scenarios where you need to communicate b
2636
2838
  4. **Analytics**: Emit events for key user interactions that other scripts might want to track.
2637
2839
 
2638
2840
  Events emitted through this API are also automatically tracked in analytics with the prefix `event:`.
2841
+
2842
+ ## Using the SDK for Link Generation
2843
+
2844
+ While `sesamy-js` provides `generateLink` which automatically signs links if the user is authenticated, you can also use the `@sesamy/sdk` package directly to generate unsigned links without requiring authentication. This is useful for generating shareable links or links for unauthenticated users.
2845
+
2846
+ ### SDK Link Generation Example
2847
+
2848
+ ```javascript
2849
+ import { client } from '@sesamy/sdk';
2850
+
2851
+ // Generate a checkout link (no authentication required)
2852
+ const checkoutUrl = client.checkout.generateLink(
2853
+ { apiUrl: 'https://api-proxy.example.com' },
2854
+ {
2855
+ items: [{ sku: 'premium-monthly' }],
2856
+ email: 'user@example.com',
2857
+ language: 'en',
2858
+ redirectUrl: 'https://example.com/success',
2859
+ requireAddress: true,
2860
+ giftMode: false,
2861
+ metaData: {
2862
+ campaignId: 'summer_2024',
2863
+ source: 'newsletter',
2864
+ },
2865
+ }
2866
+ );
2867
+
2868
+ // Generate account management links
2869
+ const accountUrl = client.links.generateAccountLink(
2870
+ { baseUrl: 'https://app.example.com', clientId: 'your-client-id' },
2871
+ { language: 'en', redirectUrl: 'https://example.com' }
2872
+ );
2873
+
2874
+ // Generate change payment link
2875
+ const changePaymentUrl = client.links.generateChangePaymentLink(
2876
+ { baseUrl: 'https://app.example.com', clientId: 'your-client-id' },
2877
+ { contractId: 'contract-123', language: 'en' }
2878
+ );
2879
+
2880
+ // Generate consume content link
2881
+ const consumeUrl = client.links.generateConsumeLink(
2882
+ { baseUrl: 'https://app.example.com', clientId: 'your-client-id' },
2883
+ { sku: 'product-123', language: 'en' }
2884
+ );
2885
+ ```
2886
+
2887
+ ### Differences Between sesamy-js generateLink and SDK Links
2888
+
2889
+ - **sesamy-js `generateLink`**: Includes authentication token in hash if user is authenticated, automatically includes tracking cookies and attribution data, supports link shortening via TTL
2890
+ - **SDK `links.*`**: Pure URL generation without authentication, useful for generating shareable links, links for unauthenticated users, or backend link generation
2891
+
2892
+ ````