@sesamy/sesamy-js 1.3.1 → 1.3.3

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.
Files changed (56) hide show
  1. package/dist/index.d.ts +108 -0
  2. package/dist/sesamy-js.cjs +6 -0
  3. package/dist/sesamy-js.iife.js +6 -0
  4. package/dist/sesamy-js.mjs +3082 -0
  5. package/package.json +4 -2
  6. package/.env +0 -2
  7. package/.env.production +0 -2
  8. package/.eslintignore +0 -4
  9. package/.eslintrc +0 -18
  10. package/.github/workflows/release.yml +0 -23
  11. package/.nvmrc +0 -1
  12. package/.prettierignore +0 -4
  13. package/.prettierrc +0 -5
  14. package/CHANGELOG.md +0 -132
  15. package/README.md +0 -69
  16. package/article.html +0 -65
  17. package/contracts.html +0 -23
  18. package/dts-bundle-generator.config.ts +0 -11
  19. package/entitlements.html +0 -23
  20. package/index.html +0 -24
  21. package/renovate.json +0 -4
  22. package/src/SesamyContracts.ts +0 -86
  23. package/src/SesamyEntitlements.ts +0 -85
  24. package/src/app.ts +0 -101
  25. package/src/constants.ts +0 -2
  26. package/src/controllers/index.ts +0 -1
  27. package/src/controllers/paywall.ts +0 -14
  28. package/src/entitlementsStyle.css +0 -147
  29. package/src/events/ready.ts +0 -12
  30. package/src/index.ts +0 -36
  31. package/src/javascript-api.ts +0 -84
  32. package/src/services/analytics/element-tracker.ts +0 -117
  33. package/src/services/analytics/index.ts +0 -234
  34. package/src/services/analytics/listeners/index.ts +0 -2
  35. package/src/services/analytics/listeners/route.ts +0 -9
  36. package/src/services/analytics/listeners/scroll.ts +0 -62
  37. package/src/services/analytics/session-id.ts +0 -11
  38. package/src/services/analytics/types/analytics-activity-utils.d.ts +0 -54
  39. package/src/services/analytics/types/analytics-router-utils.d.ts +0 -7
  40. package/src/services/analytics/types/analytics-scroll-utils.d.ts +0 -4
  41. package/src/services/analytics/types/track-event.ts +0 -70
  42. package/src/services/auth/index.ts +0 -74
  43. package/src/services/sesamy/index.ts +0 -160
  44. package/src/state.ts +0 -3
  45. package/src/style.css +0 -99
  46. package/src/types/Bills.ts +0 -12
  47. package/src/types/Config.ts +0 -11
  48. package/src/types/Contracts.ts +0 -12
  49. package/src/types/Entitlement.ts +0 -9
  50. package/src/types/Events.ts +0 -6
  51. package/src/types/Tag.ts +0 -16
  52. package/src/vite-env.d.ts +0 -1
  53. package/tsconfig.json +0 -23
  54. package/vite.config.ts +0 -43
  55. package/vite.dev.config.ts +0 -14
  56. /package/{public → dist}/sesamy.png +0 -0
package/src/app.ts DELETED
@@ -1,101 +0,0 @@
1
- import { User } from '@auth0/auth0-spa-js';
2
- import './style.css';
3
- import sesamyLogo from '/sesamy.png';
4
- import { Events } from './types/Events';
5
-
6
- /**
7
- * This class is only used for rendering the UI and not shipped in the bundle
8
- */
9
-
10
- class SesamyAppComponent extends HTMLElement {
11
- private user: User | undefined;
12
-
13
- constructor() {
14
- super();
15
- }
16
-
17
- async _handleProfile() {
18
- this.user = await window.sesamy.auth.getUser();
19
- this.render();
20
- }
21
-
22
- async connectedCallback() {
23
- this.setupEventListeners();
24
-
25
- if (!window.sesamy) {
26
- window.addEventListener(Events.READY, () => this._handleProfile());
27
- return;
28
- }
29
-
30
- this._handleProfile();
31
- }
32
-
33
- render() {
34
- this.innerHTML = `
35
- <div>
36
- <a href="https://docs.sesamy.com" target="_blank">
37
- <img src="${sesamyLogo}" class="logo" alt="Vite logo" />
38
- </a>
39
- <h1>Sesamy JS</h1>
40
- <p class="read-the-docs">
41
- Click on the Sesamy logo to learn more
42
- </p>
43
- ${this.user ? this.renderUserProfile() : this.renderLoginButton()}
44
- </div>
45
- `;
46
- }
47
-
48
- private renderLoginButton(): string {
49
- return '<button part="login-btn" class="login auth-visible" id="login-btn"> Login </button>';
50
- }
51
-
52
- private renderUserProfile(): string {
53
- return `<div class="user" part="user">
54
- <a href="/profile" part="user-link">
55
- ${
56
- this.user?.picture
57
- ? ` <img
58
- class="big"
59
- part="user-img img-big"
60
- src=${this.user.picture}
61
- alt=${this.user.name || 'User avatar'}
62
- />`
63
- : `<div part="avatar avatar-big" class="avatar big"> Placeholder </div>`
64
- }
65
- <h2 class="user-name">${this.user?.name || 'User Name'}</h2>
66
- </a>
67
-
68
- <div class="logout-wrap">
69
- <a href="#" class="logout-btn" id="logout-btn"> Logout </a>
70
- </div>
71
- <div>
72
- <a href="/entitlements.html">
73
- View Entitlements
74
- </a>
75
- </div>
76
- <div>
77
- <a href="/contracts.html">
78
- View Contracts
79
- </a>
80
- </div>
81
- </div>`;
82
- }
83
-
84
- private setupEventListeners() {
85
- this.addEventListener('click', event => {
86
- const clickedElement = event.target as Element;
87
- const logoutButton = clickedElement.closest('#logout-btn');
88
- const loginButton = clickedElement.closest('#login-btn');
89
-
90
- if (logoutButton) {
91
- window.sesamy.auth.logout();
92
- }
93
-
94
- if (loginButton) {
95
- window.sesamy.auth.loginWithRedirect();
96
- }
97
- });
98
- }
99
- }
100
-
101
- customElements.define('sesamy-app', SesamyAppComponent);
package/src/constants.ts DELETED
@@ -1,2 +0,0 @@
1
- export const BASE_URL_DOMAIN = import.meta.env.VITE_BASE_URL_DOMAIN;
2
- export const ANALYTICS_BASE_URL = import.meta.env.VITE_ANALYTICS_BASE_URL;
@@ -1 +0,0 @@
1
- // Will be stuff in here later
@@ -1,14 +0,0 @@
1
- import { triggerEvent } from '../events/ready';
2
- import { accessArticle as accessArticleService } from '../services/sesamy';
3
- import { Events } from '../types/Events';
4
-
5
- export async function accessArticle(articleId: string) {
6
- // Call the API to access the article
7
- const response = await accessArticleService({ articleId });
8
-
9
- if (response.status !== 'ok') {
10
- triggerEvent(Events.SOFT_PAYWALL, {});
11
- }
12
-
13
- return response;
14
- }
@@ -1,147 +0,0 @@
1
- .container {
2
- background-color: var(--background, transparent);
3
- font-family: var(--font-family, 'Helvetica');
4
- }
5
- ul {
6
- list-style-type: none;
7
- display: flex;
8
- flex-wrap: wrap;
9
- gap: var(--items-gap, 16px);
10
- margin-top: 0;
11
- padding: 0;
12
- }
13
- ul > * {
14
- flex-grow: 1;
15
- flex-shrink: 1;
16
- flex-basis: var(--item-width, 300px);
17
- }
18
- button {
19
- appearance: none;
20
- display: inline-block;
21
- text-decoration: none;
22
- text-align: left;
23
- background: none;
24
- border: none;
25
- width: 100%;
26
- display: flex;
27
- align-items: stretch;
28
- text-decoration: none;
29
- cursor: pointer;
30
- }
31
- button::-moz-focus-inner {
32
- border: 0;
33
- padding: 0;
34
- }
35
- button > * {
36
- flex-shrink: 0;
37
- }
38
- .image-container {
39
- padding-bottom: 14px;
40
- }
41
- img {
42
- width: var(--image-size, 95px);
43
- height: var(--image-size, 95px);
44
- border-radius: var(--image-border-radius, 12px);
45
- object-fit: cover;
46
- overflow: hidden;
47
- display: -webkit-box;
48
- -webkit-line-clamp: 2;
49
- -webkit-box-orient: vertical;
50
- }
51
- .details {
52
- margin-left: var(--details-margin-left, 8px);
53
- border-bottom-color: var(--divider-color, #70707023);
54
- border-bottom-width: var(--divider-width, 1px);
55
- padding-bottom: 14px;
56
- border-bottom-style: solid;
57
- display: flex;
58
- flex-direction: column;
59
- justify-content: var(--details-justify-content, space-between);
60
- flex: 1;
61
- }
62
- p {
63
- font-weight: normal;
64
- margin: 0;
65
- text-overflow: ellipsis;
66
- overflow: hidden;
67
- display: -webkit-box;
68
- -webkit-box-orient: vertical;
69
- }
70
- .title {
71
- color: var(--title-color, #131313);
72
- font-size: 15px;
73
- -webkit-line-clamp: 1;
74
- }
75
- .summary {
76
- color: var(--summary-color, #22222260);
77
- font-size: 12px;
78
- -webkit-line-clamp: 2;
79
- }
80
- span {
81
- overflow: hidden;
82
- text-overflow: ellipsis;
83
- display: -webkit-box;
84
- -webkit-line-clamp: 2;
85
- -webkit-box-orient: vertical;
86
- }
87
- span.type {
88
- color: var(--type-color, #22222270);
89
- text-transform: uppercase;
90
- font-size: var(--type-font-size, 11px);
91
- font-weight: medium;
92
- margin-top: 4px;
93
- font-family: var(--type-font-family, var(--font-family, 'Helvetica'));
94
- }
95
- span.date {
96
- color: var(--date-color, #22222260);
97
- font-size: var(--date-font-size, 12px);
98
- font-weight: normal;
99
- font-family: var(--date-font-family, var(--font-family, 'Helvetica'));
100
- }
101
- .modal {
102
- display: none;
103
- position: fixed;
104
- z-index: var(--modal-zindex, 100);
105
- padding-top: 20px;
106
- left: 0;
107
- top: 0;
108
- width: 100%;
109
- height: 100%;
110
- overflow: auto;
111
- }
112
- .modal-blackout {
113
- position: fixed;
114
- top: 0;
115
- left: 0;
116
- width: 100%;
117
- height: 100%;
118
- background-color: rgba(0, 0, 0, 0.4);
119
- }
120
-
121
- .modal-container {
122
- position: relative;
123
- background-color: white;
124
- margin: auto;
125
- padding: 0;
126
- max-width: 500px;
127
- -webkit-animation-name: animatetop;
128
- -webkit-animation-duration: 0.4s;
129
- animation-name: animatetop;
130
- animation-duration: 0.4s;
131
- }
132
- .close-container {
133
- position: absolute;
134
- right: 16px;
135
- top: 16px;
136
- cursor: pointer;
137
- z-index: 900;
138
- width: auto;
139
- }
140
- @media only screen and (max-width: 768px) {
141
- .modal {
142
- padding: 10px 0;
143
- }
144
- .modal-container {
145
- max-width: 100%;
146
- }
147
- }
@@ -1,12 +0,0 @@
1
- import { Events } from '../types/Events';
2
-
3
- // TODO: Separate the event into a function per event so they can be typed
4
- export function triggerEvent(eventType: Events, payload: any) {
5
- const customEvent = new CustomEvent(eventType, {
6
- detail: payload,
7
- bubbles: true,
8
- composed: true,
9
- });
10
-
11
- dispatchEvent(customEvent);
12
- }
package/src/index.ts DELETED
@@ -1,36 +0,0 @@
1
- import { triggerEvent } from './events/ready';
2
- import { registerAPI } from './javascript-api';
3
- import { Config } from './types/Config';
4
- import { init as initAuth } from './services/auth';
5
- import { initAnalytics } from './services/analytics';
6
- import { Events } from './types/Events';
7
-
8
- export async function init(config: Config) {
9
- initAnalytics({
10
- clientId: config.clientId,
11
- // The default client id can be overridden by the config
12
- ...config.analytics,
13
- });
14
-
15
- // Auth needs to be initated after the analytics so that the auth events can be tracked
16
- await initAuth(config);
17
-
18
- const api = registerAPI(config.namespace);
19
-
20
- triggerEvent(Events.READY, {});
21
-
22
- return api;
23
- }
24
-
25
- // This is for checking if the script is being loaded in the browser
26
- if (typeof document !== 'undefined') {
27
- const configElement = document.getElementById('sesamy-js');
28
- if (configElement?.textContent) {
29
- try {
30
- const config = JSON.parse(configElement.textContent);
31
- init(config);
32
- } catch (err) {
33
- console.error('Failed to parse config', err);
34
- }
35
- }
36
- }
@@ -1,84 +0,0 @@
1
- import { loginWithRedirect, getUser, isAuthenticated, logout } from './services/auth';
2
- import {
3
- getEntitlement,
4
- getEntitlements,
5
- getContract,
6
- getContracts,
7
- getBill,
8
- getBills,
9
- getTags,
10
- setTag,
11
- pushTag,
12
- } from './services/sesamy';
13
- import { accessArticle } from './controllers/paywall';
14
- import { version } from '../package.json';
15
-
16
- function getVersion() {
17
- return version;
18
- }
19
-
20
- export interface SesamyApi {
21
- articles: {
22
- access: typeof accessArticle;
23
- };
24
- auth: {
25
- getUser: typeof getUser;
26
- isAuthenticated: typeof isAuthenticated;
27
- loginWithRedirect: typeof loginWithRedirect;
28
- logout: typeof logout;
29
- };
30
- tags: {
31
- list: typeof getTags;
32
- set: typeof setTag;
33
- push: typeof pushTag;
34
- };
35
- getEntitlement: typeof getEntitlement;
36
- getEntitlements: typeof getEntitlements;
37
- getContract: typeof getContract;
38
- getContracts: typeof getContracts;
39
- getBill: typeof getBill;
40
- getBills: typeof getBills;
41
- getVersion: typeof getVersion;
42
- }
43
-
44
- interface SesamyWindow {
45
- sesamy: SesamyApi;
46
- }
47
-
48
- // Extend the global Window type with your SesamyWindow interface
49
- declare global {
50
- interface Window extends SesamyWindow {}
51
- }
52
-
53
- export function registerAPI(namespace: string | null = 'sesamy') {
54
- const api: SesamyApi = {
55
- auth: {
56
- getUser,
57
- isAuthenticated,
58
- loginWithRedirect,
59
- logout,
60
- },
61
- articles: {
62
- access: accessArticle,
63
- },
64
- tags: {
65
- list: getTags,
66
- set: setTag,
67
- push: pushTag,
68
- },
69
- getEntitlement,
70
- getEntitlements,
71
- getContract,
72
- getContracts,
73
- getBill,
74
- getBills,
75
- getVersion,
76
- };
77
-
78
- if (namespace !== null) {
79
- // This makes it possible to use a different namespace
80
- (window as any)[namespace] = api;
81
- }
82
-
83
- return api;
84
- }
@@ -1,117 +0,0 @@
1
- /// <reference path="./types/analytics-activity-utils.d.ts" />
2
- import { onUserActivity } from '@analytics/activity-utils';
3
-
4
- // IDLE_TIME is in ms
5
- const timeout = 5000;
6
-
7
- export interface ElementTrackerOptions {
8
- element: HTMLElement;
9
- viewCallback?: () => void;
10
- activeDurationCallback?: (duration: number) => void;
11
- idleDurationCallback?: (duration: number) => void;
12
- }
13
-
14
- export default class ElementTracker {
15
- element: HTMLElement;
16
-
17
- isInViewport = false;
18
-
19
- isAwake = false;
20
-
21
- isFlushing?: boolean;
22
-
23
- observer: IntersectionObserver;
24
-
25
- lastEventAt = Date.now();
26
-
27
- registeredView = false;
28
-
29
- viewCallback?: () => void;
30
-
31
- activeDurationCallback?: (duration: number, flushing?: boolean) => void;
32
-
33
- idleDurationCallback?: (duration: number, flushing?: boolean) => void;
34
-
35
- constructor(options: ElementTrackerOptions) {
36
- this.element = options.element;
37
- // We NEED to have callbacks here rather than using events as events will be lost when the browser is unloading
38
- this.viewCallback = options.viewCallback;
39
- this.activeDurationCallback = options.activeDurationCallback;
40
- this.idleDurationCallback = options.idleDurationCallback;
41
-
42
- // Setup the interaction observer
43
- this.observer = new IntersectionObserver(
44
- entries => {
45
- // I guess there will only be one entry? Verify?
46
- entries.forEach(entry => {
47
- this.handleInViewPort(entry.isIntersecting);
48
- });
49
- },
50
- {
51
- threshold: 0,
52
- },
53
- );
54
- this.observer.observe(this.element);
55
-
56
- // Setup the active/idle
57
- onUserActivity({
58
- onIdle: (elapsedTime: number) => this.handleAwake(false, elapsedTime),
59
- onWakeUp: (elapsedTime: number) => this.handleAwake(true, elapsedTime),
60
- timeout,
61
- });
62
- }
63
-
64
- /**
65
- * Flush the awake timer in case the page is unloading
66
- */
67
- flush() {
68
- this.isFlushing = true;
69
- this.handleAwake(!this.isAwake, Math.round((Date.now() - this.lastEventAt) / 1000));
70
- }
71
-
72
- handleInViewPort(isInViewport: boolean) {
73
- if (isInViewport) {
74
- // A view envent only occurs if the element is active.
75
- this.isAwake = true;
76
- this.trackInViewport();
77
- } else {
78
- // An article outside the viewport is not active
79
- this.handleAwake(false, Math.round((Date.now() - this.lastEventAt) / 1000));
80
- }
81
-
82
- this.isInViewport = isInViewport;
83
- }
84
-
85
- handleAwake(isAwake: boolean, elapsedTime: number) {
86
- // Store the current awake state
87
- this.isAwake = isAwake;
88
- this.lastEventAt = isAwake ? Date.now() - elapsedTime * timeout : Date.now();
89
-
90
- if (!this.isInViewport) {
91
- return;
92
- }
93
- this.trackAwake(isAwake, elapsedTime);
94
- }
95
-
96
- trackAwake(awake: boolean, elapsedTime: number) {
97
- if (!awake && this.activeDurationCallback) {
98
- this.activeDurationCallback(elapsedTime, this.isFlushing);
99
- }
100
-
101
- if (awake && this.idleDurationCallback) {
102
- this.idleDurationCallback(elapsedTime, this.isFlushing);
103
- }
104
- }
105
-
106
- trackInViewport() {
107
- if (this.registeredView) {
108
- return;
109
- }
110
-
111
- this.registeredView = true;
112
-
113
- if (this.viewCallback) {
114
- this.viewCallback();
115
- }
116
- }
117
- }