@networkpro/web 1.25.16 → 1.25.17
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/.github/workflows/build-and-publish.yml +3 -3
- package/.github/workflows/check-security-txt-expiry.yml +1 -1
- package/.github/workflows/lighthouse.yml +1 -1
- package/.github/workflows/playwright.yml +1 -1
- package/.github/workflows/publish-test.yml +3 -3
- package/.github/workflows/templates/publish.template.yml +3 -3
- package/.ncurc.cjs +1 -1
- package/CHANGELOG.md +65 -1
- package/eslint.config.mjs +16 -3
- package/package.json +18 -17
- package/src/app.html +1 -1
- package/src/lib/README.md +1 -1
- package/src/lib/img/qr/vcard.png +0 -0
- package/src/lib/img/qr/vcard.webp +0 -0
- package/src/lib/index.js +1 -1
- package/src/lib/utils/purify.js +4 -4
- package/src/service-worker.js +32 -32
- package/static/bin/contact.vcf +2 -2
- package/tests/unit/server/internal/ssrBoundary.test.js +107 -0
- package/static/CNAME +0 -1
|
@@ -45,7 +45,7 @@ jobs:
|
|
|
45
45
|
- name: Upgrade npm
|
|
46
46
|
run: |
|
|
47
47
|
corepack enable
|
|
48
|
-
npm install -g npm@11.
|
|
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.
|
|
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.
|
|
189
|
+
npm install -g npm@11.7.0
|
|
190
190
|
|
|
191
191
|
- name: Install Node.js dependencies
|
|
192
192
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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'
|
|
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,69 @@ This project attempts to follow [Keep a Changelog](https://keepachangelog.com/en
|
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
|
25
|
+
## [1.25.17] - 2025-12-11
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- Added SSR boundary protection test (`tests/unit/server/internal/ssrBoundary.test.js`):
|
|
30
|
+
- Detects Node-only imports (`jsdom`, `fs`, `path`, etc.) in client-visible modules.
|
|
31
|
+
- Ensures imports are properly gated behind `import.meta.env.SSR`.
|
|
32
|
+
- Prevents accidental SSR/client boundary violations in future code changes.
|
|
33
|
+
- Added support for detecting SSR-safe code paths by allowing SSR-gated dynamic imports in shared modules.
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
|
|
37
|
+
- Refactored `src/service-worker.js` for improved consistency, clarity, and lint compatibility:
|
|
38
|
+
- Removed unused function parameters (`_err`) and adjusted callback signatures to align with ESLint expectations.
|
|
39
|
+
- Replaced anonymous no-op parameters with explicitly ignored placeholders using the `_` naming convention.
|
|
40
|
+
- Improved async iteration patterns in asset caching logic for better readability and maintainability.
|
|
41
|
+
- Updated JSDoc annotations for accuracy and improved editor support.
|
|
42
|
+
- Ensured all cache operations conform to structured error-handling patterns consistent with the rest of the codebase.
|
|
43
|
+
|
|
44
|
+
- Updated `src/lib/utils/purify.js`:
|
|
45
|
+
- Replaced `typeof window !== 'undefined'` guard with compile-time `import.meta.env.SSR`.
|
|
46
|
+
- Ensures Vite tree-shakes `jsdom` imports from client bundles.
|
|
47
|
+
- Fixed build failures caused by jsdom/cssstyle when bundled on the client.
|
|
48
|
+
- Preserves existing DOMPurify caching and SSR behavior.
|
|
49
|
+
|
|
50
|
+
- Enhanced ESLint `no-unused-vars` rule in `eslint.config.mjs`:
|
|
51
|
+
- Added support for ignoring unused catch parameters via `caughtErrors` and `caughtErrorsIgnorePattern`.
|
|
52
|
+
- Prevented false positives on intentionally unused error variables (e.g., `_err`).
|
|
53
|
+
- Expanded ignore patterns to match project coding conventions.
|
|
54
|
+
|
|
55
|
+
- Replaced `src/lib/img/qr/vcard.png` and `src/lib/img/qr/vcard.webp` with revised versions.
|
|
56
|
+
- Updated GitHub workflows to utilize **npm** `11.7.0`.
|
|
57
|
+
- Updated generator metadata in `src/app.html` to reflect **SvelteKit 2.49.2**.
|
|
58
|
+
- Updated `src/lib/README.md` to reflect the newly updated app constant.
|
|
59
|
+
- Updated contact information in `static/bin/contact.vcf`.
|
|
60
|
+
- Updated `CONTACT.PHONE` app constant to reflect our new phone number, (602) 428-5300.
|
|
61
|
+
- Removed `jsdom` from `.ncurc.cjs` `reject` list.
|
|
62
|
+
- Bumped project version to `v1.25.17`.
|
|
63
|
+
- Updated dependencies:
|
|
64
|
+
- `dompurify` `^3.3.0` → `^3.3.1`
|
|
65
|
+
- `posthog-js` `^1.295.0` → `^1.305.0`
|
|
66
|
+
- `svelte` `5.43.12` → `5.45.9`
|
|
67
|
+
- `@playwright/test` `^1.56.1` → `^1.57.0`
|
|
68
|
+
- `@sveltejs/adapter-vercel` `^6.1.1` → `^6.2.0`
|
|
69
|
+
- `@sveltejs/kit` `2.48.5` → `2.49.2`
|
|
70
|
+
- `browserslist` `^4.28.0` → `^4.28.1`
|
|
71
|
+
- `eslint-plugin-jsdoc` `^61.2.1` → `^61.5.0`
|
|
72
|
+
- `eslint-plugin-svelte` `^3.13.0` → `^3.13.1`
|
|
73
|
+
- `markdownlint` `^0.39.0` → `^0.40.0`
|
|
74
|
+
- `markdownlint-cli2` `0.19.0` → `0.20.0`
|
|
75
|
+
- `playwright` `^1.56.1` → `^1.57.0`
|
|
76
|
+
- `stylelint` `^16.25.0` → `^16.26.1`
|
|
77
|
+
- `svelte-eslint-parser` `^1.4.0` → `^1.4.1`
|
|
78
|
+
- `vite` `^7.2.2` → `^7.2.7`
|
|
79
|
+
- `jsdom` `26.1.0` → `27.3.0`
|
|
80
|
+
|
|
81
|
+
### Fixed
|
|
82
|
+
|
|
83
|
+
- Resolved client-side build failures caused by dynamic jsdom imports leaking into the Vite dependency graph.
|
|
84
|
+
- Resolved false positive ESLint errors for unused catch bindings in JS modules.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
25
88
|
## [1.25.16] - 2025-11-18
|
|
26
89
|
|
|
27
90
|
### Changed
|
|
@@ -1961,7 +2024,8 @@ This enables analytics filtering and CSP hardening for the audit environment.
|
|
|
1961
2024
|
|
|
1962
2025
|
<!-- Link references -->
|
|
1963
2026
|
|
|
1964
|
-
[Unreleased]: https://github.com/netwk-pro/netwk-pro.github.io/compare/v1.25.
|
|
2027
|
+
[Unreleased]: https://github.com/netwk-pro/netwk-pro.github.io/compare/v1.25.17...HEAD
|
|
2028
|
+
[1.25.17]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.25.17
|
|
1965
2029
|
[1.25.16]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.25.16
|
|
1966
2030
|
[1.25.15]: https://github.com/netwk-pro/netwk-pro.github.io/releases/tag/v1.25.15
|
|
1967
2031
|
[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
|
-
|
|
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.
|
|
4
|
+
"version": "1.25.17",
|
|
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.
|
|
89
|
-
"posthog-js": "^1.
|
|
88
|
+
"dompurify": "^3.3.1",
|
|
89
|
+
"posthog-js": "^1.305.0",
|
|
90
90
|
"semver": "^7.7.3",
|
|
91
|
-
"svelte": "5.
|
|
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.
|
|
97
|
+
"@playwright/test": "^1.57.0",
|
|
98
98
|
"@sveltejs/adapter-netlify": "^5.2.4",
|
|
99
|
-
"@sveltejs/adapter-vercel": "^6.
|
|
100
|
-
"@sveltejs/kit": "2.
|
|
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.
|
|
106
|
+
"browserslist": "^4.28.1",
|
|
107
107
|
"eslint": "^9.39.1",
|
|
108
108
|
"eslint-config-prettier": "^10.1.8",
|
|
109
|
-
"eslint-plugin-jsdoc": "^61.
|
|
110
|
-
"eslint-plugin-svelte": "^3.13.
|
|
109
|
+
"eslint-plugin-jsdoc": "^61.5.0",
|
|
110
|
+
"eslint-plugin-svelte": "^3.13.1",
|
|
111
111
|
"globals": "^16.5.0",
|
|
112
|
-
"
|
|
112
|
+
"globby": "^16.0.0",
|
|
113
|
+
"jsdom": "27.3.0",
|
|
113
114
|
"lightningcss": "^1.30.2",
|
|
114
|
-
"markdownlint": "^0.
|
|
115
|
-
"markdownlint-cli2": "0.
|
|
115
|
+
"markdownlint": "^0.40.0",
|
|
116
|
+
"markdownlint-cli2": "0.20.0",
|
|
116
117
|
"npm-run-all": "^4.1.5",
|
|
117
|
-
"playwright": "^1.
|
|
118
|
+
"playwright": "^1.57.0",
|
|
118
119
|
"postcss": "^8.5.6",
|
|
119
120
|
"prettier": "3.6.2",
|
|
120
121
|
"prettier-plugin-svelte": "^3.4.0",
|
|
121
122
|
"simple-git-hooks": "^2.13.1",
|
|
122
|
-
"stylelint": "^16.
|
|
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.
|
|
128
|
+
"svelte-eslint-parser": "^1.4.1",
|
|
128
129
|
"svelte-preprocess": "^6.0.3",
|
|
129
130
|
"typescript": "^5.9.3",
|
|
130
|
-
"vite": "^7.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
package/src/lib/README.md
CHANGED
|
@@ -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 | `(
|
|
100
|
+
| `PHONE` | Company phone number | `(602) 428-5300` |
|
|
101
101
|
|
|
102
102
|
### 🗂️ PAGE
|
|
103
103
|
|
package/src/lib/img/qr/vcard.png
CHANGED
|
Binary file
|
|
Binary file
|
package/src/lib/index.js
CHANGED
package/src/lib/utils/purify.js
CHANGED
|
@@ -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-
|
|
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 (
|
|
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
|
|
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);
|
package/src/service-worker.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
|
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[]>}
|
|
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
|
|
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 (
|
|
271
|
-
if (isDev)
|
|
273
|
+
} catch (_err) {
|
|
274
|
+
if (isDev)
|
|
272
275
|
console.warn(
|
|
273
|
-
'[SW] Fetch failed; offline fallback
|
|
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
|
package/static/bin/contact.vcf
CHANGED
|
@@ -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:(
|
|
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
|
|
@@ -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
|