@networkpro/web 1.7.3 → 1.7.6

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.
@@ -8,8 +8,8 @@ This file is part of Network Pro.
8
8
 
9
9
  <a name="top"></a>
10
10
 
11
- [SPDX-License-Identifier](https://spdx.dev/learn/handling-license-info):
12
- `CC-BY-4.0 OR GPL-3.0-or-later`
11
+ <sup>[SPDX-License-Identifier](https://spdx.dev/learn/handling-license-info):
12
+ `CC-BY-4.0 OR GPL-3.0-or-later`</sup>
13
13
 
14
14
  # Contributor Covenant Code of Conduct
15
15
 
@@ -152,12 +152,12 @@ For answers to common questions about this code of conduct, see the FAQ at
152
152
 
153
153
  ---
154
154
 
155
- <div style="font-size: 12px; font-weight: bold; text-align: center;">
155
+ <span style="font-size: 12px; font-weight: bold; text-align: center;">
156
156
 
157
157
  [Home](https://netwk.pro) &nbsp; | &nbsp; [Terms of Use](https://netwk.pro/terms-of-use)
158
158
  [Privacy Policy](https://netwk.pro/privacy) &nbsp; | &nbsp; [Legal](https://netwk.pro/license)
159
159
 
160
- </div>
160
+ </span>
161
161
 
162
162
  &nbsp;
163
163
 
package/LICENSE.md CHANGED
@@ -6,8 +6,8 @@ SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
6
6
  This file is part of Network Pro.
7
7
  ====================================================================== -->
8
8
 
9
- [SPDX-License-Identifier](https://spdx.dev/learn/handling-license-info/):
10
- `CC-BY-4.0 OR GPL-3.0-or-later`
9
+ <sup>[SPDX-License-Identifier](https://spdx.dev/learn/handling-license-info/):
10
+ `CC-BY-4.0 OR GPL-3.0-or-later`</sup>
11
11
 
12
12
  <a name="top"></a>
13
13
 
package/budget.json ADDED
@@ -0,0 +1,34 @@
1
+ [
2
+ {
3
+ "path": "/*",
4
+ "resourceSizes": [
5
+ { "resourceType": "script", "budget": 300 },
6
+ { "resourceType": "stylesheet", "budget": 100 },
7
+ { "resourceType": "image", "budget": 350 },
8
+ { "resourceType": "font", "budget": 200 },
9
+ { "resourceType": "other", "budget": 150 },
10
+ { "resourceType": "document", "budget": 50 },
11
+ { "resourceType": "total", "budget": 1000 }
12
+ ],
13
+ "resourceCounts": [
14
+ { "resourceType": "third-party", "budget": 15 },
15
+ { "resourceType": "script", "budget": 15 },
16
+ { "resourceType": "stylesheet", "budget": 5 },
17
+ { "resourceType": "image", "budget": 15 },
18
+ { "resourceType": "font", "budget": 10 },
19
+ { "resourceType": "other", "budget": 10 },
20
+ { "resourceType": "total", "budget": 60 }
21
+ ]
22
+ },
23
+ {
24
+ "path": "/foss-spotlight",
25
+ "resourceSizes": [
26
+ { "resourceType": "image", "budget": 500 },
27
+ { "resourceType": "total", "budget": 1200 }
28
+ ],
29
+ "resourceCounts": [
30
+ { "resourceType": "image", "budget": 25 },
31
+ { "resourceType": "total", "budget": 75 }
32
+ ]
33
+ }
34
+ ]
package/cspell.json CHANGED
@@ -12,9 +12,12 @@
12
12
  "Embedder",
13
13
  "Ente",
14
14
  "esbuild",
15
+ "fontawesome",
15
16
  "foss",
16
17
  "geolocation",
18
+ "heliboard",
17
19
  "homescreen",
20
+ "Izzy",
18
21
  "lhci",
19
22
  "lighthouseci",
20
23
  "lighthouserc",
@@ -37,6 +40,7 @@
37
40
  "SIEM",
38
41
  "SPDY",
39
42
  "stylelintignore",
43
+ "stylesheet",
40
44
  "Subsite",
41
45
  "subsites",
42
46
  "Supercookie",
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "sideEffects": [
5
5
  "./.netlify/shims.js"
6
6
  ],
7
- "version": "1.7.3",
7
+ "version": "1.7.6",
8
8
  "description": "Locking Down Networks, Unlocking Confidence | Security, Networking, Privacy — Network Pro Strategies",
9
9
  "keywords": [
10
10
  "advisory",
@@ -78,13 +78,13 @@
78
78
  },
79
79
  "dependencies": {
80
80
  "nodemailer": "^7.0.3",
81
- "posthog-js": "^1.248.1",
81
+ "posthog-js": "^1.249.0",
82
82
  "semver": "^7.7.2",
83
83
  "svelte": "5.33.10"
84
84
  },
85
85
  "devDependencies": {
86
86
  "@eslint/compat": "^1.2.9",
87
- "@eslint/js": "^9.27.0",
87
+ "@eslint/js": "^9.28.0",
88
88
  "@lhci/cli": "^0.14.0",
89
89
  "@playwright/test": "^1.52.0",
90
90
  "@sveltejs/adapter-netlify": "^5.0.2",
@@ -95,7 +95,7 @@
95
95
  "@vitest/coverage-v8": "^3.1.4",
96
96
  "autoprefixer": "^10.4.21",
97
97
  "browserslist": "^4.25.0",
98
- "eslint": "^9.27.0",
98
+ "eslint": "^9.28.0",
99
99
  "eslint-config-prettier": "^10.1.5",
100
100
  "eslint-plugin-jsdoc": "^50.6.17",
101
101
  "eslint-plugin-svelte": "^3.9.0",
@@ -6,12 +6,82 @@ SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
6
6
  This file is part of Network Pro.
7
7
  ========================================================================== */
8
8
 
9
- // cspell:ignore lsheet eauth bolditalic tosdr
10
-
11
9
  // Import FOSS images
12
- import { acodePng, acodeWbp, eauthPng, eauthWbp, lsheetPng, lsheetWbp, pmxPng, pmxWbp, tosPng, tosWbp, urlPng, urlWbp } from "$lib";
10
+ import { acodePng, acodeWbp, eauthPng, eauthWbp, hboardPng, hboardWbp, lsheetPng, lsheetWbp, pmxPng, pmxWbp, tosPng, tosWbp, urlPng, urlWbp } from "$lib";
13
11
 
14
12
  export const fossData = [
13
+ {
14
+ id: "heliboard",
15
+ images: {
16
+ webp: hboardWbp,
17
+ png: hboardPng,
18
+ },
19
+ imgAlt: "HeliBoard",
20
+ title: "HeliBoard",
21
+ headline: "⌨️ A privacy-first keyboard that respects your data. Always.",
22
+ headlineDescription: `
23
+ <p>
24
+ Meet <strong>HeliBoard</strong> — a fully open-source Android keyboard that puts privacy and user control first. No internet permissions. No telemetry. No tracking. Just a lightweight, seamless typing experience built by developers who genuinely care about digital freedom and transparency.
25
+ </p>
26
+ `,
27
+ features: [
28
+ {
29
+ emoji: "💡",
30
+ label: "Why Make the Switch to HeliBoard?",
31
+ isIntro: true
32
+ },
33
+ {
34
+ emoji: "✔️",
35
+ label: "Material Design interface",
36
+ },
37
+ {
38
+ emoji: "✔️",
39
+ label: "Built-in themes with dark mode support",
40
+ },
41
+ {
42
+ emoji: "✔️",
43
+ label: "No ads, data collection, or background connections",
44
+ },
45
+ {
46
+ emoji: "✔️",
47
+ label: "Emoji support, gesture input, and smart customization",
48
+ },
49
+ {
50
+ emoji: "✔️",
51
+ label: "Actively developed on GitHub",
52
+ description: "get involved!"
53
+ }
54
+ ],
55
+ detailsDescription: `
56
+ <p>
57
+ Whether you're switching from Gboard or just want something more minimal and ethical, HeliBoard brings you that true FOSS flavor while keeping your taps smooth and secure.
58
+ </p>
59
+ <p>
60
+ 🛠️ Open-source. Lightweight. Transparent. HeliBoard isn't just a keyboard—it's a philosophy.
61
+ </p>
62
+ <p>
63
+ ✨ <strong>Weekly FOSS gems like this remind us: we have powerful alternatives, built by passionate devs, made for people who care. <em>Let's support that</em>.</strong>
64
+ </p>
65
+
66
+ `,
67
+ links: [
68
+ {
69
+ label: "GitHub",
70
+ href: "https://github.com/Helium314/HeliBoard",
71
+ },
72
+ {
73
+ label: "F-Droid",
74
+ href: "https://f-droid.org/packages/helium314.keyboard/",
75
+ },
76
+ {
77
+ label: "IzzyOnDroid",
78
+ href: "https://apt.izzysoft.de/fdroid/index/apk/helium314.keyboard",
79
+ },
80
+ ],
81
+ notes: [
82
+ "Network Pro&trade; <strong>highly recommends</strong> that Android users choose an open-source keyboard—ideally one that does not require internet permissions. Concerns remain valid around proprietary keyboards like Gboard and Microsoft SwiftKey, which may collect and store user input data."
83
+ ],
84
+ },
15
85
  {
16
86
  id: "eauth",
17
87
  images: {
@@ -23,7 +93,7 @@ export const fossData = [
23
93
  headline: "🔐 Elevate Your 2FA Game with Ente Auth — The Cross-Platform Open-Source Powerhouse!",
24
94
  headlineDescription: `
25
95
  <p>
26
- This week's <strong>FOSS Spotlight</strong> is on <strong>Ente Auth</strong> — the sleek, open-source 2FA authenticator that's putting privacy and usability front and center.
96
+ Discover <strong>Ente Auth</strong> — the sleek, open-source 2FA authenticator that's putting privacy and usability front and center.
27
97
  </p>
28
98
  <p>
29
99
  Whether you're a dev, a cybersecurity enthusiast, or simply serious about protecting your accounts, <strong>Ente Auth</strong> offers a next-level authentication experience — <strong>backed by encryption, not ads.</strong>
@@ -434,3 +504,5 @@ export const fossData = [
434
504
  notes: [],
435
505
  },
436
506
  ];
507
+
508
+ // cspell:ignore hboard gboard lsheet eauth tosdr
package/src/lib/images.js CHANGED
@@ -15,7 +15,7 @@ This file is part of Network Pro.
15
15
  * @description Provides convenient access to images in the src/lib/img directory
16
16
  * @module src/lib
17
17
  * @author SunDevil311
18
- * @updated 2025-05-28
18
+ * @updated 2025-05-30
19
19
  */
20
20
 
21
21
  // Import favicon images
@@ -41,6 +41,8 @@ import acodePng from "$lib/img/posts/acode.png";
41
41
  import acodeWbp from "$lib/img/posts/acode.webp";
42
42
  import eauthPng from "$lib/img/posts/eauth.png";
43
43
  import eauthWbp from "$lib/img/posts/eauth.webp";
44
+ import hboardPng from "$lib/img/posts/hboard.png";
45
+ import hboardWbp from "$lib/img/posts/hboard.webp";
44
46
  import lsheetPng from "$lib/img/posts/linksheet.png";
45
47
  import lsheetWbp from "$lib/img/posts/linksheet.webp";
46
48
  import pmxPng from "$lib/img/posts/pmx.png";
@@ -67,6 +69,8 @@ export {
67
69
  eauthWbp,
68
70
  faviconSvg,
69
71
  gplBadge,
72
+ hboardPng,
73
+ hboardWbp,
70
74
  logoPng,
71
75
  logoWbp,
72
76
  lsheetPng,
@@ -84,4 +88,4 @@ export {
84
88
  vcfSrc
85
89
  };
86
90
 
87
- // cspell:ignore eauth
91
+ // cspell:ignore eauth hboard
Binary file
Binary file
@@ -48,6 +48,16 @@ export function registerServiceWorker() {
48
48
  .then((registration) => {
49
49
  console.log("✅ Service Worker registered with scope:", registration.scope);
50
50
 
51
+ // 🧼 Manual cleanup of unexpected caches
52
+ caches.keys().then((keys) => {
53
+ keys.forEach((key) => {
54
+ if (!key.startsWith("cache-")) {
55
+ console.log("🧹 Deleting unexpected cache:", key);
56
+ caches.delete(key);
57
+ }
58
+ });
59
+ });
60
+
51
61
  registration.addEventListener("updatefound", () => {
52
62
  const newWorker = registration.installing;
53
63
  console.log("[SW-CLIENT] New service worker installing...");
@@ -33,7 +33,6 @@ const IGNORE_PATHS = new Set([
33
33
  "/docs/extensions.md",
34
34
  "/docs/Home.md",
35
35
  "/img/banner-1280x640.png",
36
- "/img/banner-og-1200x630.png",
37
36
  "/img/logo-transparent.png",
38
37
  "/img/logo.png",
39
38
  "/img/svelte.png",
@@ -55,6 +54,7 @@ const ASSETS = [
55
54
 
56
55
  const shouldExclude =
57
56
  path.startsWith("http") ||
57
+ path.startsWith("/assets/") ||
58
58
  disallowedHosts.some(
59
59
  (host) => hostname === host || hostname.endsWith(`.${host}`),
60
60
  ) ||
@@ -74,25 +74,105 @@ const ASSETS = [
74
74
 
75
75
  const uniqueExcludedAssets = [...new Set(excludedAssets)].sort();
76
76
 
77
+ /** @type {string[]} */
78
+ const REQUIRED_ASSETS = [
79
+ "/disableSw.js",
80
+ "/favicon.ico",
81
+ "/icon-192x192.png",
82
+ "/icon-512x512-maskable.png",
83
+ "/icon-512x512.png",
84
+ "/icon-contact.png",
85
+ "/icon-services.png",
86
+ "/icon-splash.png",
87
+ "/img/banner-og-1200x630.png",
88
+ "/img/qr/pgp-contact.png",
89
+ "/img/qr/pgp-github.png",
90
+ "/img/qr/pgp-support.png",
91
+ "/img/qr/vcard.png",
92
+ "/manifest.json",
93
+ "/offline.html",
94
+ "/offline.min.css",
95
+ "/screenshots/desktop-about.png",
96
+ "/screenshots/desktop-home.png",
97
+ "/screenshots/mobile-foss.png",
98
+ "/screenshots/mobile-home.png",
99
+ "/styles/brands.min.css",
100
+ "/styles/fontawesome.min.css",
101
+ "/styles/global.min.css",
102
+ "/styles/solid.min.css",
103
+ "/webfonts/fa-brands-400.woff2",
104
+ "/webfonts/fa-solid-900.woff2",
105
+ "/.well-known/dnt-policy-1.0.txt",
106
+ ];
107
+
77
108
  if (isDev) {
78
109
  console.log("[SW] Assets to precache:", ASSETS);
79
110
  console.log("[SW] Excluded assets:", uniqueExcludedAssets);
80
111
  }
81
112
 
113
+ /**
114
+ * Safely cache a list of assets, logging or throwing if required assets fail.
115
+ *
116
+ * @param {Cache} cache
117
+ * @param {string[]} assets
118
+ * @param {string[]} required
119
+ * @returns {Promise<string[]>} Cached asset paths
120
+ */
121
+ async function cacheAssetsSafely(cache, assets, required = []) {
122
+ /** @type {string[]} */
123
+ const cachedPaths = [];
124
+
125
+ await Promise.all(
126
+ assets.map(async (asset) => {
127
+ try {
128
+ await cache.add(asset);
129
+ cachedPaths.push(asset);
130
+ } catch (err) {
131
+ const msg =
132
+ err instanceof Error
133
+ ? `[SW] Failed to cache ${asset}: ${err.message}`
134
+ : `[SW] Failed to cache ${asset}: Unknown error`;
135
+
136
+ if (isDev) {
137
+ throw new Error(msg);
138
+ } else {
139
+ console.warn(msg);
140
+ }
141
+ }
142
+ }),
143
+ );
144
+
145
+ const missing = required.filter((req) => !cachedPaths.includes(req));
146
+ if (missing.length > 0) {
147
+ const errorMsg = `[SW] ⚠️ Missing required assets: ${missing.join(", ")}`;
148
+ if (isDev) throw new Error(errorMsg);
149
+ console.error(errorMsg);
150
+ }
151
+
152
+ return cachedPaths;
153
+ }
154
+
82
155
  // 🔹 Install event
83
156
  sw.addEventListener("install", (event) => {
84
157
  if (isDev) console.log("[SW] Install event");
158
+
85
159
  event.waitUntil(
86
160
  (async () => {
87
161
  const cache = await caches.open(CACHE);
162
+ let cachedPaths = [];
163
+
88
164
  try {
89
- await cache.addAll(ASSETS);
90
- if (isDev) console.log("[SW] Precaching complete");
91
- sw.skipWaiting();
92
- if (isDev) console.log("[SW] skipWaiting() called");
165
+ cachedPaths = await cacheAssetsSafely(cache, ASSETS, REQUIRED_ASSETS);
166
+ if (isDev) {
167
+ console.log("[SW] Cached assets:", cachedPaths);
168
+ }
93
169
  } catch (err) {
94
- if (isDev) console.warn("[SW] Failed to precache some assets:", err);
170
+ if (isDev) throw err;
171
+ console.warn("[SW] Error while precaching (non-fatal in prod):", err);
95
172
  }
173
+
174
+ await sw.skipWaiting();
175
+ if (isDev) console.log("[SW] skipWaiting() called");
96
176
  })(),
97
177
  );
98
178
  });
@@ -112,12 +192,12 @@ sw.addEventListener("activate", (event) => {
112
192
  tasks.push(
113
193
  caches.keys().then((keys) =>
114
194
  Promise.all(
115
- keys.map((key) => {
116
- if (key !== CACHE) {
195
+ keys
196
+ .filter((key) => key !== CACHE)
197
+ .map((key) => {
117
198
  if (isDev) console.log("[SW] Deleting old cache:", key);
118
199
  return caches.delete(key);
119
- }
120
- }),
200
+ }),
121
201
  ),
122
202
  ),
123
203
  );
Binary file
@@ -1,40 +0,0 @@
1
- /* ==========================================================================
2
- tsconfig.custom.jsonc
3
-
4
- NOTE: This file is for reference only and is not actively used in the build.
5
- The project uses the SvelteKit-generated .svelte-kit/tsconfig.json extended by
6
- jsconfig.json for actual TypeScript configuration.
7
-
8
- Copyright © 2025 Network Pro Strategies (Network Pro™)
9
- SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
10
- This file is part of Network Pro.
11
- ========================================================================== */
12
-
13
- {
14
- "extends": "./.svelte-kit/tsconfig.json", // Extend SvelteKit's generated tsconfig
15
- "compilerOptions": {
16
- "baseUrl": ".", // Base path for resolving non-relative imports
17
- "paths": {
18
- "$lib": ["src/lib"], // Alias for the lib directory
19
- "$lib/*": ["src/lib/*"], // Alias for lib subdirectories
20
- "$types": [".svelte-kit/types"] // Alias for SvelteKit types
21
- }
22
- },
23
- "include": [
24
- "src/**/*.ts", // Include TypeScript files
25
- "src/**/*.js", // Include JavaScript files
26
- "src/**/*.svelte", // Include Svelte files
27
- "tests/**/*.ts", // Include TypeScript test files
28
- "tests/**/*.js", // Include JavaScript test files
29
- "tests/**/*.svelte", // Include Svelte test files
30
- ".svelte-kit/types/**/*.d.ts" // Include SvelteKit-generated types
31
- ],
32
- "exclude": [
33
- "node_modules/**", // Exclude node_modules
34
- "dist/**", // Exclude distribution folder
35
- "src/service-worker.js", // Exclude service workers
36
- "src/service-worker/**/*.js",
37
- "src/service-worker.ts",
38
- "src/service-worker/**/*.ts"
39
- ]
40
- }