@usertour/helpers 0.0.9 → 0.0.11

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.
@@ -1,318 +0,0 @@
1
- // src/finderx.ts
2
- import { finder as finderLib } from "@medv/finder";
3
- var finderAttrs = [
4
- "data-for",
5
- "data-id",
6
- "data-testid",
7
- "data-test-id",
8
- "for",
9
- "id",
10
- "name",
11
- "placeholder",
12
- "role"
13
- ];
14
- var defaultConfig = {
15
- idName: () => false,
16
- className: () => false,
17
- tagName: () => false,
18
- attr: () => false,
19
- seedMinLength: 1,
20
- optimizedMinLength: 2,
21
- threshold: 1e3,
22
- maxNumberOfTries: 1e4
23
- };
24
- var finderConfigs = [
25
- {
26
- ...defaultConfig,
27
- tagName: () => true
28
- },
29
- {
30
- ...defaultConfig,
31
- idName: () => true
32
- },
33
- {
34
- ...defaultConfig,
35
- tagName: () => true,
36
- attr: (name) => finderAttrs.includes(name)
37
- },
38
- {
39
- ...defaultConfig,
40
- className: () => true,
41
- attr: (name) => finderAttrs.includes(name)
42
- },
43
- {
44
- ...defaultConfig,
45
- tagName: () => true,
46
- idName: () => true,
47
- className: () => true,
48
- attr: () => false
49
- },
50
- {
51
- ...defaultConfig,
52
- tagName: () => true,
53
- idName: () => true,
54
- className: () => true,
55
- attr: (name) => finderAttrs.includes(name)
56
- }
57
- ];
58
- function getMaxDepth(node) {
59
- if (node.parentNode) {
60
- return getMaxDepth(node.parentNode);
61
- }
62
- return node.depth;
63
- }
64
- function queryNodeListBySelectors(selectors, rootDocument, removeRepeat = true) {
65
- const nodes = [];
66
- if (!selectors) {
67
- return nodes;
68
- }
69
- for (const s of selectors) {
70
- const els = rootDocument.querySelectorAll(s.replace(/\\\\/g, "\\"));
71
- if (els && els.length > 0) {
72
- nodes.push(...Array.from(els));
73
- }
74
- }
75
- return removeRepeat ? [...new Set(nodes)] : nodes;
76
- }
77
- function findMostRecurringNode(nodes) {
78
- const m = /* @__PURE__ */ new Map();
79
- let finalNode = nodes[0];
80
- let count = 0;
81
- for (const node of nodes) {
82
- const i = m.get(node) ? m.get(node) + 1 : 1;
83
- m.set(node, i);
84
- }
85
- m.forEach((value, key) => {
86
- if (value > count) {
87
- count = value;
88
- finalNode = key;
89
- }
90
- });
91
- return finalNode;
92
- }
93
- function compareParentNode(node, el, rootDocument, isCompareSibings = false) {
94
- let nodeParentNode = node.parentNode;
95
- let elParentElement = el.parentElement;
96
- const maxDepth = getMaxDepth(node);
97
- const xresult = {
98
- maxDepth,
99
- failedDepth: 0,
100
- success: true
101
- };
102
- while (nodeParentNode && elParentElement) {
103
- if (elParentElement === rootDocument) {
104
- break;
105
- }
106
- if (elParentElement === document.body || elParentElement === document.documentElement || elParentElement.parentElement === document.body) {
107
- break;
108
- }
109
- const parentNodes = queryNodeListBySelectors(nodeParentNode.selectors, rootDocument);
110
- const isMatchSibings = isCompareSibings ? compareSibingsNode(nodeParentNode, elParentElement, rootDocument) : true;
111
- if (!parentNodes || parentNodes.length === 0 || !parentNodes.includes(elParentElement) || !isMatchSibings) {
112
- xresult.failedDepth = nodeParentNode.depth;
113
- xresult.success = false;
114
- }
115
- nodeParentNode = nodeParentNode.parentNode;
116
- elParentElement = elParentElement.parentElement;
117
- }
118
- return xresult;
119
- }
120
- function compareSibingsNode(node, el, rootDocument) {
121
- let isMatchNext = true;
122
- let isMatchPrevious = true;
123
- const { previousElementSelectors, nextElementSelectors } = node;
124
- if (nextElementSelectors && nextElementSelectors.length > 0) {
125
- const nextElementSiblings = queryNodeListBySelectors(nextElementSelectors, rootDocument);
126
- isMatchNext = el.nextElementSibling && nextElementSiblings.includes(el.nextElementSibling);
127
- }
128
- if (previousElementSelectors && previousElementSelectors.length > 0) {
129
- const previousElementSiblings = queryNodeListBySelectors(
130
- previousElementSelectors,
131
- rootDocument
132
- );
133
- isMatchPrevious = el.previousElementSibling && previousElementSiblings.includes(el.previousElementSibling);
134
- }
135
- return isMatchNext && isMatchPrevious;
136
- }
137
- function queryElementSelectors(input) {
138
- const classes = Array.from(input.classList);
139
- const selectors = [];
140
- const configs = [...finderConfigs];
141
- for (const className of classes) {
142
- configs.push({
143
- ...defaultConfig,
144
- className: (name) => {
145
- if (classes.filter((cn) => cn !== className).includes(name)) {
146
- return false;
147
- }
148
- return true;
149
- }
150
- });
151
- }
152
- try {
153
- for (const cfg of configs) {
154
- selectors.push(finder(input, cfg));
155
- }
156
- } catch (_) {
157
- return selectors;
158
- }
159
- return [...new Set(selectors)];
160
- }
161
- function parseSelectorsTree(input, parentNode, depth = 0) {
162
- const selectors = queryElementSelectors(input);
163
- if (selectors.length === 0) {
164
- return parentNode;
165
- }
166
- const currentNode = {
167
- previousElementSelectors: [],
168
- nextElementSelectors: [],
169
- selectors,
170
- depth
171
- };
172
- if (input.previousElementSibling) {
173
- currentNode.previousElementSelectors = queryElementSelectors(input.previousElementSibling);
174
- }
175
- if (input.nextElementSibling) {
176
- currentNode.nextElementSelectors = queryElementSelectors(input.nextElementSibling);
177
- }
178
- if (parentNode === null) {
179
- if (input.parentElement) {
180
- parseSelectorsTree(input.parentElement, currentNode, depth + 1);
181
- }
182
- return currentNode;
183
- }
184
- parentNode.parentNode = currentNode;
185
- if (input.parentElement) {
186
- parseSelectorsTree(input.parentElement, currentNode, depth + 1);
187
- }
188
- return parentNode;
189
- }
190
- function finderMostPrecisionElement(elements, node, rootDocument, precision) {
191
- const successEls = [];
192
- let failedData = {
193
- el: null,
194
- failedDepth: 0,
195
- maxDepth: 0
196
- };
197
- for (const el of elements) {
198
- const { success, failedDepth, maxDepth } = compareParentNode(node, el, rootDocument);
199
- if (success) {
200
- successEls.push(el);
201
- } else if (!failedData.el || failedDepth > failedData.failedDepth) {
202
- failedData = { el, failedDepth, maxDepth };
203
- }
204
- }
205
- if (successEls.length === 1) {
206
- return successEls[0];
207
- }
208
- if (successEls.length > 1) {
209
- let tempEl = successEls[0];
210
- let tempFailedDepth = 0;
211
- for (const el of successEls) {
212
- const { success, failedDepth } = compareParentNode(node, el, rootDocument, true);
213
- if (success) {
214
- return el;
215
- }
216
- if (failedDepth > tempFailedDepth) {
217
- tempFailedDepth = failedDepth;
218
- tempEl = el;
219
- }
220
- }
221
- return tempEl;
222
- }
223
- if (failedData.el) {
224
- const { failedDepth, maxDepth, el } = failedData;
225
- const rate = (failedDepth - 1) / maxDepth * 10;
226
- if (rate >= precision) {
227
- return el;
228
- }
229
- }
230
- return null;
231
- }
232
- function finder(input, options) {
233
- return finderLib(input, options);
234
- }
235
- function parserX(input) {
236
- return parseSelectorsTree(input, null);
237
- }
238
- function parserV2(element) {
239
- var _a;
240
- const content = (_a = element.innerText) != null ? _a : "";
241
- const selectors = parseSelectorsTree(element, null);
242
- const selectorsList = queryElementSelectors(element);
243
- return { content, selectors, selectorsList };
244
- }
245
- function finderV2(target, root) {
246
- const {
247
- selectors,
248
- content = "",
249
- sequence = 0,
250
- precision = "strict",
251
- isDynamicContent = false,
252
- customSelector = "",
253
- type = "auto"
254
- } = target;
255
- if (type === "auto") {
256
- const mapping = {
257
- looser: 1,
258
- loose: 3,
259
- loosest: 5,
260
- strict: 7,
261
- stricter: 8,
262
- strictest: 10
263
- };
264
- const el = finderX(selectors, root, mapping[precision]);
265
- if (el) {
266
- if (isDynamicContent && content && el.innerText !== content) {
267
- return null;
268
- }
269
- return el;
270
- }
271
- } else {
272
- const sequenceMapping = {
273
- "1st": 0,
274
- "2st": 1,
275
- "3st": 2,
276
- "4st": 3,
277
- "5st": 4
278
- };
279
- if (customSelector) {
280
- const selector = customSelector.replace(/\\\\/g, "\\");
281
- const els = root.querySelectorAll(selector);
282
- if (els.length > 0) {
283
- const el = els[sequenceMapping[sequence]] || els[0];
284
- if (content && el.innerText.trim() !== content) {
285
- return null;
286
- }
287
- return el;
288
- }
289
- }
290
- }
291
- return null;
292
- }
293
- function finderX(node, root, precision = 10) {
294
- if (!node || node.selectors.length === 0) {
295
- return null;
296
- }
297
- const rootDocument = root || document;
298
- const elements = [];
299
- const nodeList = queryNodeListBySelectors(node.selectors, rootDocument, false);
300
- if (!nodeList || nodeList.length === 0) {
301
- return null;
302
- }
303
- if ([...new Set(nodeList)].length !== nodeList.length) {
304
- const el = findMostRecurringNode(nodeList);
305
- elements.push(el);
306
- } else {
307
- elements.push(...nodeList);
308
- }
309
- return finderMostPrecisionElement(elements, node, rootDocument, precision);
310
- }
311
-
312
- export {
313
- finder,
314
- parserX,
315
- parserV2,
316
- finderV2,
317
- finderX
318
- };
@@ -1,112 +0,0 @@
1
- import {
2
- __publicField
3
- } from "./chunk-XEO3YXBM.js";
4
-
5
- // src/jwt-license-signer.ts
6
- import * as fs from "fs";
7
- import * as path from "path";
8
- import jwt from "jsonwebtoken";
9
- var JWTLicenseSigner = class {
10
- constructor(options) {
11
- __publicField(this, "privateKey");
12
- __publicField(this, "issuer");
13
- __publicField(this, "algorithm");
14
- this.privateKey = this.loadPrivateKey(options.privateKeyPath);
15
- this.issuer = options.issuer || "https://www.usertour.io";
16
- this.algorithm = options.algorithm || "RS256";
17
- }
18
- /**
19
- * Load RSA private key from file
20
- */
21
- loadPrivateKey(keyPath) {
22
- try {
23
- const fullPath = path.resolve(keyPath);
24
- return fs.readFileSync(fullPath, "utf8");
25
- } catch (error) {
26
- throw new Error(`Failed to load private key from ${keyPath}: ${error}`);
27
- }
28
- }
29
- /**
30
- * Generate a JWT license token
31
- */
32
- generateLicense(options) {
33
- const now = Math.floor(Date.now() / 1e3);
34
- const expiresAt = now + options.expiresInDays * 24 * 60 * 60;
35
- const payload = {
36
- plan: options.plan,
37
- sub: options.subject,
38
- projectId: options.projectId,
39
- iat: now,
40
- exp: expiresAt,
41
- issuer: options.issuer || this.issuer,
42
- features: options.features
43
- };
44
- try {
45
- return jwt.sign(payload, this.privateKey, {
46
- algorithm: this.algorithm,
47
- issuer: this.issuer
48
- });
49
- } catch (error) {
50
- throw new Error(`Failed to generate JWT license: ${error}`);
51
- }
52
- }
53
- /**
54
- * Generate a license and return both token and payload info
55
- */
56
- generateLicenseWithInfo(options) {
57
- const now = Math.floor(Date.now() / 1e3);
58
- const expiresAt = now + options.expiresInDays * 24 * 60 * 60;
59
- const payload = {
60
- plan: options.plan,
61
- sub: options.subject,
62
- projectId: options.projectId,
63
- iat: now,
64
- exp: expiresAt,
65
- issuer: options.issuer || this.issuer,
66
- features: options.features
67
- };
68
- const token = jwt.sign(payload, this.privateKey, {
69
- algorithm: this.algorithm,
70
- issuer: this.issuer
71
- });
72
- return {
73
- token,
74
- payload,
75
- expiresAt: new Date(expiresAt * 1e3)
76
- };
77
- }
78
- /**
79
- * Decode a JWT token without verification (for debugging)
80
- */
81
- decodeToken(token) {
82
- try {
83
- return jwt.decode(token);
84
- } catch (error) {
85
- console.error("Failed to decode JWT token:", error);
86
- return null;
87
- }
88
- }
89
- /**
90
- * Get token information without verification
91
- */
92
- getTokenInfo(token) {
93
- try {
94
- const decoded = jwt.decode(token, { complete: true });
95
- if (!decoded || typeof decoded === "string") {
96
- return null;
97
- }
98
- return {
99
- header: decoded.header,
100
- payload: decoded.payload,
101
- signature: decoded.signature
102
- };
103
- } catch (error) {
104
- console.error("Failed to get token info:", error);
105
- return null;
106
- }
107
- }
108
- };
109
-
110
- export {
111
- JWTLicenseSigner
112
- };
@@ -1,183 +0,0 @@
1
- // src/jwt-license-validator.ts
2
- import jwt from "jsonwebtoken";
3
- var JWTLicenseValidator = {
4
- /**
5
- * Validate a JWT license
6
- * @param license - JWT license string
7
- * @param publicKey - RSA public key in PEM format
8
- * @param options - Validation options
9
- * @returns Validation result
10
- */
11
- validateLicense(license, publicKey, options = {}) {
12
- try {
13
- const { checkExpiration = true, currentTime = /* @__PURE__ */ new Date() } = options;
14
- const decoded = jwt.verify(license, publicKey, {
15
- algorithms: ["RS256"],
16
- ignoreExpiration: !checkExpiration
17
- });
18
- const fieldValidation = this.validateRequiredFields(decoded);
19
- if (!fieldValidation.isValid) {
20
- return fieldValidation;
21
- }
22
- if (checkExpiration) {
23
- const expirationValidation = this.checkExpiration(decoded, currentTime);
24
- if (!expirationValidation.isValid) {
25
- return expirationValidation;
26
- }
27
- }
28
- const hasFeature = (feature) => {
29
- return decoded.features.includes("*") || decoded.features.includes(feature);
30
- };
31
- return {
32
- isValid: true,
33
- payload: decoded,
34
- isExpired: false,
35
- hasFeature
36
- };
37
- } catch (error) {
38
- if (error instanceof jwt.JsonWebTokenError) {
39
- return {
40
- isValid: false,
41
- error: `JWT validation failed: ${error.message}`
42
- };
43
- }
44
- if (error instanceof jwt.TokenExpiredError) {
45
- return {
46
- isValid: false,
47
- error: `License expired: ${error.message}`,
48
- isExpired: true
49
- };
50
- }
51
- return {
52
- isValid: false,
53
- error: `License validation failed: ${error instanceof Error ? error.message : "Unknown error"}`
54
- };
55
- }
56
- },
57
- /**
58
- * Validate that all required fields are present in license payload
59
- * @param payload - License payload to validate
60
- * @returns Validation result
61
- */
62
- validateRequiredFields(payload) {
63
- const requiredFields = ["plan", "sub", "projectId", "iat", "exp", "issuer", "features"];
64
- for (const field of requiredFields) {
65
- if (!(field in payload)) {
66
- return {
67
- isValid: false,
68
- error: `Missing required field: ${field}`
69
- };
70
- }
71
- }
72
- if (typeof payload.plan !== "string" || !payload.plan.trim()) {
73
- return {
74
- isValid: false,
75
- error: "Invalid plan: must be a non-empty string"
76
- };
77
- }
78
- if (typeof payload.sub !== "string" || !payload.sub.trim()) {
79
- return {
80
- isValid: false,
81
- error: "Invalid sub: must be a non-empty string"
82
- };
83
- }
84
- if (typeof payload.projectId !== "string" || !payload.projectId.trim()) {
85
- return {
86
- isValid: false,
87
- error: "Invalid projectId: must be a non-empty string"
88
- };
89
- }
90
- if (typeof payload.issuer !== "string" || !payload.issuer.trim()) {
91
- return {
92
- isValid: false,
93
- error: "Invalid issuer: must be a non-empty string"
94
- };
95
- }
96
- if (!Array.isArray(payload.features)) {
97
- return {
98
- isValid: false,
99
- error: "Invalid features: must be an array"
100
- };
101
- }
102
- if (typeof payload.iat !== "number" || payload.iat <= 0) {
103
- return {
104
- isValid: false,
105
- error: "Invalid iat: must be a positive number"
106
- };
107
- }
108
- if (typeof payload.exp !== "number" || payload.exp <= 0) {
109
- return {
110
- isValid: false,
111
- error: "Invalid exp: must be a positive number"
112
- };
113
- }
114
- if (payload.iat >= payload.exp) {
115
- return {
116
- isValid: false,
117
- error: "Invalid timestamps: iat must be before exp"
118
- };
119
- }
120
- return { isValid: true };
121
- },
122
- /**
123
- * Check if license has expired
124
- * @param payload - License payload
125
- * @param currentTime - Current time to check against (defaults to now)
126
- * @returns Validation result
127
- */
128
- checkExpiration(payload, currentTime = /* @__PURE__ */ new Date()) {
129
- const now = Math.floor(currentTime.getTime() / 1e3);
130
- const expiresAt = payload.exp;
131
- if (now > expiresAt) {
132
- return {
133
- isValid: false,
134
- error: `License expired on ${new Date(expiresAt * 1e3).toISOString()}`,
135
- isExpired: true
136
- };
137
- }
138
- return { isValid: true, isExpired: false };
139
- },
140
- /**
141
- * Check if license has a specific feature
142
- * @param payload - License payload
143
- * @param feature - Feature to check
144
- * @returns Whether the feature is available
145
- */
146
- hasFeature(payload, feature) {
147
- return payload.features.includes("*") || payload.features.includes(feature);
148
- },
149
- /**
150
- * Get license expiration status
151
- * @param payload - License payload
152
- * @param currentTime - Current time to check against (defaults to now)
153
- * @returns Expiration information
154
- */
155
- getExpirationInfo(payload, currentTime = /* @__PURE__ */ new Date()) {
156
- const now = Math.floor(currentTime.getTime() / 1e3);
157
- const expiresAt = payload.exp;
158
- const isExpired = now > expiresAt;
159
- const daysUntilExpiration = Math.ceil((expiresAt - now) / (24 * 60 * 60));
160
- return {
161
- isExpired,
162
- expiresAt: new Date(expiresAt * 1e3),
163
- daysUntilExpiration: isExpired ? 0 : daysUntilExpiration
164
- };
165
- },
166
- /**
167
- * Decode JWT license without verification (for debugging)
168
- * @param license - JWT license string
169
- * @returns Decoded payload or null if invalid
170
- */
171
- decodeLicense(license) {
172
- try {
173
- const decoded = jwt.decode(license);
174
- return decoded;
175
- } catch {
176
- return null;
177
- }
178
- }
179
- };
180
-
181
- export {
182
- JWTLicenseValidator
183
- };
@@ -1,28 +0,0 @@
1
- import {
2
- navigator,
3
- win
4
- } from "./chunk-H7VA3ML2.js";
5
-
6
- // src/listener.ts
7
- var noop = () => {
8
- };
9
- function on(obj, ...args) {
10
- if (obj == null ? void 0 : obj.addEventListener) {
11
- obj.addEventListener(...args);
12
- }
13
- }
14
- function off(obj, ...args) {
15
- if (obj == null ? void 0 : obj.removeEventListener) {
16
- obj.removeEventListener(...args);
17
- }
18
- }
19
- var isBrowser = typeof win !== "undefined";
20
- var isNavigator = typeof navigator !== "undefined";
21
-
22
- export {
23
- noop,
24
- on,
25
- off,
26
- isBrowser,
27
- isNavigator
28
- };