@hellotext/hellotext 2.2.0 → 2.2.1

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.
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.Cookies = void 0;
7
7
  var _hellotext = _interopRequireDefault(require("../hellotext"));
8
+ var _page = require("./page");
8
9
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
9
10
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
10
11
  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
@@ -19,7 +20,15 @@ let Cookies = /*#__PURE__*/function () {
19
20
  key: "set",
20
21
  value: function set(name, value) {
21
22
  if (typeof document !== 'undefined') {
22
- document.cookie = `${name}=${value}; path=/;`;
23
+ const secure = window.location.protocol === 'https:' ? '; Secure' : '';
24
+ const domain = _page.Page.getRootDomain();
25
+ const maxAge = 10 * 365 * 24 * 60 * 60; // 10 years in seconds
26
+
27
+ if (domain) {
28
+ document.cookie = `${name}=${value}; path=/${secure}; domain=${domain}; max-age=${maxAge}; SameSite=Lax`;
29
+ } else {
30
+ document.cookie = `${name}=${value}; path=/${secure}; max-age=${maxAge}; SameSite=Lax`;
31
+ }
23
32
  }
24
33
  if (name === 'hello_session') {
25
34
  _hellotext.default.eventEmitter.dispatch('session-set', value);
@@ -4,6 +4,7 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
4
4
  function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
5
5
  function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
6
6
  import Hellotext from '../hellotext';
7
+ import { Page } from './page';
7
8
  var Cookies = /*#__PURE__*/function () {
8
9
  function Cookies() {
9
10
  _classCallCheck(this, Cookies);
@@ -12,7 +13,15 @@ var Cookies = /*#__PURE__*/function () {
12
13
  key: "set",
13
14
  value: function set(name, value) {
14
15
  if (typeof document !== 'undefined') {
15
- document.cookie = "".concat(name, "=").concat(value, "; path=/;");
16
+ var secure = window.location.protocol === 'https:' ? '; Secure' : '';
17
+ var domain = Page.getRootDomain();
18
+ var maxAge = 10 * 365 * 24 * 60 * 60; // 10 years in seconds
19
+
20
+ if (domain) {
21
+ document.cookie = "".concat(name, "=").concat(value, "; path=/").concat(secure, "; domain=").concat(domain, "; max-age=").concat(maxAge, "; SameSite=Lax");
22
+ } else {
23
+ document.cookie = "".concat(name, "=").concat(value, "; path=/").concat(secure, "; max-age=").concat(maxAge, "; SameSite=Lax");
24
+ }
16
25
  }
17
26
  if (name === 'hello_session') {
18
27
  Hellotext.eventEmitter.dispatch('session-set', value);
@@ -24,7 +24,7 @@ let Page = /*#__PURE__*/function () {
24
24
  _createClass(Page, [{
25
25
  key: "url",
26
26
  get: function () {
27
- return this._url || window.location.href;
27
+ return this._url !== null && this._url !== undefined ? this._url : window.location.href;
28
28
  }
29
29
 
30
30
  /**
@@ -80,6 +80,84 @@ let Page = /*#__PURE__*/function () {
80
80
  utm_params: this.utmParams
81
81
  };
82
82
  }
83
+
84
+ /**
85
+ * Get the current page domain (root domain for cookie sharing)
86
+ * @returns {string} The root domain with leading dot, or null if no valid URL
87
+ */
88
+ }, {
89
+ key: "domain",
90
+ get: function () {
91
+ try {
92
+ const url = this.url;
93
+ if (!url) {
94
+ return null;
95
+ }
96
+ const hostname = new URL(url).hostname;
97
+ return Page.getRootDomain(hostname);
98
+ } catch (e) {
99
+ return null;
100
+ }
101
+ }
102
+
103
+ /**
104
+ * Get the root domain from a hostname (static method, no instance needed)
105
+ * @param {string} hostname - The hostname to parse
106
+ * @returns {string} The root domain with leading dot, or null if invalid
107
+ */
108
+ }], [{
109
+ key: "getRootDomain",
110
+ value: function getRootDomain(hostname = null) {
111
+ try {
112
+ if (!hostname) {
113
+ var _window$location;
114
+ if (typeof window === 'undefined' || !((_window$location = window.location) !== null && _window$location !== void 0 && _window$location.hostname)) {
115
+ return null;
116
+ }
117
+ hostname = window.location.hostname;
118
+ }
119
+ const parts = hostname.split('.');
120
+
121
+ // Handle localhost or single-part domains
122
+ if (parts.length <= 1) {
123
+ return hostname;
124
+ }
125
+
126
+ // Handle e-commerce platform domains where store identifier must be preserved
127
+ // Examples:
128
+ // storename.myshopify.com -> .storename.myshopify.com
129
+ // storename.vtexcommercestable.com.br -> .storename.vtexcommercestable.com.br
130
+ // storename.wixsite.com -> .storename.wixsite.com
131
+ const platformSuffixes = ['myshopify.com', 'vtexcommercestable.com.br', 'myvtex.com', 'wixsite.com'];
132
+ for (const suffix of platformSuffixes) {
133
+ const suffixParts = suffix.split('.');
134
+ // Get the last N parts of the hostname (e.g., last 2 parts for 'myshopify.com')
135
+ const domainTail = parts.slice(-suffixParts.length).join('.');
136
+
137
+ // Check if the tail exactly matches the platform suffix
138
+ // and there are additional parts for the store identifier
139
+ if (domainTail === suffix && parts.length > suffixParts.length) {
140
+ // Include store identifier + platform suffix
141
+ // e.g., ['secure', 'mystore', 'myshopify', 'com'] -> '.mystore.myshopify.com'
142
+ return `.${parts.slice(-(suffixParts.length + 1)).join('.')}`;
143
+ }
144
+ }
145
+
146
+ // Simple heuristic: if TLD is 2 chars and second-level is short (<=3 chars),
147
+ // it's likely a multi-part TLD like .com.br, .co.uk
148
+ const tld = parts[parts.length - 1];
149
+ const secondLevel = parts[parts.length - 2];
150
+ if (parts.length > 2 && tld.length === 2 && secondLevel.length <= 3) {
151
+ // Multi-part TLD: take last 3 parts (e.g., store.com.br)
152
+ return `.${parts.slice(-3).join('.')}`;
153
+ }
154
+
155
+ // Regular TLD: take last 2 parts (e.g., example.com)
156
+ return `.${parts.slice(-2).join('.')}`;
157
+ } catch (e) {
158
+ return null;
159
+ }
160
+ }
83
161
  }]);
84
162
  return Page;
85
163
  }();
@@ -19,7 +19,7 @@ var Page = /*#__PURE__*/function () {
19
19
  _createClass(Page, [{
20
20
  key: "url",
21
21
  get: function get() {
22
- return this._url || window.location.href;
22
+ return this._url !== null && this._url !== undefined ? this._url : window.location.href;
23
23
  }
24
24
 
25
25
  /**
@@ -75,6 +75,85 @@ var Page = /*#__PURE__*/function () {
75
75
  utm_params: this.utmParams
76
76
  };
77
77
  }
78
+
79
+ /**
80
+ * Get the current page domain (root domain for cookie sharing)
81
+ * @returns {string} The root domain with leading dot, or null if no valid URL
82
+ */
83
+ }, {
84
+ key: "domain",
85
+ get: function get() {
86
+ try {
87
+ var url = this.url;
88
+ if (!url) {
89
+ return null;
90
+ }
91
+ var hostname = new URL(url).hostname;
92
+ return Page.getRootDomain(hostname);
93
+ } catch (e) {
94
+ return null;
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Get the root domain from a hostname (static method, no instance needed)
100
+ * @param {string} hostname - The hostname to parse
101
+ * @returns {string} The root domain with leading dot, or null if invalid
102
+ */
103
+ }], [{
104
+ key: "getRootDomain",
105
+ value: function getRootDomain() {
106
+ var hostname = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
107
+ try {
108
+ if (!hostname) {
109
+ var _window$location;
110
+ if (typeof window === 'undefined' || !((_window$location = window.location) !== null && _window$location !== void 0 && _window$location.hostname)) {
111
+ return null;
112
+ }
113
+ hostname = window.location.hostname;
114
+ }
115
+ var parts = hostname.split('.');
116
+
117
+ // Handle localhost or single-part domains
118
+ if (parts.length <= 1) {
119
+ return hostname;
120
+ }
121
+
122
+ // Handle e-commerce platform domains where store identifier must be preserved
123
+ // Examples:
124
+ // storename.myshopify.com -> .storename.myshopify.com
125
+ // storename.vtexcommercestable.com.br -> .storename.vtexcommercestable.com.br
126
+ // storename.wixsite.com -> .storename.wixsite.com
127
+ var platformSuffixes = ['myshopify.com', 'vtexcommercestable.com.br', 'myvtex.com', 'wixsite.com'];
128
+ for (var suffix of platformSuffixes) {
129
+ var suffixParts = suffix.split('.');
130
+ // Get the last N parts of the hostname (e.g., last 2 parts for 'myshopify.com')
131
+ var domainTail = parts.slice(-suffixParts.length).join('.');
132
+
133
+ // Check if the tail exactly matches the platform suffix
134
+ // and there are additional parts for the store identifier
135
+ if (domainTail === suffix && parts.length > suffixParts.length) {
136
+ // Include store identifier + platform suffix
137
+ // e.g., ['secure', 'mystore', 'myshopify', 'com'] -> '.mystore.myshopify.com'
138
+ return ".".concat(parts.slice(-(suffixParts.length + 1)).join('.'));
139
+ }
140
+ }
141
+
142
+ // Simple heuristic: if TLD is 2 chars and second-level is short (<=3 chars),
143
+ // it's likely a multi-part TLD like .com.br, .co.uk
144
+ var tld = parts[parts.length - 1];
145
+ var secondLevel = parts[parts.length - 2];
146
+ if (parts.length > 2 && tld.length === 2 && secondLevel.length <= 3) {
147
+ // Multi-part TLD: take last 3 parts (e.g., store.com.br)
148
+ return ".".concat(parts.slice(-3).join('.'));
149
+ }
150
+
151
+ // Regular TLD: take last 2 parts (e.g., example.com)
152
+ return ".".concat(parts.slice(-2).join('.'));
153
+ } catch (e) {
154
+ return null;
155
+ }
156
+ }
78
157
  }]);
79
158
  return Page;
80
159
  }();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hellotext/hellotext",
3
- "version": "2.2.0",
3
+ "version": "2.2.1",
4
4
  "description": "Hellotext JavaScript Client",
5
5
  "source": "src/index.js",
6
6
  "main": "lib/index.cjs",
@@ -1,9 +1,18 @@
1
1
  import Hellotext from '../hellotext'
2
+ import { Page } from './page'
2
3
 
3
4
  class Cookies {
4
5
  static set(name, value) {
5
6
  if (typeof document !== 'undefined') {
6
- document.cookie = `${name}=${value}; path=/;`
7
+ const secure = window.location.protocol === 'https:' ? '; Secure' : ''
8
+ const domain = Page.getRootDomain()
9
+ const maxAge = 10 * 365 * 24 * 60 * 60 // 10 years in seconds
10
+
11
+ if (domain) {
12
+ document.cookie = `${name}=${value}; path=/${secure}; domain=${domain}; max-age=${maxAge}; SameSite=Lax`
13
+ } else {
14
+ document.cookie = `${name}=${value}; path=/${secure}; max-age=${maxAge}; SameSite=Lax`
15
+ }
7
16
  }
8
17
 
9
18
  if (name === 'hello_session') {
@@ -11,7 +11,7 @@ class Page {
11
11
  * @returns {string} The page URL
12
12
  */
13
13
  get url() {
14
- return this._url || window.location.href
14
+ return this._url !== null && this._url !== undefined ? this._url : window.location.href
15
15
  }
16
16
 
17
17
  /**
@@ -60,6 +60,88 @@ class Page {
60
60
  utm_params: this.utmParams,
61
61
  }
62
62
  }
63
+
64
+ /**
65
+ * Get the current page domain (root domain for cookie sharing)
66
+ * @returns {string} The root domain with leading dot, or null if no valid URL
67
+ */
68
+ get domain() {
69
+ try {
70
+ const url = this.url
71
+ if (!url) {
72
+ return null
73
+ }
74
+
75
+ const hostname = new URL(url).hostname
76
+ return Page.getRootDomain(hostname)
77
+ } catch (e) {
78
+ return null
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Get the root domain from a hostname (static method, no instance needed)
84
+ * @param {string} hostname - The hostname to parse
85
+ * @returns {string} The root domain with leading dot, or null if invalid
86
+ */
87
+ static getRootDomain(hostname = null) {
88
+ try {
89
+ if (!hostname) {
90
+ if (typeof window === 'undefined' || !window.location?.hostname) {
91
+ return null
92
+ }
93
+ hostname = window.location.hostname
94
+ }
95
+
96
+ const parts = hostname.split('.')
97
+
98
+ // Handle localhost or single-part domains
99
+ if (parts.length <= 1) {
100
+ return hostname
101
+ }
102
+
103
+ // Handle e-commerce platform domains where store identifier must be preserved
104
+ // Examples:
105
+ // storename.myshopify.com -> .storename.myshopify.com
106
+ // storename.vtexcommercestable.com.br -> .storename.vtexcommercestable.com.br
107
+ // storename.wixsite.com -> .storename.wixsite.com
108
+ const platformSuffixes = [
109
+ 'myshopify.com',
110
+ 'vtexcommercestable.com.br',
111
+ 'myvtex.com',
112
+ 'wixsite.com',
113
+ ]
114
+
115
+ for (const suffix of platformSuffixes) {
116
+ const suffixParts = suffix.split('.')
117
+ // Get the last N parts of the hostname (e.g., last 2 parts for 'myshopify.com')
118
+ const domainTail = parts.slice(-suffixParts.length).join('.')
119
+
120
+ // Check if the tail exactly matches the platform suffix
121
+ // and there are additional parts for the store identifier
122
+ if (domainTail === suffix && parts.length > suffixParts.length) {
123
+ // Include store identifier + platform suffix
124
+ // e.g., ['secure', 'mystore', 'myshopify', 'com'] -> '.mystore.myshopify.com'
125
+ return `.${parts.slice(-(suffixParts.length + 1)).join('.')}`
126
+ }
127
+ }
128
+
129
+ // Simple heuristic: if TLD is 2 chars and second-level is short (<=3 chars),
130
+ // it's likely a multi-part TLD like .com.br, .co.uk
131
+ const tld = parts[parts.length - 1]
132
+ const secondLevel = parts[parts.length - 2]
133
+
134
+ if (parts.length > 2 && tld.length === 2 && secondLevel.length <= 3) {
135
+ // Multi-part TLD: take last 3 parts (e.g., store.com.br)
136
+ return `.${parts.slice(-3).join('.')}`
137
+ }
138
+
139
+ // Regular TLD: take last 2 parts (e.g., example.com)
140
+ return `.${parts.slice(-2).join('.')}`
141
+ } catch (e) {
142
+ return null
143
+ }
144
+ }
63
145
  }
64
146
 
65
147
  export { Page }