@networkpro/web 1.6.5 → 1.7.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.
Files changed (37) hide show
  1. package/CODE_OF_CONDUCT.md +2 -2
  2. package/LICENSE.md +20 -9
  3. package/_redirects +1 -0
  4. package/cspell.json +2 -0
  5. package/package.json +4 -4
  6. package/playwright.config.js +1 -0
  7. package/src/lib/components/FullWidthSection.svelte +19 -4
  8. package/src/lib/components/LegalNav.svelte +31 -29
  9. package/src/lib/components/PostHog.svelte +20 -8
  10. package/src/lib/components/layout/Footer.svelte +1 -1
  11. package/src/lib/components/layout/HeaderDefault.svelte +2 -2
  12. package/src/lib/components/layout/HeaderHome.svelte +2 -2
  13. package/src/lib/images.js +3 -2
  14. package/src/lib/index.js +2 -1
  15. package/src/lib/meta.js +6 -1
  16. package/src/lib/pages/LicenseContent.svelte +17 -17
  17. package/src/lib/pages/PrivacyContent.svelte +116 -6
  18. package/src/lib/pages/PrivacyDashboard.svelte +240 -0
  19. package/src/lib/pages/TermsUseContent.svelte +1 -1
  20. package/src/lib/styles/css/default.css +23 -10
  21. package/src/lib/styles/global.min.css +1 -3
  22. package/src/lib/utils/privacy.js +18 -3
  23. package/src/lib/utils/trackingCookies.js +40 -0
  24. package/src/lib/utils/trackingStatus.js +46 -0
  25. package/src/lib/utils/utm.js +8 -1
  26. package/src/routes/about/+page.svelte +1 -7
  27. package/src/routes/foss-spotlight/+page.svelte +1 -7
  28. package/src/routes/license/+page.svelte +2 -8
  29. package/src/routes/privacy/+page.server.js +18 -0
  30. package/src/routes/{privacy-policy → privacy}/+page.svelte +5 -11
  31. package/src/routes/{privacy-policy → privacy-dashboard}/+page.server.js +2 -2
  32. package/src/routes/privacy-dashboard/+page.svelte +69 -0
  33. package/src/routes/terms-conditions/+page.svelte +2 -8
  34. package/src/routes/terms-of-use/+page.svelte +2 -8
  35. package/src/service-worker.js +31 -6
  36. package/static/sitemap.xml +10 -22
  37. package/tests/e2e/app.spec.js +21 -63
@@ -0,0 +1,69 @@
1
+ <!-- ==========================================================================
2
+ src/routes/privacy-dashboard/+page.svelte
3
+
4
+ Copyright © 2025 Network Pro Strategies (Network Pro™)
5
+ SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
6
+ This file is part of Network Pro.
7
+ ========================================================================== -->
8
+
9
+ <script>
10
+ import Badges from "$lib/components/Badges.svelte";
11
+ import FullWidthSection from "$lib/components/FullWidthSection.svelte";
12
+ import PrivacyDashboard from "$lib/pages/PrivacyDashboard.svelte";
13
+ import LegalNav from "$lib/components/LegalNav.svelte";
14
+ import SocialMedia from "$lib/components/SocialMedia.svelte";
15
+ import MetaTags from "$lib/components/MetaTags.svelte";
16
+
17
+ /**
18
+ * @type {string}
19
+ * Style class for the horizontal rule element.
20
+ */
21
+ const hrStyle = "hr-styled";
22
+
23
+ /**
24
+ * @type {string}
25
+ * Style class for the div element.
26
+ */
27
+ const spaceStyle = "spacer";
28
+
29
+ export let data;
30
+ </script>
31
+
32
+ <MetaTags title={data.meta.title} description={data.meta.description} />
33
+
34
+ <link rel="canonical" href="https://netwk.pro/privacy-dashboard" />
35
+
36
+ <section id="privacy">
37
+ <FullWidthSection containerClass="readable">
38
+ <!-- BEGIN PRIVACY DASHBOARD -->
39
+ <section id="main-content">
40
+ <PrivacyDashboard />
41
+ </section>
42
+ <!-- END PRIVACY DASHBOARD -->
43
+
44
+ <div class={spaceStyle}></div>
45
+
46
+ <!-- BEGIN SOCIAL MEDIA -->
47
+ <section id="social-media">
48
+ <SocialMedia />
49
+ </section>
50
+ <!-- END SOCIAL MEDIA -->
51
+
52
+ <hr />
53
+
54
+ <div class={spaceStyle}></div>
55
+
56
+ <!-- BEGIN LEGAL -->
57
+ <section id="legal-nav">
58
+ <LegalNav />
59
+ </section>
60
+ <!-- END LEGAL -->
61
+
62
+ <div class={spaceStyle}></div>
63
+
64
+ <!-- BEGIN BADGES -->
65
+ <section id="badges">
66
+ <Badges />
67
+ </section>
68
+ </FullWidthSection>
69
+ </section>
@@ -14,12 +14,6 @@ This file is part of Network Pro.
14
14
  import SocialMedia from "$lib/components/SocialMedia.svelte";
15
15
  import MetaTags from "$lib/components/MetaTags.svelte";
16
16
 
17
- /**
18
- * @type {string}
19
- * Style class for the horizontal rule element.
20
- */
21
- const hrStyle = "hr-styled";
22
-
23
17
  /**
24
18
  * @type {string}
25
19
  * Style class for the div element.
@@ -34,7 +28,7 @@ This file is part of Network Pro.
34
28
  <link rel="canonical" href="https://netwk.pro/terms-conditions" />
35
29
 
36
30
  <section id="terms-conditions">
37
- <FullWidthSection>
31
+ <FullWidthSection containerClass="readable">
38
32
  <!-- BEGIN TERMS AND CONDITIONS -->
39
33
  <section id="main-content">
40
34
  <TermsConditionsContent />
@@ -49,7 +43,7 @@ This file is part of Network Pro.
49
43
  </section>
50
44
  <!-- END SOCIAL MEDIA -->
51
45
 
52
- <hr class={hrStyle} />
46
+ <hr />
53
47
 
54
48
  <div class={spaceStyle}></div>
55
49
 
@@ -14,12 +14,6 @@ This file is part of Network Pro.
14
14
  import SocialMedia from "$lib/components/SocialMedia.svelte";
15
15
  import MetaTags from "$lib/components/MetaTags.svelte";
16
16
 
17
- /**
18
- * @type {string}
19
- * Style class for the horizontal rule element.
20
- */
21
- const hrStyle = "hr-styled";
22
-
23
17
  /**
24
18
  * @type {string}
25
19
  * Style class for the div element.
@@ -34,7 +28,7 @@ This file is part of Network Pro.
34
28
  <link rel="canonical" href="https://netwk.pro/terms-of-use" />
35
29
 
36
30
  <section id="terms-of-use">
37
- <FullWidthSection>
31
+ <FullWidthSection containerClass="readable">
38
32
  <!-- BEGIN TERMS OF USE -->
39
33
  <section id="main-content">
40
34
  <TermsUseContent />
@@ -49,7 +43,7 @@ This file is part of Network Pro.
49
43
  </section>
50
44
  <!-- END SOCIAL MEDIA -->
51
45
 
52
- <hr class={hrStyle} />
46
+ <hr />
53
47
 
54
48
  <div class={spaceStyle}></div>
55
49
 
@@ -11,6 +11,8 @@ const sw = /** @type {ServiceWorkerGlobalScope} */ (
11
11
  /** @type {unknown} */ (self)
12
12
  );
13
13
 
14
+ /// <reference types="vite/client" />
15
+
14
16
  const isDev = location.hostname === "localhost";
15
17
  const disallowedHosts = [
16
18
  "us.i.posthog.com", // Add PostHog to disallowed hosts
@@ -130,14 +132,35 @@ sw.addEventListener("activate", (event) => {
130
132
  );
131
133
  });
132
134
 
135
+ /**
136
+ * Determine if a request should be skipped by the service worker.
137
+ * Specifically filters out dev/build files, module imports, and source files.
138
+ * Only active in development mode.
139
+ *
140
+ * @param {URL} url
141
+ * @returns {boolean}
142
+ */
143
+ function shouldSkipDevModule(url) {
144
+ if (!isDev) return false;
145
+
146
+ return (
147
+ url.pathname.startsWith("/@fs") ||
148
+ url.pathname.startsWith("/node_modules") ||
149
+ url.pathname.includes(".vite") ||
150
+ url.pathname.includes(".svelte-kit") ||
151
+ !!url.pathname.match(/\.(js|ts|svelte)$/)
152
+ );
153
+ }
154
+
133
155
  // 🔹 Fetch event
134
156
  sw.addEventListener("fetch", (event) => {
135
157
  const requestUrl = new URL(event.request.url);
136
158
 
137
- // ✅ Skip handling for non-local requests (cross-origin)
138
- if (requestUrl.origin !== location.origin) {
139
- return; // let the browser handle external requests
140
- }
159
+ // ✅ Skip cross-origin requests
160
+ if (requestUrl.origin !== location.origin) return;
161
+
162
+ // ✅ Skip internal dev/module files (only in dev)
163
+ if (shouldSkipDevModule(requestUrl)) return;
141
164
 
142
165
  if (isDev) console.log("[SW] Fetch intercepted:", event.request.url);
143
166
 
@@ -153,17 +176,19 @@ sw.addEventListener("fetch", (event) => {
153
176
  if (event.request.mode === "navigate") {
154
177
  const preloadResponse = await event.preloadResponse;
155
178
  if (preloadResponse) {
156
- if (isDev)
179
+ if (isDev) {
157
180
  console.log(
158
181
  "[SW] Using preload response for:",
159
182
  event.request.url,
160
183
  );
184
+ }
161
185
  return preloadResponse;
162
186
  }
163
187
  }
164
188
 
165
189
  if (isDev)
166
190
  console.log("[SW] Fetching from network:", event.request.url);
191
+
167
192
  return await fetch(event.request);
168
193
  } catch (err) {
169
194
  if (isDev) {
@@ -188,4 +213,4 @@ sw.addEventListener("fetch", (event) => {
188
213
  );
189
214
  });
190
215
 
191
- // @cspell:ignore precaching licdn
216
+ // @cspell:ignore precaching
@@ -1,5 +1,5 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <!-- Sitemap last updated on 2025-05-18 -->
2
+ <!-- Sitemap last updated on 2025-05-28 -->
3
3
 
4
4
  <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
5
5
 
@@ -7,7 +7,7 @@
7
7
 
8
8
  <loc>https://netwk.pro</loc>
9
9
 
10
- <lastmod>2025-05-24</lastmod>
10
+ <lastmod>2025-05-28</lastmod>
11
11
 
12
12
  <changefreq>weekly</changefreq>
13
13
 
@@ -19,7 +19,7 @@
19
19
 
20
20
  <loc>https://netwk.pro/foss-spotlight</loc>
21
21
 
22
- <lastmod>2025-05-18</lastmod>
22
+ <lastmod>2025-05-27</lastmod>
23
23
 
24
24
  <changefreq>weekly</changefreq>
25
25
 
@@ -29,9 +29,9 @@
29
29
 
30
30
  <url>
31
31
 
32
- <loc>https://netwk.pro/contact</loc>
32
+ <loc>https://netwk.pro/privacy-dashboard</loc>
33
33
 
34
- <lastmod>2025-05-24</lastmod>
34
+ <lastmod>2025-05-28</lastmod>
35
35
 
36
36
  <changefreq>monthly</changefreq>
37
37
 
@@ -41,21 +41,9 @@
41
41
 
42
42
  <url>
43
43
 
44
- <loc>https://netwk.pro/privacy-rights</loc>
44
+ <loc>https://netwk.pro/privacy</loc>
45
45
 
46
- <lastmod>2025-05-24</lastmod>
47
-
48
- <changefreq>monthly</changefreq>
49
-
50
- <priority>0.7</priority>
51
-
52
- </url>
53
-
54
- <url>
55
-
56
- <loc>https://netwk.pro/privacy-policy</loc>
57
-
58
- <lastmod>2025-05-23</lastmod>
46
+ <lastmod>2025-05-28</lastmod>
59
47
 
60
48
  <changefreq>monthly</changefreq>
61
49
 
@@ -67,7 +55,7 @@
67
55
 
68
56
  <loc>https://netwk.pro/license</loc>
69
57
 
70
- <lastmod>2025-05-24</lastmod>
58
+ <lastmod>2025-05-28</lastmod>
71
59
 
72
60
  <changefreq>monthly</changefreq>
73
61
 
@@ -79,7 +67,7 @@
79
67
 
80
68
  <loc>https://netwk.pro/terms-of-use</loc>
81
69
 
82
- <lastmod>2025-05-21</lastmod>
70
+ <lastmod>2025-05-27</lastmod>
83
71
 
84
72
  <changefreq>monthly</changefreq>
85
73
 
@@ -91,7 +79,7 @@
91
79
 
92
80
  <loc>https://netwk.pro/terms-conditions</loc>
93
81
 
94
- <lastmod>2025-05-08</lastmod>
82
+ <lastmod>2025-05-27</lastmod>
95
83
 
96
84
  <changefreq>monthly</changefreq>
97
85
 
@@ -9,120 +9,78 @@ This file is part of Network Pro.
9
9
  import { expect, test } from "@playwright/test";
10
10
 
11
11
  test.describe("Desktop Tests", () => {
12
- // Simplified Test for Title on Desktop
13
12
  test("should load successfully with the correct title", async ({
14
13
  page,
15
14
  browserName,
16
15
  }) => {
17
- if (browserName === "webkit") {
18
- test.skip(); // Skip WebKit if it's problematic
19
- }
16
+ if (browserName === "webkit") test.skip();
20
17
 
21
18
  await page.setViewportSize({ width: 1280, height: 720 });
22
-
23
- // Add a small timeout before navigating to the page
24
- await page.waitForTimeout(1500); // Wait for 1.5 seconds
25
-
19
+ await page.waitForTimeout(1500);
26
20
  await page.goto("/");
27
-
28
- // Wait for the page to fully load
29
- await page.waitForLoadState("load", { timeout: 60000 }); // Wait until the page is fully loaded
30
-
31
- // Assert that the title matches
21
+ await page.waitForLoadState("load", { timeout: 60000 });
32
22
  await expect(page).toHaveTitle(/Locking Down Networks/);
33
23
  });
34
24
 
35
- // Simplified Test for Navigation Bar
36
25
  test("should display the navigation bar and 'about' link", async ({
37
26
  page,
38
27
  }) => {
39
28
  await page.setViewportSize({ width: 1280, height: 720 });
40
-
41
- // Add a small timeout before navigating to the page
42
- await page.waitForTimeout(1500); // Wait for 1.5 seconds
43
-
29
+ await page.waitForTimeout(1500);
44
30
  await page.goto("/");
45
31
 
46
- // Ensure the navigation bar is visible
47
- const nav = page.locator("nav");
32
+ const nav = page.getByRole("navigation", { name: "Homepage navigation" });
48
33
  await expect(nav).toBeVisible();
49
34
 
50
- // Check for 'about' route in the navigation
51
- const aboutLink = nav.locator("a", { hasText: "about" });
35
+ const aboutLink = nav.getByRole("link", { name: "about" });
52
36
  await expect(aboutLink).toBeVisible();
53
- await expect(aboutLink).toHaveAttribute("href", "/about"); // Ensure it points to the correct route
37
+ await expect(aboutLink).toHaveAttribute("href", "/about");
54
38
  });
55
39
 
56
- // Simplified Footer Visibility Test
57
40
  test("should display the footer correctly", async ({ page }) => {
58
41
  await page.setViewportSize({ width: 1280, height: 720 });
59
-
60
- // Add a small timeout before navigating to the page
61
- await page.waitForTimeout(1500); // Wait for 1.5 seconds
62
-
42
+ await page.waitForTimeout(1500);
63
43
  await page.goto("/");
64
44
 
65
- // Check that the footer is visible
66
45
  const footer = page.locator("footer");
67
46
  await expect(footer).toBeVisible();
68
47
  });
69
48
 
70
- // Simplified Test for Clickable Links (e.g., 'about' link)
71
49
  test("should ensure the 'about' link is clickable", async ({ page }) => {
72
50
  await page.setViewportSize({ width: 1280, height: 720 });
73
-
74
- // Add a small timeout before navigating to the page
75
- await page.waitForTimeout(1500); // Wait for 1.5 seconds
76
-
77
51
  await page.goto("/");
78
52
 
79
- // Ensure the "about" link is visible and clickable
80
- const aboutLink = page.locator("a", { hasText: "about" });
81
- await expect(aboutLink).toBeVisible();
82
- await aboutLink.click();
53
+ const nav = page.getByRole("navigation", { name: "Homepage navigation" });
54
+ await expect(nav).toBeVisible({ timeout: 60000 });
83
55
 
84
- // Wait for the URL to update instead of relying on navigation
85
- await page.waitForURL("/about", { timeout: 60000 }); // Wait for the correct URL
56
+ const aboutLink = nav.getByRole("link", { name: "about" });
57
+ await expect(aboutLink).toBeVisible({ timeout: 60000 });
58
+ await aboutLink.click();
86
59
 
87
- // Assert that it navigates to the correct route
60
+ await page.waitForURL("/about", { timeout: 60000 });
88
61
  await expect(page).toHaveURL(/\/about/);
89
62
  });
90
- });
63
+ }); // End Desktop Tests
91
64
 
92
65
  test.describe("Mobile Tests", () => {
93
- // Simplified Test for correct title on mobile
94
66
  test("should load successfully with the correct title on mobile", async ({
95
67
  page,
96
68
  browserName,
97
69
  }) => {
98
- if (browserName === "webkit") {
99
- test.skip(); // Skip WebKit if it's problematic
100
- }
101
-
102
- await page.setViewportSize({ width: 375, height: 667 }); // Mobile size (e.g., iPhone 6)
103
-
104
- // Add a small timeout before navigating to the page
105
- await page.waitForTimeout(1500); // Wait for 1.5 seconds
70
+ if (browserName === "webkit") test.skip();
106
71
 
72
+ await page.setViewportSize({ width: 375, height: 667 });
73
+ await page.waitForTimeout(1500);
107
74
  await page.goto("/");
108
-
109
- // Wait for the page to fully load
110
- await page.waitForLoadState("load", { timeout: 60000 }); // Wait until the page is fully loaded
111
-
112
- // Assert that the title matches
75
+ await page.waitForLoadState("load", { timeout: 60000 });
113
76
  await expect(page).toHaveTitle(/Locking Down Networks/);
114
77
  });
115
78
 
116
- // Simplified Test for mobile content visibility
117
79
  test("should display main content correctly on mobile", async ({ page }) => {
118
- await page.setViewportSize({ width: 375, height: 667 }); // Mobile size
119
-
120
- // Add a small timeout before navigating to the page
121
- await page.waitForTimeout(1500); // Wait for 1.5 seconds
122
-
80
+ await page.setViewportSize({ width: 375, height: 667 });
81
+ await page.waitForTimeout(1500);
123
82
  await page.goto("/");
124
83
 
125
- // Check that the main heading is visible on mobile
126
84
  const mainHeading = page.locator("h1, h2");
127
85
  await expect(mainHeading).toBeVisible();
128
86
  });