@huloglobal/vendure-plugin-visitor-analytics 0.11.0 → 0.11.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.
- package/CHANGELOG.md +11 -0
- package/dist/detect-bot.d.ts.map +1 -1
- package/dist/detect-bot.js +6 -1
- package/dist/detect-bot.js.map +1 -1
- package/dist/detect-bot.test.d.ts +2 -0
- package/dist/detect-bot.test.d.ts.map +1 -0
- package/dist/detect-bot.test.js +53 -0
- package/dist/detect-bot.test.js.map +1 -0
- package/dist/proxy-headers.test.d.ts +2 -0
- package/dist/proxy-headers.test.d.ts.map +1 -0
- package/dist/proxy-headers.test.js +55 -0
- package/dist/proxy-headers.test.js.map +1 -0
- package/dist/url-pattern.test.d.ts +2 -0
- package/dist/url-pattern.test.d.ts.map +1 -0
- package/dist/url-pattern.test.js +39 -0
- package/dist/url-pattern.test.js.map +1 -0
- package/package.json +6 -3
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,17 @@ documented here. The format follows
|
|
|
5
5
|
[Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project
|
|
6
6
|
adheres to [semantic versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.11.1] — 2026-08-02
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- `anonymizeIp` produced a malformed address (e.g. `fe80::1::`) for
|
|
12
|
+
already-abbreviated IPv6 inputs. Abbreviated addresses are now left
|
|
13
|
+
unchanged; full-form IPv6 still truncates to the first three hextets.
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
- Unit test suites: URL glob matcher, bot detection + IP anonymisation,
|
|
17
|
+
proxy-header extraction.
|
|
18
|
+
|
|
8
19
|
## [0.8.4] — 2026-07-04
|
|
9
20
|
|
|
10
21
|
### Added
|
package/dist/detect-bot.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detect-bot.d.ts","sourceRoot":"","sources":["../src/detect-bot.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAeH,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAG9D;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"detect-bot.d.ts","sourceRoot":"","sources":["../src/detect-bot.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAeH,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAG9D;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAiB5D"}
|
package/dist/detect-bot.js
CHANGED
|
@@ -36,7 +36,12 @@ function anonymizeIp(ip) {
|
|
|
36
36
|
if (!ip)
|
|
37
37
|
return null;
|
|
38
38
|
if (ip.includes(':')) {
|
|
39
|
-
// IPv6 — keep first 3 hextets.
|
|
39
|
+
// IPv6 — keep first 3 hextets. An already-abbreviated address
|
|
40
|
+
// (contains `::`) can't be sliced reliably by ':' — splitting
|
|
41
|
+
// "fe80::1" yields an empty middle part and re-joining would
|
|
42
|
+
// produce a malformed "fe80::1::", so leave those as-is.
|
|
43
|
+
if (ip.includes('::'))
|
|
44
|
+
return ip;
|
|
40
45
|
const parts = ip.split(':');
|
|
41
46
|
if (parts.length < 3)
|
|
42
47
|
return ip;
|
package/dist/detect-bot.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detect-bot.js","sourceRoot":"","sources":["../src/detect-bot.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAeH,0BAGC;AAQD,
|
|
1
|
+
{"version":3,"file":"detect-bot.js","sourceRoot":"","sources":["../src/detect-bot.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAeH,0BAGC;AAQD,kCAiBC;AAzCD,MAAM,YAAY,GAAG;IACjB,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU;IAC7C,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,SAAS,EAAE,QAAQ;IAC7D,sBAAsB,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc;IACjE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW;IACvD,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,YAAY;IACxD,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,eAAe;IACnE,cAAc,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW;IAClE,SAAS,EAAE,SAAS,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,SAAS;IACrE,aAAa,EAAE,QAAQ,EAAE,iBAAiB,EAAE,SAAS,EAAE,SAAS;IAChE,iBAAiB,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa;CAC5E,CAAC;AAEF,SAAgB,OAAO,CAAC,EAA6B;IACjD,IAAI,CAAC,EAAE;QAAE,OAAO,KAAK,CAAC;IACtB,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED;;;;;GAKG;AACH,SAAgB,WAAW,CAAC,EAAiB;IACzC,IAAI,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IACrB,IAAI,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACnB,8DAA8D;QAC9D,8DAA8D;QAC9D,6DAA6D;QAC7D,yDAAyD;QACzD,IAAI,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,EAAE,CAAC;QAChC,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IAC9C,CAAC;IACD,IAAI,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACnB,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3E,CAAC;IACD,OAAO,EAAE,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-bot.test.d.ts","sourceRoot":"","sources":["../src/detect-bot.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const detect_bot_1 = require("./detect-bot");
|
|
5
|
+
(0, vitest_1.describe)('isBotUa', () => {
|
|
6
|
+
(0, vitest_1.it)('flags well-known crawlers and tools', () => {
|
|
7
|
+
for (const ua of [
|
|
8
|
+
'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)',
|
|
9
|
+
'Mozilla/5.0 (compatible; bingbot/2.0)',
|
|
10
|
+
'facebookexternalhit/1.1',
|
|
11
|
+
'Slackbot-LinkExpanding 1.0',
|
|
12
|
+
'curl/8.4.0',
|
|
13
|
+
'python-requests/2.31.0',
|
|
14
|
+
'axios/1.6.0',
|
|
15
|
+
'Go-http-client/2.0',
|
|
16
|
+
'Mozilla/5.0 HeadlessChrome/120.0',
|
|
17
|
+
'UptimeRobot/2.0',
|
|
18
|
+
]) {
|
|
19
|
+
(0, vitest_1.expect)((0, detect_bot_1.isBotUa)(ua), ua).toBe(true);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
(0, vitest_1.it)('passes real browser UAs', () => {
|
|
23
|
+
for (const ua of [
|
|
24
|
+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36',
|
|
25
|
+
'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 Version/17.0 Mobile/15E148 Safari/604.1',
|
|
26
|
+
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Gecko/20100101 Firefox/121.0',
|
|
27
|
+
]) {
|
|
28
|
+
(0, vitest_1.expect)((0, detect_bot_1.isBotUa)(ua), ua).toBe(false);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
(0, vitest_1.it)('handles null / empty', () => {
|
|
32
|
+
(0, vitest_1.expect)((0, detect_bot_1.isBotUa)(null)).toBe(false);
|
|
33
|
+
(0, vitest_1.expect)((0, detect_bot_1.isBotUa)(undefined)).toBe(false);
|
|
34
|
+
(0, vitest_1.expect)((0, detect_bot_1.isBotUa)('')).toBe(false);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
(0, vitest_1.describe)('anonymizeIp', () => {
|
|
38
|
+
(0, vitest_1.it)('zeroes the last octet of IPv4', () => {
|
|
39
|
+
(0, vitest_1.expect)((0, detect_bot_1.anonymizeIp)('203.0.113.42')).toBe('203.0.113.0');
|
|
40
|
+
(0, vitest_1.expect)((0, detect_bot_1.anonymizeIp)('10.1.2.3')).toBe('10.1.2.0');
|
|
41
|
+
});
|
|
42
|
+
(0, vitest_1.it)('keeps the first three hextets of IPv6', () => {
|
|
43
|
+
(0, vitest_1.expect)((0, detect_bot_1.anonymizeIp)('2001:db8:85a3:8d3:1319:8a2e:370:7348')).toBe('2001:db8:85a3::');
|
|
44
|
+
});
|
|
45
|
+
(0, vitest_1.it)('passes through unexpected shapes unchanged', () => {
|
|
46
|
+
(0, vitest_1.expect)((0, detect_bot_1.anonymizeIp)('fe80::1')).toBe('fe80::1'); // < 3 hextets
|
|
47
|
+
(0, vitest_1.expect)((0, detect_bot_1.anonymizeIp)('not-an-ip')).toBe('not-an-ip');
|
|
48
|
+
});
|
|
49
|
+
(0, vitest_1.it)('returns null for null input', () => {
|
|
50
|
+
(0, vitest_1.expect)((0, detect_bot_1.anonymizeIp)(null)).toBeNull();
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
//# sourceMappingURL=detect-bot.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-bot.test.js","sourceRoot":"","sources":["../src/detect-bot.test.ts"],"names":[],"mappings":";;AAAA,mCAA8C;AAC9C,6CAAoD;AAEpD,IAAA,iBAAQ,EAAC,SAAS,EAAE,GAAG,EAAE;IACrB,IAAA,WAAE,EAAC,qCAAqC,EAAE,GAAG,EAAE;QAC3C,KAAK,MAAM,EAAE,IAAI;YACb,0EAA0E;YAC1E,uCAAuC;YACvC,yBAAyB;YACzB,4BAA4B;YAC5B,YAAY;YACZ,wBAAwB;YACxB,aAAa;YACb,oBAAoB;YACpB,kCAAkC;YAClC,iBAAiB;SACpB,EAAE,CAAC;YACA,IAAA,eAAM,EAAC,IAAA,oBAAO,EAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,yBAAyB,EAAE,GAAG,EAAE;QAC/B,KAAK,MAAM,EAAE,IAAI;YACb,6GAA6G;YAC7G,qHAAqH;YACrH,8EAA8E;SACjF,EAAE,CAAC;YACA,IAAA,eAAM,EAAC,IAAA,oBAAO,EAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,sBAAsB,EAAE,GAAG,EAAE;QAC5B,IAAA,eAAM,EAAC,IAAA,oBAAO,EAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClC,IAAA,eAAM,EAAC,IAAA,oBAAO,EAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvC,IAAA,eAAM,EAAC,IAAA,oBAAO,EAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,aAAa,EAAE,GAAG,EAAE;IACzB,IAAA,WAAE,EAAC,+BAA+B,EAAE,GAAG,EAAE;QACrC,IAAA,eAAM,EAAC,IAAA,wBAAW,EAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACxD,IAAA,eAAM,EAAC,IAAA,wBAAW,EAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,uCAAuC,EAAE,GAAG,EAAE;QAC7C,IAAA,eAAM,EAAC,IAAA,wBAAW,EAAC,sCAAsC,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACxF,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,4CAA4C,EAAE,GAAG,EAAE;QAClD,IAAA,eAAM,EAAC,IAAA,wBAAW,EAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,cAAc;QAC9D,IAAA,eAAM,EAAC,IAAA,wBAAW,EAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,6BAA6B,EAAE,GAAG,EAAE;QACnC,IAAA,eAAM,EAAC,IAAA,wBAAW,EAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IACzC,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-headers.test.d.ts","sourceRoot":"","sources":["../src/proxy-headers.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const proxy_headers_1 = require("./proxy-headers");
|
|
5
|
+
const req = (headers, ip) => ({ headers, ip });
|
|
6
|
+
(0, vitest_1.describe)('getRealIp', () => {
|
|
7
|
+
(0, vitest_1.it)('prefers CF-Connecting-IP above everything', () => {
|
|
8
|
+
(0, vitest_1.expect)((0, proxy_headers_1.getRealIp)(req({
|
|
9
|
+
'cf-connecting-ip': '1.1.1.1', 'true-client-ip': '2.2.2.2',
|
|
10
|
+
'x-real-ip': '3.3.3.3', 'x-forwarded-for': '4.4.4.4',
|
|
11
|
+
}, '5.5.5.5'))).toBe('1.1.1.1');
|
|
12
|
+
});
|
|
13
|
+
(0, vitest_1.it)('falls through the precedence chain', () => {
|
|
14
|
+
(0, vitest_1.expect)((0, proxy_headers_1.getRealIp)(req({ 'true-client-ip': '2.2.2.2', 'x-real-ip': '3.3.3.3' }))).toBe('2.2.2.2');
|
|
15
|
+
(0, vitest_1.expect)((0, proxy_headers_1.getRealIp)(req({ 'x-real-ip': '3.3.3.3' }))).toBe('3.3.3.3');
|
|
16
|
+
(0, vitest_1.expect)((0, proxy_headers_1.getRealIp)(req({ 'x-forwarded-for': '4.4.4.4, 9.9.9.9' }))).toBe('4.4.4.4');
|
|
17
|
+
});
|
|
18
|
+
(0, vitest_1.it)('uses the left-most XFF entry', () => {
|
|
19
|
+
(0, vitest_1.expect)((0, proxy_headers_1.getRealIp)(req({ 'x-forwarded-for': ' 203.0.113.1 , 10.0.0.1 , 10.0.0.2 ' }))).toBe('203.0.113.1');
|
|
20
|
+
});
|
|
21
|
+
(0, vitest_1.it)('falls back to req.ip then null', () => {
|
|
22
|
+
(0, vitest_1.expect)((0, proxy_headers_1.getRealIp)(req({}, '5.5.5.5'))).toBe('5.5.5.5');
|
|
23
|
+
(0, vitest_1.expect)((0, proxy_headers_1.getRealIp)(req({}))).toBeNull();
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
(0, vitest_1.describe)('getResolvedCountry', () => {
|
|
27
|
+
(0, vitest_1.it)('reads cf-ipcountry', () => {
|
|
28
|
+
(0, vitest_1.expect)((0, proxy_headers_1.getResolvedCountry)(req({ 'cf-ipcountry': 'gb' }))).toBe('GB');
|
|
29
|
+
});
|
|
30
|
+
(0, vitest_1.it)('ignores CF placeholders XX and T1', () => {
|
|
31
|
+
(0, vitest_1.expect)((0, proxy_headers_1.getResolvedCountry)(req({ 'cf-ipcountry': 'XX' }))).toBeNull();
|
|
32
|
+
(0, vitest_1.expect)((0, proxy_headers_1.getResolvedCountry)(req({ 'cf-ipcountry': 'T1' }))).toBeNull();
|
|
33
|
+
});
|
|
34
|
+
(0, vitest_1.it)('parses Akamai edgescape', () => {
|
|
35
|
+
(0, vitest_1.expect)((0, proxy_headers_1.getResolvedCountry)(req({ 'x-akamai-edgescape': 'georegion=246,country_code=US,region_code=CA' }))).toBe('US');
|
|
36
|
+
});
|
|
37
|
+
(0, vitest_1.it)('reads the Fastly country header', () => {
|
|
38
|
+
(0, vitest_1.expect)((0, proxy_headers_1.getResolvedCountry)(req({ 'x-country-code': 'de' }))).toBe('DE');
|
|
39
|
+
(0, vitest_1.expect)((0, proxy_headers_1.getResolvedCountry)(req({ 'x-country-code': 'not-a-code' }))).toBeNull();
|
|
40
|
+
});
|
|
41
|
+
(0, vitest_1.it)('returns null when nothing present', () => {
|
|
42
|
+
(0, vitest_1.expect)((0, proxy_headers_1.getResolvedCountry)(req({}))).toBeNull();
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
(0, vitest_1.describe)('getResolvedRegion', () => {
|
|
46
|
+
(0, vitest_1.it)('reads cf-region-code', () => {
|
|
47
|
+
(0, vitest_1.expect)((0, proxy_headers_1.getResolvedRegion)(req({ 'cf-region-code': 'eng' }))).toBe('ENG');
|
|
48
|
+
(0, vitest_1.expect)((0, proxy_headers_1.getResolvedRegion)(req({ 'cf-region-code': 'CA' }))).toBe('CA');
|
|
49
|
+
});
|
|
50
|
+
(0, vitest_1.it)('rejects malformed region codes and empties', () => {
|
|
51
|
+
(0, vitest_1.expect)((0, proxy_headers_1.getResolvedRegion)(req({ 'cf-region-code': 'TOOLONG' }))).toBeNull();
|
|
52
|
+
(0, vitest_1.expect)((0, proxy_headers_1.getResolvedRegion)(req({}))).toBeNull();
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
//# sourceMappingURL=proxy-headers.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-headers.test.js","sourceRoot":"","sources":["../src/proxy-headers.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url-pattern.test.d.ts","sourceRoot":"","sources":["../src/url-pattern.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const url_pattern_1 = require("./url-pattern");
|
|
5
|
+
(0, vitest_1.describe)('matchUrl', () => {
|
|
6
|
+
(0, vitest_1.it)('matches exact literals case-insensitively', () => {
|
|
7
|
+
(0, vitest_1.expect)((0, url_pattern_1.matchUrl)('/checkout/success', '/checkout/success')).toBe(true);
|
|
8
|
+
(0, vitest_1.expect)((0, url_pattern_1.matchUrl)('/Checkout/Success', '/checkout/success')).toBe(true);
|
|
9
|
+
(0, vitest_1.expect)((0, url_pattern_1.matchUrl)('/checkout/success', '/checkout/fail')).toBe(false);
|
|
10
|
+
});
|
|
11
|
+
(0, vitest_1.it)('single * matches within a segment but not across /', () => {
|
|
12
|
+
(0, vitest_1.expect)((0, url_pattern_1.matchUrl)('/product/*', '/product/widget')).toBe(true);
|
|
13
|
+
(0, vitest_1.expect)((0, url_pattern_1.matchUrl)('/product/*', '/product/')).toBe(true);
|
|
14
|
+
(0, vitest_1.expect)((0, url_pattern_1.matchUrl)('/product/*', '/product/widget/reviews')).toBe(false);
|
|
15
|
+
(0, vitest_1.expect)((0, url_pattern_1.matchUrl)('/p/*/buy', '/p/123/buy')).toBe(true);
|
|
16
|
+
(0, vitest_1.expect)((0, url_pattern_1.matchUrl)('/p/*/buy', '/p/123/456/buy')).toBe(false);
|
|
17
|
+
});
|
|
18
|
+
(0, vitest_1.it)('double ** matches across segments', () => {
|
|
19
|
+
(0, vitest_1.expect)((0, url_pattern_1.matchUrl)('/shop/**', '/shop/a/b/c')).toBe(true);
|
|
20
|
+
(0, vitest_1.expect)((0, url_pattern_1.matchUrl)('/shop/**', '/shop/')).toBe(true);
|
|
21
|
+
(0, vitest_1.expect)((0, url_pattern_1.matchUrl)('/**/checkout', '/a/b/checkout')).toBe(true);
|
|
22
|
+
(0, vitest_1.expect)((0, url_pattern_1.matchUrl)('**', '/anything/at/all')).toBe(true);
|
|
23
|
+
});
|
|
24
|
+
(0, vitest_1.it)('escapes regex metacharacters in the literal parts', () => {
|
|
25
|
+
(0, vitest_1.expect)((0, url_pattern_1.matchUrl)('/price.list', '/price.list')).toBe(true);
|
|
26
|
+
(0, vitest_1.expect)((0, url_pattern_1.matchUrl)('/price.list', '/priceXlist')).toBe(false); // . is literal, not "any char"
|
|
27
|
+
(0, vitest_1.expect)((0, url_pattern_1.matchUrl)('/a(b)+', '/a(b)+')).toBe(true);
|
|
28
|
+
});
|
|
29
|
+
(0, vitest_1.it)('anchors the whole string', () => {
|
|
30
|
+
(0, vitest_1.expect)((0, url_pattern_1.matchUrl)('/cart', '/cart/extra')).toBe(false);
|
|
31
|
+
(0, vitest_1.expect)((0, url_pattern_1.matchUrl)('/cart', 'x/cart')).toBe(false);
|
|
32
|
+
});
|
|
33
|
+
(0, vitest_1.it)('returns false for empty pattern or url', () => {
|
|
34
|
+
(0, vitest_1.expect)((0, url_pattern_1.matchUrl)('', '/x')).toBe(false);
|
|
35
|
+
(0, vitest_1.expect)((0, url_pattern_1.matchUrl)('/x', '')).toBe(false);
|
|
36
|
+
(0, vitest_1.expect)((0, url_pattern_1.matchUrl)('', '')).toBe(false);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
//# sourceMappingURL=url-pattern.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url-pattern.test.js","sourceRoot":"","sources":["../src/url-pattern.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@huloglobal/vendure-plugin-visitor-analytics",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"description": "Full-funnel visitor analytics for Vendure storefronts — pageviews, time-on-page, session journey, exit pages, funnel drop-off, and per-visitor profile drawer with parsed user-agent + MaxMind GeoLite2 enrichment. Auto-issues visitor + session cookies on first request; logs guest and signed-in events against the same visitor id so the journey survives login.",
|
|
5
5
|
"license": "AGPL-3.0-or-later",
|
|
6
6
|
"author": "Wayne Garrison <wayne@garrison.me.uk>",
|
|
@@ -22,7 +22,9 @@
|
|
|
22
22
|
],
|
|
23
23
|
"scripts": {
|
|
24
24
|
"build": "tsc -p tsconfig.json",
|
|
25
|
-
"prepublishOnly": "yarn build"
|
|
25
|
+
"prepublishOnly": "yarn build",
|
|
26
|
+
"test": "vitest run",
|
|
27
|
+
"test:watch": "vitest"
|
|
26
28
|
},
|
|
27
29
|
"dependencies": {
|
|
28
30
|
"@huloglobal/vendure-licence-sdk": "^0.6.0",
|
|
@@ -41,7 +43,8 @@
|
|
|
41
43
|
"@nestjs/common": "^10.0.0",
|
|
42
44
|
"@vendure/core": "^3.7.1",
|
|
43
45
|
"typeorm": "^0.3.0",
|
|
44
|
-
"typescript": "^5.4.0"
|
|
46
|
+
"typescript": "^5.4.0",
|
|
47
|
+
"vitest": "^2.0.0"
|
|
45
48
|
},
|
|
46
49
|
"keywords": [
|
|
47
50
|
"vendure",
|