@networkpro/web 1.25.16 → 1.25.18

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.
@@ -45,7 +45,7 @@ jobs:
45
45
  - name: Upgrade npm
46
46
  run: |
47
47
  corepack enable
48
- npm install -g npm@11.6.2
48
+ npm install -g npm@11.7.0
49
49
 
50
50
  - name: Install Node.js dependencies
51
51
  run: npm ci
@@ -130,7 +130,7 @@ jobs:
130
130
  - name: Upgrade npm
131
131
  run: |
132
132
  corepack enable
133
- npm install -g npm@11.6.2
133
+ npm install -g npm@11.7.0
134
134
 
135
135
  - name: Install Node.js dependencies
136
136
  run: npm ci
@@ -186,7 +186,7 @@ jobs:
186
186
  - name: Upgrade npm
187
187
  run: |
188
188
  corepack enable
189
- npm install -g npm@11.6.2
189
+ npm install -g npm@11.7.0
190
190
 
191
191
  - name: Install Node.js dependencies
192
192
  run: npm ci
@@ -10,7 +10,7 @@ permissions:
10
10
 
11
11
  jobs:
12
12
  check-expiry:
13
- runs-on: ubuntu-latest
13
+ runs-on: ubuntu-24.04
14
14
  name: Validate .well-known/security.txt expiration
15
15
  env:
16
16
  ENV_MODE: ci
@@ -51,7 +51,7 @@ jobs:
51
51
  - name: Upgrade npm
52
52
  run: |
53
53
  corepack enable
54
- npm install -g npm@11.6.2
54
+ npm install -g npm@11.7.0
55
55
 
56
56
  - name: Clean previous Lighthouse reports
57
57
  run: |
@@ -41,7 +41,7 @@ jobs:
41
41
  - name: Upgrade npm
42
42
  run: |
43
43
  corepack enable
44
- npm install -g npm@11.6.2
44
+ npm install -g npm@11.7.0
45
45
 
46
46
  - name: Install Node.js dependencies
47
47
  run: npm ci
@@ -48,7 +48,7 @@ jobs:
48
48
  - name: Upgrade npm
49
49
  run: |
50
50
  corepack enable
51
- npm install -g npm@11.6.2
51
+ npm install -g npm@11.7.0
52
52
 
53
53
  - name: Install Node.js dependencies
54
54
  run: npm ci
@@ -134,7 +134,7 @@ jobs:
134
134
  - name: Upgrade npm
135
135
  run: |
136
136
  corepack enable
137
- npm install -g npm@11.6.2
137
+ npm install -g npm@11.7.0
138
138
 
139
139
  - name: Install Node.js dependencies
140
140
  run: npm ci
@@ -195,7 +195,7 @@ jobs:
195
195
  - name: Upgrade npm
196
196
  run: |
197
197
  corepack enable
198
- npm install -g npm@11.6.2
198
+ npm install -g npm@11.7.0
199
199
 
200
200
  - name: Install Node.js dependencies
201
201
  run: npm ci
@@ -53,7 +53,7 @@ jobs:
53
53
  - name: Upgrade npm
54
54
  run: |
55
55
  corepack enable
56
- npm install -g npm@11.6.2
56
+ npm install -g npm@11.7.0
57
57
 
58
58
  - name: Install Node.js dependencies
59
59
  run: npm ci
@@ -134,7 +134,7 @@ jobs:
134
134
  - name: Upgrade npm
135
135
  run: |
136
136
  corepack enable
137
- npm install -g npm@11.6.2
137
+ npm install -g npm@11.7.0
138
138
 
139
139
  - name: Install Node.js dependencies
140
140
  run: npm ci
@@ -190,7 +190,7 @@ jobs:
190
190
  - name: Upgrade npm
191
191
  run: |
192
192
  corepack enable
193
- npm install -g npm@11.6.2
193
+ npm install -g npm@11.7.0
194
194
 
195
195
  - name: Install Node.js dependencies
196
196
  run: npm ci
package/.ncurc.cjs CHANGED
@@ -31,7 +31,7 @@ This file is part of Network Pro.
31
31
  /** @type {import('npm-check-updates').RunOptions} */
32
32
  module.exports = {
33
33
  // Ignore specific dependencies (prevent upgrades)
34
- reject: ['vitest', '@vitest/coverage-v8', 'prettier', 'jsdom'],
34
+ reject: ['vitest', '@vitest/coverage-v8', 'prettier'],
35
35
 
36
36
  // Always upgrade devDependencies as well
37
37
  dep: 'prod,dev',
package/CHANGELOG.md CHANGED
@@ -22,6 +22,85 @@ This project attempts to follow [Keep a Changelog](https://keepachangelog.com/en
22
22
 
23
23
  ---
24
24
 
25
+ ## [1.25.18] - 2025-12-11
26
+
27
+ ### Changed
28
+
29
+ - Refreshed timestamp for root route in `sitemap.xml`.
30
+ - Reformatted the following files with Prettier:
31
+ - `src/lib/README.md`
32
+ - `src/lib/pages/LicenseContent.svelte`
33
+ - `src/lib/pages/PrivacyContent.svelte`
34
+ - `src/lib/pages/TermsUseContent.svelte`
35
+ - Bumped project version to `v1.25.18`.
36
+ - Updated dependencies:
37
+ - `prettier` `3.6.2` → `3.7.4`
38
+
39
+ ---
40
+
41
+ ## [1.25.17] - 2025-12-11
42
+
43
+ ### Added
44
+
45
+ - Added SSR boundary protection test (`tests/unit/server/internal/ssrBoundary.test.js`):
46
+ - Detects Node-only imports (`jsdom`, `fs`, `path`, etc.) in client-visible modules.
47
+ - Ensures imports are properly gated behind `import.meta.env.SSR`.
48
+ - Prevents accidental SSR/client boundary violations in future code changes.
49
+ - Added support for detecting SSR-safe code paths by allowing SSR-gated dynamic imports in shared modules.
50
+
51
+ ### Changed
52
+
53
+ - Refactored `src/service-worker.js` for improved consistency, clarity, and lint compatibility:
54
+ - Removed unused function parameters (`_err`) and adjusted callback signatures to align with ESLint expectations.
55
+ - Replaced anonymous no-op parameters with explicitly ignored placeholders using the `_` naming convention.
56
+ - Improved async iteration patterns in asset caching logic for better readability and maintainability.
57
+ - Updated JSDoc annotations for accuracy and improved editor support.
58
+ - Ensured all cache operations conform to structured error-handling patterns consistent with the rest of the codebase.
59
+
60
+ - Updated `src/lib/utils/purify.js`:
61
+ - Replaced `typeof window !== 'undefined'` guard with compile-time `import.meta.env.SSR`.
62
+ - Ensures Vite tree-shakes `jsdom` imports from client bundles.
63
+ - Fixed build failures caused by jsdom/cssstyle when bundled on the client.
64
+ - Preserves existing DOMPurify caching and SSR behavior.
65
+
66
+ - Enhanced ESLint `no-unused-vars` rule in `eslint.config.mjs`:
67
+ - Added support for ignoring unused catch parameters via `caughtErrors` and `caughtErrorsIgnorePattern`.
68
+ - Prevented false positives on intentionally unused error variables (e.g., `_err`).
69
+ - Expanded ignore patterns to match project coding conventions.
70
+
71
+ - Replaced `src/lib/img/qr/vcard.png` and `src/lib/img/qr/vcard.webp` with revised versions.
72
+ - Updated GitHub workflows to utilize **npm** `11.7.0`.
73
+ - Updated generator metadata in `src/app.html` to reflect **SvelteKit 2.49.2**.
74
+ - Updated `src/lib/README.md` to reflect the newly updated app constant.
75
+ - Updated contact information in `static/bin/contact.vcf`.
76
+ - Updated `CONTACT.PHONE` app constant to reflect our new phone number, (602) 428-5300.
77
+ - Removed `jsdom` from `.ncurc.cjs` `reject` list.
78
+ - Bumped project version to `v1.25.17`.
79
+ - Updated dependencies:
80
+ - `dompurify` `^3.3.0` → `^3.3.1`
81
+ - `posthog-js` `^1.295.0` → `^1.305.0`
82
+ - `svelte` `5.43.12` → `5.45.9`
83
+ - `@playwright/test` `^1.56.1` → `^1.57.0`
84
+ - `@sveltejs/adapter-vercel` `^6.1.1` → `^6.2.0`
85
+ - `@sveltejs/kit` `2.48.5` → `2.49.2`
86
+ - `browserslist` `^4.28.0` → `^4.28.1`
87
+ - `eslint-plugin-jsdoc` `^61.2.1` → `^61.5.0`
88
+ - `eslint-plugin-svelte` `^3.13.0` → `^3.13.1`
89
+ - `markdownlint` `^0.39.0` → `^0.40.0`
90
+ - `markdownlint-cli2` `0.19.0` → `0.20.0`
91
+ - `playwright` `^1.56.1` → `^1.57.0`
92
+ - `stylelint` `^16.25.0` → `^16.26.1`
93
+ - `svelte-eslint-parser` `^1.4.0` → `^1.4.1`
94
+ - `vite` `^7.2.2` → `^7.2.7`
95
+ - `jsdom` `26.1.0` → `27.3.0`
96
+
97
+ ### Fixed
98
+
99
+ - Resolved client-side build failures caused by dynamic jsdom imports leaking into the Vite dependency graph.
100
+ - Resolved false positive ESLint errors for unused catch bindings in JS modules.
101
+
102
+ ---
103
+
25
104
  ## [1.25.16] - 2025-11-18
26
105
 
27
106
  ### Changed
@@ -1961,7 +2040,9 @@ This enables analytics filtering and CSP hardening for the audit environment.
1961
2040
 
1962
2041
  <!-- Link references -->
1963
2042
 
1964
- [Unreleased]: https://github.com/netwk-pro/netwk-pro.github.io/compare/v1.25.16...HEAD
2043
+ [Unreleased]: https://github.com/netwk-pro/netwk-pro.github.io/compare/v1.25.18...HEAD
2044
+ [1.25.18]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.25.18
2045
+ [1.25.17]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.25.17
1965
2046
  [1.25.16]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.25.16
1966
2047
  [1.25.15]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.25.15
1967
2048
  [1.25.14]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.25.14
package/eslint.config.mjs CHANGED
@@ -65,14 +65,27 @@ export default [
65
65
  ...js.configs.recommended.rules, // ESLint's core recommended rules (scoped)
66
66
  ...eslintConfigPrettier.rules, // Prettier config to disable conflicting ESLint rules (scoped)
67
67
  ...ESLINT_RULES, // Additional custom rules
68
- 'no-unused-vars': ['error', { argsIgnorePattern: '^_' }], // Ignore unused variables starting with an underscore
68
+
69
+ // Updated unused variable handling:
70
+ // - Ignore args starting with "_"
71
+ // - Ignore vars starting with "_"
72
+ // - Allow unused catch variables named "_err" or any "_*"
73
+ 'no-unused-vars': [
74
+ 'error',
75
+ {
76
+ argsIgnorePattern: '^_',
77
+ varsIgnorePattern: '^_',
78
+ caughtErrors: 'all',
79
+ caughtErrorsIgnorePattern: '^_',
80
+ },
81
+ ],
82
+
69
83
  'jsdoc/check-alignment': 'warn', // Ensure JSDoc block tags are aligned
70
84
  'jsdoc/check-param-names': 'warn', // Checks parameter names in JSDoc
71
- // Updated rule to allow the @updated tag
72
85
  'jsdoc/check-tag-names': [
73
86
  'warn',
74
87
  {
75
- definedTags: ['updated'],
88
+ definedTags: ['updated'], // Allow custom @updated tag
76
89
  },
77
90
  ],
78
91
  'jsdoc/check-types': 'warn', // Checks if types in JSDoc are defined correctly
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@networkpro/web",
3
3
  "private": false,
4
- "version": "1.25.16",
4
+ "version": "1.25.18",
5
5
  "description": "Locking Down Networks, Unlocking Confidence™ | Security, Networking, Privacy — Network Pro Strategies",
6
6
  "keywords": [
7
7
  "advisory",
@@ -85,49 +85,50 @@
85
85
  "pre-push": "if [ \"$CI\" = \"true\" ]; then exit 0; else npm run checkout; fi"
86
86
  },
87
87
  "dependencies": {
88
- "dompurify": "^3.3.0",
89
- "posthog-js": "^1.295.0",
88
+ "dompurify": "^3.3.1",
89
+ "posthog-js": "^1.305.0",
90
90
  "semver": "^7.7.3",
91
- "svelte": "5.43.12"
91
+ "svelte": "5.45.9"
92
92
  },
93
93
  "devDependencies": {
94
94
  "@eslint/compat": "^2.0.0",
95
95
  "@eslint/js": "^9.39.1",
96
96
  "@lhci/cli": "^0.15.1",
97
- "@playwright/test": "^1.56.1",
97
+ "@playwright/test": "^1.57.0",
98
98
  "@sveltejs/adapter-netlify": "^5.2.4",
99
- "@sveltejs/adapter-vercel": "^6.1.1",
100
- "@sveltejs/kit": "2.48.5",
99
+ "@sveltejs/adapter-vercel": "^6.2.0",
100
+ "@sveltejs/kit": "2.49.2",
101
101
  "@sveltejs/vite-plugin-svelte": "^6.2.1",
102
102
  "@testing-library/jest-dom": "^6.9.1",
103
103
  "@testing-library/svelte": "^5.2.9",
104
104
  "@vitest/coverage-v8": "3.2.4",
105
105
  "autoprefixer": "^10.4.22",
106
- "browserslist": "^4.28.0",
106
+ "browserslist": "^4.28.1",
107
107
  "eslint": "^9.39.1",
108
108
  "eslint-config-prettier": "^10.1.8",
109
- "eslint-plugin-jsdoc": "^61.2.1",
110
- "eslint-plugin-svelte": "^3.13.0",
109
+ "eslint-plugin-jsdoc": "^61.5.0",
110
+ "eslint-plugin-svelte": "^3.13.1",
111
111
  "globals": "^16.5.0",
112
- "jsdom": "26.1.0",
112
+ "globby": "^16.0.0",
113
+ "jsdom": "27.3.0",
113
114
  "lightningcss": "^1.30.2",
114
- "markdownlint": "^0.39.0",
115
- "markdownlint-cli2": "0.19.0",
115
+ "markdownlint": "^0.40.0",
116
+ "markdownlint-cli2": "0.20.0",
116
117
  "npm-run-all": "^4.1.5",
117
- "playwright": "^1.56.1",
118
+ "playwright": "^1.57.0",
118
119
  "postcss": "^8.5.6",
119
- "prettier": "3.6.2",
120
+ "prettier": "3.7.4",
120
121
  "prettier-plugin-svelte": "^3.4.0",
121
122
  "simple-git-hooks": "^2.13.1",
122
- "stylelint": "^16.25.0",
123
+ "stylelint": "^16.26.1",
123
124
  "stylelint-config-html": "^1.1.0",
124
125
  "stylelint-config-recommended": "^17.0.0",
125
126
  "stylelint-order": "^7.0.0",
126
127
  "svelte-check": "^4.3.4",
127
- "svelte-eslint-parser": "^1.4.0",
128
+ "svelte-eslint-parser": "^1.4.1",
128
129
  "svelte-preprocess": "^6.0.3",
129
130
  "typescript": "^5.9.3",
130
- "vite": "^7.2.2",
131
+ "vite": "^7.2.7",
131
132
  "vite-plugin-devtools-json": "^1.0.0",
132
133
  "vite-plugin-lightningcss": "^0.0.5",
133
134
  "vite-tsconfig-paths": "^5.1.4",
package/src/app.html CHANGED
@@ -53,7 +53,7 @@
53
53
  content="bx4ham0zkpvzztzu213bhpt76m9siq" />
54
54
  <!-- cspell:enable -->
55
55
 
56
- <meta name="generator" content="SvelteKit 2.48.5" />
56
+ <meta name="generator" content="SvelteKit 2.49.2" />
57
57
 
58
58
  <script src="/disableSw.js"></script>
59
59
 
package/src/lib/README.md CHANGED
@@ -84,7 +84,7 @@ console.log(CONSTANTS.COMPANY_INFO.APP_NAME); // "Network Pro"
84
84
  | Key | Description | Example |
85
85
  | ---------- | ---------------------------- | ------------------------ |
86
86
  | `NAME` | Full company name | `Network Pro Strategies` |
87
- | `APP_NAME` | Application or branding name | `Network Pro™` |
87
+ | `APP_NAME` | Application or branding name | `Network Pro™` |
88
88
  | `YEAR` | Copyright / app year | `2025` |
89
89
 
90
90
  ### 📬 CONTACT
@@ -97,7 +97,7 @@ console.log(CONSTANTS.COMPANY_INFO.APP_NAME); // "Network Pro"
97
97
  | `SECURE_LINK` | Secure contact address (link) | `contact@s.neteng.pro` |
98
98
  | `PRIVACY` | Privacy-related contact | `privacy (at) netwk.pro` |
99
99
  | `PRIVACY_LINK` | Privacy-related contact (link) | `privacy@netwk.pro` |
100
- | `PHONE` | Company phone number | `(623) 252-4350` |
100
+ | `PHONE` | Company phone number | `(602) 428-5300` |
101
101
 
102
102
  ### 🗂️ PAGE
103
103
 
Binary file
Binary file
package/src/lib/index.js CHANGED
@@ -62,7 +62,7 @@ export const CONSTANTS = {
62
62
  SECURE_LINK: 'contact@s.neteng.pro',
63
63
  PRIVACY: 'privacy (at) netwk.pro',
64
64
  PRIVACY_LINK: 'privacy@netwk.pro',
65
- PHONE: '(623) 252-4350',
65
+ PHONE: '(602) 428-5300',
66
66
  },
67
67
  PAGE: {
68
68
  BLANK: '_blank',
@@ -313,8 +313,8 @@ This file is part of Network Pro.
313
313
  </p>
314
314
 
315
315
  <p>
316
- {COMPANY_INFO.APP_NAME} is free software: you can redistribute it and/or
317
- modify it under the terms of the
316
+ {COMPANY_INFO.APP_NAME} is free software: you can redistribute it and/or modify
317
+ it under the terms of the
318
318
  <strong>GNU General Public License</strong> (GNU GPL) as published by
319
319
  the
320
320
  <a rel={PAGE.REL} href="https://fsf.org" target={PAGE.BLANK}
@@ -163,8 +163,8 @@ This file is part of Network Pro.
163
163
  {COMPANY_INFO.NAME} ("Company," "we," "us," or "our") is committed to protecting
164
164
  the privacy of clients and website visitors. This Privacy Policy outlines
165
165
  how we collect, use, and safeguard your information when you interact with
166
- our website or services, consistent with applicable U.S. federal law and
167
- Arizona law, including Title 18, Chapter 5, Article 4 of the
166
+ our website or services, consistent with applicable U.S. federal law and Arizona
167
+ law, including Title 18, Chapter 5, Article 4 of the
168
168
  <strong>
169
169
  <a
170
170
  rel={PAGE.REL}
@@ -222,8 +222,8 @@ This file is part of Network Pro.
222
222
  opt-out and opt-in settings stored as browser cookies. These settings
223
223
  override any Do Not Track (DNT) or Global Privacy Control (GPC) signals. <strong
224
224
  >If you opt out, analytics tracking via PostHog is disabled entirely
225
- until you change your preference.</strong> Your selection will persist
226
- until manually updated.
225
+ until you change your preference.</strong> Your selection will persist until
226
+ manually updated.
227
227
  </p>
228
228
  <p class="emphasis">
229
229
  For convenient access, you can manage these settings through our <a
@@ -367,10 +367,10 @@ This file is part of Network Pro.
367
367
  <strong>Business Transfers</strong>: In the event of a merger,
368
368
  acquisition, or sale of assets, personal and business information may
369
369
  be transferred
370
- <em>only if the receiving party provides written assurances</em> that:
371
- (a) the information will not be sold or misused, (b) it will be handled
372
- in a manner consistent with our privacy commitments, and (c) appropriate
373
- technical and contractual safeguards are in place to protect it.
370
+ <em>only if the receiving party provides written assurances</em> that: (a)
371
+ the information will not be sold or misused, (b) it will be handled in a
372
+ manner consistent with our privacy commitments, and (c) appropriate technical
373
+ and contractual safeguards are in place to protect it.
374
374
  </li>
375
375
  </ul>
376
376
  <p>
@@ -402,8 +402,8 @@ This file is part of Network Pro.
402
402
 
403
403
  <ul>
404
404
  <li>
405
- <strong>Access, correct, or delete</strong> your personal information,
406
- subject to legal and contractual limitations;
405
+ <strong>Access, correct, or delete</strong> your personal information, subject
406
+ to legal and contractual limitations;
407
407
  </li>
408
408
  <li>
409
409
  <strong
@@ -445,10 +445,10 @@ This file is part of Network Pro.
445
445
  </p>
446
446
  {:else if link.id === 'disclaimers'}
447
447
  <p>
448
- {COMPANY_INFO.NAME} offers informational content as a public service. No
449
- warranties are made regarding the accuracy or completeness of such content.
450
- Consulting services are governed by separate contracts. We disclaim liability
451
- for third-party services integrated or referenced.
448
+ {COMPANY_INFO.NAME} offers informational content as a public service. No warranties
449
+ are made regarding the accuracy or completeness of such content. Consulting
450
+ services are governed by separate contracts. We disclaim liability for third-party
451
+ services integrated or referenced.
452
452
  </p>
453
453
  {:else if link.id === 'changes'}
454
454
  <p>
@@ -197,8 +197,8 @@ This file is part of Network Pro.
197
197
  <p>
198
198
  {COMPANY_INFO.NAME} is based in Maricopa County, Arizona. Any legal action
199
199
  or dispute arising from these Terms of Use shall be subject to the exclusive
200
- jurisdiction of the state and federal courts located in Maricopa County,
201
- Arizona. These Terms shall be governed by the
200
+ jurisdiction of the state and federal courts located in Maricopa County, Arizona.
201
+ These Terms shall be governed by the
202
202
  <strong>Arizona Revised Statutes (A.R.S.)</strong> and applicable
203
203
  provisions of the <strong>United States Code (U.S.C.)</strong>.
204
204
  </p>
@@ -10,9 +10,9 @@ This file is part of Network Pro.
10
10
  * @file purify.js
11
11
  * @description Universal DOMPurify instance for SSR + client with safe build support.
12
12
  * Secures untrusted HTML before injecting it into the DOM.
13
- * @module src/lib/utils/
13
+ * @module src/lib/utils
14
14
  * @author Scott Lopez
15
- * @updated 2025-06-01
15
+ * @updated 2025-12-11
16
16
  */
17
17
 
18
18
  import createDOMPurify from 'dompurify';
@@ -37,11 +37,11 @@ let jsdomWindow = null;
37
37
  export async function getDOMPurify() {
38
38
  if (DOMPurifyInstance) return DOMPurifyInstance;
39
39
 
40
- if (typeof window !== 'undefined') {
40
+ if (!import.meta.env.SSR) {
41
41
  // ✅ Client-side: use native window
42
42
  DOMPurifyInstance = createDOMPurify(window);
43
43
  } else {
44
- // ✅ SSR: dynamically import jsdom to avoid bundling
44
+ // ✅ SSR: dynamically import jsdom gated so Vite will tree-shake it from the client bundle
45
45
  const { JSDOM } = await import('jsdom');
46
46
  jsdomWindow = jsdomWindow || new JSDOM('').window;
47
47
  DOMPurifyInstance = createDOMPurify(jsdomWindow);
@@ -6,18 +6,20 @@ 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
- /** @type {ServiceWorkerGlobalScope} */
9
+ /// <reference lib="webworker" />
10
+ /// <reference types="vite/client" />
11
+
12
+ /**
13
+ * @type {ServiceWorkerGlobalScope}
14
+ */
10
15
  const sw = /** @type {ServiceWorkerGlobalScope} */ (
11
16
  /** @type {unknown} */ (self)
12
17
  );
13
18
 
14
- /// <reference types="vite/client" />
15
-
16
19
  const isDev = location.hostname === 'localhost';
17
- const disallowedHosts = [
18
- 'us.i.posthog.com', // Add PostHog to disallowed hosts
19
- 'posthog.com', // Add PostHog to disallowed hosts
20
- ];
20
+
21
+ /** @type {string[]} */
22
+ const disallowedHosts = ['us.i.posthog.com', 'posthog.com'];
21
23
 
22
24
  import { build, files, version } from '$service-worker';
23
25
 
@@ -27,6 +29,7 @@ const CACHE = `cache-${version}`;
27
29
  /** @type {string[]} */
28
30
  const excludedAssets = [];
29
31
 
32
+ /** @type {Set<string>} */
30
33
  const IGNORE_PATHS = new Set([
31
34
  '/.well-known/security.txt.sig',
32
35
  '/img/banner-1280x640.png',
@@ -76,6 +79,7 @@ const ASSETS = [
76
79
  ),
77
80
  ];
78
81
 
82
+ /** @type {string[]} */
79
83
  const uniqueExcludedAssets = [...new Set(excludedAssets)].sort();
80
84
 
81
85
  /** @type {string[]} */
@@ -108,12 +112,12 @@ if (isDev) {
108
112
  }
109
113
 
110
114
  /**
111
- * Safely cache a list of assets, logging or throwing if required assets fail.
115
+ * Safely cache a list of assets.
112
116
  *
113
117
  * @param {Cache} cache
114
118
  * @param {string[]} assets
115
- * @param {string[]} required
116
- * @returns {Promise<string[]>} Cached asset paths
119
+ * @param {string[]} [required=[]]
120
+ * @returns {Promise<string[]>}
117
121
  */
118
122
  async function cacheAssetsSafely(cache, assets, required = []) {
119
123
  /** @type {string[]} */
@@ -150,6 +154,9 @@ async function cacheAssetsSafely(cache, assets, required = []) {
150
154
  }
151
155
 
152
156
  // 🔹 Install event
157
+ /**
158
+ * @param {ExtendableEvent} event
159
+ */
153
160
  sw.addEventListener('install', (event) => {
154
161
  if (isDev) console.log('[SW] Install event');
155
162
 
@@ -160,9 +167,7 @@ sw.addEventListener('install', (event) => {
160
167
 
161
168
  try {
162
169
  cachedPaths = await cacheAssetsSafely(cache, ASSETS, REQUIRED_ASSETS);
163
- if (isDev) {
164
- console.log('[SW] Cached assets:', cachedPaths);
165
- }
170
+ if (isDev) console.log('[SW] Cached assets:', cachedPaths);
166
171
  } catch (err) {
167
172
  if (isDev) throw err;
168
173
  console.warn('[SW] Error while precaching (non-fatal in prod):', err);
@@ -175,8 +180,12 @@ sw.addEventListener('install', (event) => {
175
180
  });
176
181
 
177
182
  // 🔹 Activate event
183
+ /**
184
+ * @param {ExtendableEvent} event
185
+ */
178
186
  sw.addEventListener('activate', (event) => {
179
187
  if (isDev) console.log('[SW] Activate event');
188
+
180
189
  event.waitUntil(
181
190
  (async () => {
182
191
  const tasks = [];
@@ -210,9 +219,7 @@ sw.addEventListener('activate', (event) => {
210
219
  });
211
220
 
212
221
  /**
213
- * Determine if a request should be skipped by the service worker.
214
- * Specifically filters out dev/build files, module imports, and source files.
215
- * Only active in development mode.
222
+ * Determine if a request should be ignored during development.
216
223
  *
217
224
  * @param {URL} url
218
225
  * @returns {boolean}
@@ -230,13 +237,13 @@ function shouldSkipDevModule(url) {
230
237
  }
231
238
 
232
239
  // 🔹 Fetch event
240
+ /**
241
+ * @param {FetchEvent} event
242
+ */
233
243
  sw.addEventListener('fetch', (event) => {
234
244
  const requestUrl = new URL(event.request.url);
235
245
 
236
- // ✅ Skip cross-origin requests
237
246
  if (requestUrl.origin !== location.origin) return;
238
-
239
- // ✅ Skip internal dev/module files (only in dev)
240
247
  if (shouldSkipDevModule(requestUrl)) return;
241
248
 
242
249
  if (isDev) console.log('[SW] Fetch intercepted:', event.request.url);
@@ -253,12 +260,8 @@ sw.addEventListener('fetch', (event) => {
253
260
  if (event.request.mode === 'navigate') {
254
261
  const preloadResponse = await event.preloadResponse;
255
262
  if (preloadResponse) {
256
- if (isDev) {
257
- console.log(
258
- '[SW] Using preload response for:',
259
- event.request.url,
260
- );
261
- }
263
+ if (isDev)
264
+ console.log('[SW] Using preload response:', event.request.url);
262
265
  return preloadResponse;
263
266
  }
264
267
  }
@@ -267,18 +270,17 @@ sw.addEventListener('fetch', (event) => {
267
270
  console.log('[SW] Fetching from network:', event.request.url);
268
271
 
269
272
  return await fetch(event.request);
270
- } catch (err) {
271
- if (isDev) {
273
+ } catch (_err) {
274
+ if (isDev)
272
275
  console.warn(
273
- '[SW] Fetch failed; offline fallback used:',
276
+ '[SW] Fetch failed; offline fallback:',
274
277
  event.request.url,
275
- err,
276
278
  );
277
- }
278
279
 
279
280
  if (event.request.mode === 'navigate') {
280
281
  const offline = await caches.match('/offline.html');
281
282
  if (offline) return offline;
283
+
282
284
  return new Response('<h1>Offline</h1>', {
283
285
  headers: { 'Content-Type': 'text/html' },
284
286
  });
@@ -289,5 +291,3 @@ sw.addEventListener('fetch', (event) => {
289
291
  })(),
290
292
  );
291
293
  });
292
-
293
- // @cspell:ignore precaching
@@ -2,11 +2,11 @@ BEGIN:VCARD
2
2
  VERSION:3.0
3
3
  FN:Scott Lopez
4
4
  N:Lopez;Scott
5
- TEL;TYPE=WORK,PREF=1:(623) 252-4350
5
+ TEL;TYPE=WORK,PREF=1:(602) 428-5300
6
6
  EMAIL;TYPE=WORK:support@netwk.pro
7
7
  EMAIL;TYPE=Secure:business@s.neteng.pro
8
8
  ADR;TYPE=WORK:;;Peoria\, AZ 85382\nUS
9
9
  ORG:Network Pro Strategies
10
- TITLE:Network Engineer
10
+ TITLE:Network Engineer and Consultant
11
11
  URL:https://netwk.pro
12
12
  END:VCARD
@@ -1,5 +1,5 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <!-- Sitemap last updated 2025-11-09 -->
2
+ <!-- Sitemap last updated 2025-12-11 -->
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-11-09</lastmod>
10
+ <lastmod>2025-12-11</lastmod>
11
11
 
12
12
  <changefreq>weekly</changefreq>
13
13
 
@@ -0,0 +1,107 @@
1
+ /* ==========================================================================
2
+ tests/unit/server/ssrBoundary.test.js
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
+ /**
10
+ * @file ssrBoundary.test.js
11
+ * @description Checks for improper usage of Node
12
+ * @module tests/unit/server/internal
13
+ * @author Scott Lopez
14
+ * @updated 2025-12-11
15
+ */
16
+
17
+ // @vitest-environment node
18
+
19
+ import fs from 'fs/promises';
20
+ import { globby } from 'globby';
21
+
22
+ // Node-only modules that cannot appear in client-visible code
23
+ const NODE_ONLY_IMPORTS = [
24
+ 'fs',
25
+ 'path',
26
+ 'url',
27
+ 'crypto',
28
+ 'os',
29
+ 'child_process',
30
+ 'module',
31
+ 'jsdom',
32
+ ];
33
+
34
+ // Files in these locations are ALWAYS allowed to use Node-only modules
35
+ const SERVER_ONLY_ALLOWLIST = [
36
+ 'src/lib/server/',
37
+ '/server/',
38
+ '+server.js',
39
+ '+server.ts',
40
+ '.test.',
41
+ '.spec.',
42
+ 'vitest.config',
43
+ 'playwright.config',
44
+ ];
45
+
46
+ function isServerOnlyFile(filePath) {
47
+ return SERVER_ONLY_ALLOWLIST.some((key) => filePath.includes(key));
48
+ }
49
+
50
+ // Regex helpers
51
+ function createStaticImportRegex(moduleName) {
52
+ return new RegExp(`import\\s+[^;]*['"]${moduleName}['"]`);
53
+ }
54
+
55
+ function createDynamicImportRegex(moduleName) {
56
+ return new RegExp(`import\\(['"]${moduleName}['"]\\)`);
57
+ }
58
+
59
+ function hasSSRGuard(text) {
60
+ // Basic detection of SSR guard presence
61
+ // Stronger variants are possible, but this avoids false positives
62
+ return /import\.meta\.env\.SSR/.test(text);
63
+ }
64
+
65
+ test('no Node-only modules leak into client-visible modules', async () => {
66
+ const files = await globby([
67
+ 'src/**/*.{js,ts,svelte}',
68
+ '!src/lib/server/**', // ignore server-only utilities
69
+ '!**/*.test.*',
70
+ '!**/*.spec.*',
71
+ ]);
72
+
73
+ const violations = [];
74
+
75
+ for (const file of files) {
76
+ if (isServerOnlyFile(file)) continue;
77
+
78
+ const text = await fs.readFile(file, 'utf8');
79
+
80
+ for (const mod of NODE_ONLY_IMPORTS) {
81
+ const staticMatch = createStaticImportRegex(mod).test(text);
82
+ const dynamicMatch = createDynamicImportRegex(mod).test(text);
83
+
84
+ if (!staticMatch && !dynamicMatch) continue;
85
+
86
+ // If SSR guarded, allow it
87
+ if (hasSSRGuard(text)) continue;
88
+
89
+ violations.push({
90
+ file,
91
+ module: mod,
92
+ });
93
+ }
94
+ }
95
+
96
+ if (violations.length > 0) {
97
+ const formatted = violations
98
+ .map((v) => `❌ ${v.module} imported in ${v.file}`)
99
+ .join('\n');
100
+
101
+ throw new Error(
102
+ 'SSR boundary violations detected:\n' +
103
+ formatted +
104
+ '\n\nTo fix: move to src/lib/server/, or wrap the import in import.meta.env.SSR.',
105
+ );
106
+ }
107
+ });
package/static/CNAME DELETED
@@ -1 +0,0 @@
1
- netwk.pro