@networkpro/web 1.5.6 → 1.6.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.
- package/LICENSE.md +3 -0
- package/README.md +72 -16
- package/cspell.json +10 -1
- package/jsconfig.json +2 -1
- package/netlify-functions/cspReport.js +68 -0
- package/netlify.toml +17 -8
- package/package.json +10 -7
- package/playwright.config.js +20 -19
- package/scripts/checkNode.js +7 -1
- package/src/app.d.ts +7 -4
- package/src/app.html +6 -49
- package/src/hooks.client.ts +15 -7
- package/src/hooks.server.js +91 -0
- package/src/lib/components/foss/FossFeatures.svelte +57 -4
- package/src/lib/components/foss/FossItemContent.svelte +1 -1
- package/src/lib/components/layout/Footer.svelte +1 -1
- package/src/lib/components/layout/HeaderDefault.svelte +1 -1
- package/src/lib/components/layout/HeaderHome.svelte +1 -1
- package/src/lib/data/fossData.js +271 -68
- package/src/lib/images.js +6 -0
- package/src/lib/img/posts/eauth.png +0 -0
- package/src/lib/img/posts/eauth.webp +0 -0
- package/src/lib/meta.js +0 -1
- package/src/lib/pages/FossContent.svelte +1 -1
- package/src/lib/registerServiceWorker.js +32 -31
- package/src/routes/+layout.js +6 -1
- package/src/routes/+layout.svelte +7 -6
- package/src/routes/api/mock-csp/+server.js +22 -0
- package/src/service-worker.js +55 -28
- package/static/disableSw.js +12 -0
- package/stylelint.config.js +2 -6
- package/tests/e2e/app.spec.js +58 -21
- package/tests/e2e/mobile.spec.js +49 -29
- package/tests/unit/cspReport.test.js +81 -0
- package/_headers +0 -9
package/LICENSE.md
CHANGED
|
@@ -16,6 +16,9 @@ This file is part of Network Pro.
|
|
|
16
16
|
**Network Pro Strategies**
|
|
17
17
|
**Effective Date:** May 18, 2025
|
|
18
18
|
|
|
19
|
+
**Official Version Notice**
|
|
20
|
+
This document is provided for convenience only. In the event of any discrepancy, the authoritative version is the one published at [https://netwk.pro](https://netwk.pro).
|
|
21
|
+
|
|
19
22
|
|
|
20
23
|
|
|
21
24
|
<!-- markdownlint-disable MD001 -->
|
package/README.md
CHANGED
|
@@ -32,11 +32,14 @@ All infrastructure and data flows are designed with **maximum transparency, self
|
|
|
32
32
|
.
|
|
33
33
|
├── .github/workflows # CI workflows and automation
|
|
34
34
|
├── .vscode/ # Recommended VS Code settings, extensions
|
|
35
|
+
├── netlify-functions/
|
|
36
|
+
│ └── cspReport.js # Serverless function to receive and log CSP violation reports
|
|
35
37
|
├── scripts/ # Utility scripts
|
|
36
38
|
├── src/
|
|
37
39
|
│ ├── lib/ # Reusable components, styles, utilities
|
|
38
40
|
│ ├── routes/ # SvelteKit routes (+page.svelte, +page.server.js)
|
|
39
|
-
│ ├── hooks.client.ts #
|
|
41
|
+
│ ├── hooks.client.ts # Handles PWA install prompt and logs client errors
|
|
42
|
+
│ ├── hooks.server.js # Injects CSP headers and permissions policy
|
|
40
43
|
│ ├── app.html # SvelteKit entry HTML with CSP/meta/bootentry
|
|
41
44
|
│ └── service-worker.js # Custom Service Worker
|
|
42
45
|
├── static/ # Static assets served at root
|
|
@@ -92,9 +95,9 @@ npm install
|
|
|
92
95
|
> You can also use `bootstrap.local.sh` to automate the steps above and more (optional).
|
|
93
96
|
> `ENV_MODE` controls local tooling behavior — it is not used by the app runtime directly.
|
|
94
97
|
|
|
95
|
-
|
|
98
|
+
---
|
|
96
99
|
|
|
97
|
-
|
|
100
|
+
#### 💾 Version Enforcement
|
|
98
101
|
|
|
99
102
|
To ensure consistent environments across contributors and CI systems, this project enforces specific Node.js and npm versions via the `"engines"` field in `package.json`:
|
|
100
103
|
|
|
@@ -160,7 +163,59 @@ npm -v # Should fall within engines.npm
|
|
|
160
163
|
|
|
161
164
|
|
|
162
165
|
|
|
163
|
-
|
|
166
|
+
## 🛡️ Configuration
|
|
167
|
+
|
|
168
|
+
This project includes custom runtime configuration files for enhancing security, error handling, and PWA functionality. These modules are used by the framework during server- and client-side lifecycle hooks.
|
|
169
|
+
|
|
170
|
+
### 🔐 `hooks.server.js`
|
|
171
|
+
|
|
172
|
+
Located at src/hooks.server.js, this file is responsible for injecting dynamic security headers. It includes:
|
|
173
|
+
|
|
174
|
+
- Content Security Policy (CSP) with support for relaxed directives (inline scripts allowed)
|
|
175
|
+
- Permissions Policy to explicitly disable unnecessary browser APIs
|
|
176
|
+
- X-Content-Type-Options, X-Frame-Options, and Referrer-Policy headers
|
|
177
|
+
|
|
178
|
+
> 💡 The CSP nonce feature has been disabled. Inline scripts are now allowed through the policy using the "script-src 'self' 'unsafe-inline'" directive. If you wish to use nonces in the future, you can re-enable them by uncommenting the relevant sections in hooks.server.js and modifying your inline <script> tags.
|
|
179
|
+
|
|
180
|
+
To re-enable nonce generation for inline scripts in the future:
|
|
181
|
+
|
|
182
|
+
1. Uncomment the nonce generation and injection logic in hooks.server.js.
|
|
183
|
+
2. Add nonce="**cspNonce**" to inline <script> blocks in app.html or route templates.
|
|
184
|
+
|
|
185
|
+
> 💡 The `[headers]` block in `netlify.toml` has been deprecated — all headers are now set dynamically from within SvelteKit.
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
### 🧭 `hooks.client.ts`
|
|
190
|
+
|
|
191
|
+
This lightweight hook enhances client experience:
|
|
192
|
+
|
|
193
|
+
- Handles the `beforeinstallprompt` event to support progressive web app (PWA) install flows
|
|
194
|
+
- Provides a `handleError()` hook that logs uncaught client-side errors
|
|
195
|
+
|
|
196
|
+
Located at `src/hooks.client.ts`, it is automatically used by the SvelteKit runtime during client boot.
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
### 📣 CSP Report Handler
|
|
201
|
+
|
|
202
|
+
To receive and inspect CSP violation reports in development or production, the repo includes a Netlify-compatible function at:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
netlify-functions/csp-report.js
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
This function receives reports sent to `/functions/csp-report` and logs them to the console. You can later integrate with logging tools or alerts (e.g., via email, Slack, or SIEM ingestion).
|
|
209
|
+
|
|
210
|
+
Make sure to include the `report-uri` directive in your CSP header:
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
Content-Security-Policy: ...; report-uri /.netlify/functions/csp-report;
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
## 🧪 Testing
|
|
164
219
|
|
|
165
220
|
This project uses a mix of automated performance, accessibility, and end-to-end testing tools to maintain quality across environments and deployments.
|
|
166
221
|
|
|
@@ -170,7 +225,7 @@ This project uses a mix of automated performance, accessibility, and end-to-end
|
|
|
170
225
|
| [`@lhci/cli`](https://github.com/GoogleChrome/lighthouse-ci) | Lighthouse CI — automated performance audits | CI (optional local) |
|
|
171
226
|
| [`lighthouse`](https://github.com/GoogleChrome/lighthouse) | Manual/scripted Lighthouse runs via CLI | Local (global) |
|
|
172
227
|
|
|
173
|
-
> **Note:** `lighthouse` is intended to be installed globally (`npm i -g lighthouse)
|
|
228
|
+
> **Note:** `lighthouse` is intended to be installed globally (`npm i -g lighthouse`) or run via the `lighthouse` npm script, which uses the locally installed binary if available. You can also run Lighthouse through Chrome DevTools manually if preferred.
|
|
174
229
|
|
|
175
230
|
<!-- markdownlint-disable MD028 -->
|
|
176
231
|
|
|
@@ -180,7 +235,7 @@ This project uses a mix of automated performance, accessibility, and end-to-end
|
|
|
180
235
|
|
|
181
236
|
|
|
182
237
|
|
|
183
|
-
|
|
238
|
+
### Testing Configuration Files
|
|
184
239
|
|
|
185
240
|
| File | Description | Usage Context |
|
|
186
241
|
| ---------------------- | ------------------------------------------------------------------------ | ------------- |
|
|
@@ -189,7 +244,7 @@ This project uses a mix of automated performance, accessibility, and end-to-end
|
|
|
189
244
|
|
|
190
245
|
|
|
191
246
|
|
|
192
|
-
|
|
247
|
+
### Running Tests
|
|
193
248
|
|
|
194
249
|
Local testing via Playwright:
|
|
195
250
|
|
|
@@ -234,7 +289,7 @@ You can also audit locally using Chrome DevTools → Lighthouse tab for on-the-f
|
|
|
234
289
|
|
|
235
290
|
---
|
|
236
291
|
|
|
237
|
-
|
|
292
|
+
## 🛠 Recommended Toolchain
|
|
238
293
|
|
|
239
294
|
To streamline development and align with project conventions, we recommend the following setup — especially for contributors without a strong existing preference.
|
|
240
295
|
|
|
@@ -273,7 +328,7 @@ npm run format:fix
|
|
|
273
328
|
|
|
274
329
|
---
|
|
275
330
|
|
|
276
|
-
|
|
331
|
+
## ⚙️ Tooling Configuration
|
|
277
332
|
|
|
278
333
|
All linting, formatting, and version settings are defined in versioned project config files:
|
|
279
334
|
|
|
@@ -303,13 +358,14 @@ The following CLI commands are available via `npm run <script>` or `pnpm run <sc
|
|
|
303
358
|
|
|
304
359
|
### 🔄 Development
|
|
305
360
|
|
|
306
|
-
| Script | Description
|
|
307
|
-
| --------------- |
|
|
308
|
-
| `dev` | Start development server with Vite
|
|
309
|
-
| `preview` | Preview production build locally
|
|
310
|
-
| `build` | Build the project with Vite
|
|
311
|
-
| `
|
|
312
|
-
| `
|
|
361
|
+
| Script | Description |
|
|
362
|
+
| --------------- | ------------------------------------------------------------------------ |
|
|
363
|
+
| `dev` | Start development server with Vite |
|
|
364
|
+
| `preview` | Preview production build locally |
|
|
365
|
+
| `build` | Build the project with Vite |
|
|
366
|
+
| `dev:netlify` | Start local dev server using Netlify Dev (emulates serverless + headers) |
|
|
367
|
+
| `build:netlify` | Build using Netlify CLI |
|
|
368
|
+
| `css:bundle` | Bundle and minify CSS |
|
|
313
369
|
|
|
314
370
|
---
|
|
315
371
|
|
package/cspell.json
CHANGED
|
@@ -4,8 +4,13 @@
|
|
|
4
4
|
"words": [
|
|
5
5
|
"acode",
|
|
6
6
|
"autorun",
|
|
7
|
+
"beforeinstallprompt",
|
|
7
8
|
"bootentry",
|
|
9
|
+
"Embedder",
|
|
10
|
+
"Ente",
|
|
11
|
+
"esbuild",
|
|
8
12
|
"foss",
|
|
13
|
+
"geolocation",
|
|
9
14
|
"homescreen",
|
|
10
15
|
"lhci",
|
|
11
16
|
"lighthouseci",
|
|
@@ -21,14 +26,18 @@
|
|
|
21
26
|
"Nextcloud",
|
|
22
27
|
"noopener",
|
|
23
28
|
"noreferrer",
|
|
29
|
+
"nosniff",
|
|
30
|
+
"nosw",
|
|
24
31
|
"obtainium",
|
|
32
|
+
"SIEM",
|
|
25
33
|
"stylelintignore",
|
|
26
34
|
"Subsite",
|
|
27
35
|
"subsites",
|
|
28
36
|
"urlcheck",
|
|
29
37
|
"vcard",
|
|
30
38
|
"vite",
|
|
31
|
-
"vitest"
|
|
39
|
+
"vitest",
|
|
40
|
+
"webfonts"
|
|
32
41
|
],
|
|
33
42
|
"ignorePaths": [
|
|
34
43
|
".gitignore",
|
package/jsconfig.json
CHANGED
|
@@ -18,7 +18,8 @@ This file is part of Network Pro.
|
|
|
18
18
|
"strict": true,
|
|
19
19
|
"moduleResolution": "bundler"
|
|
20
20
|
},
|
|
21
|
-
"exclude": ["vite.config.js"] // Exclude the config file if needed
|
|
21
|
+
"exclude": ["vite.config.js"], // Exclude the config file if needed
|
|
22
|
+
"include": ["src", "src/global.d.ts", "src/service-worker.js"]
|
|
22
23
|
|
|
23
24
|
// Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
|
|
24
25
|
// except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/* ==========================================================================
|
|
2
|
+
netlify-functions/cspReport.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
|
+
import nodemailer from "nodemailer";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Netlify Function: CSP violation report handler
|
|
13
|
+
*
|
|
14
|
+
* @param {import('@netlify/functions').HandlerEvent} event - Incoming Netlify request
|
|
15
|
+
* @returns {Promise<import('@netlify/functions').HandlerResponse>} - Netlify-compatible HTTP response
|
|
16
|
+
*/
|
|
17
|
+
export async function handler(event) {
|
|
18
|
+
try {
|
|
19
|
+
if (event.httpMethod !== "POST") {
|
|
20
|
+
return {
|
|
21
|
+
statusCode: 405,
|
|
22
|
+
body: "Method Not Allowed",
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (!event.body) {
|
|
27
|
+
return {
|
|
28
|
+
statusCode: 400,
|
|
29
|
+
body: "No body provided",
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** @type {Record<string, any>} */
|
|
34
|
+
const report = JSON.parse(event.body);
|
|
35
|
+
const violation = report["csp-report"] || report;
|
|
36
|
+
|
|
37
|
+
const shouldSendEmail =
|
|
38
|
+
process.env.MAIL_ENABLED !== "false" && process.env.NODE_ENV !== "test";
|
|
39
|
+
|
|
40
|
+
if (shouldSendEmail) {
|
|
41
|
+
const transporter = nodemailer.createTransport({
|
|
42
|
+
host: process.env.SMTP_HOST,
|
|
43
|
+
port: 465,
|
|
44
|
+
secure: true,
|
|
45
|
+
auth: {
|
|
46
|
+
user: process.env.SMTP_USER,
|
|
47
|
+
pass: process.env.SMTP_PASS,
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
await transporter.sendMail({
|
|
52
|
+
from: `"CSP Reporter" <${process.env.SMTP_USER}>`,
|
|
53
|
+
to: process.env.NOTIFY_EMAIL,
|
|
54
|
+
subject: "🚨 CSP Violation Detected",
|
|
55
|
+
text: JSON.stringify(violation, null, 2),
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
statusCode: 204,
|
|
61
|
+
};
|
|
62
|
+
} catch (error) {
|
|
63
|
+
return {
|
|
64
|
+
statusCode: 400,
|
|
65
|
+
body: `Invalid JSON: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
package/netlify.toml
CHANGED
|
@@ -2,14 +2,23 @@
|
|
|
2
2
|
command = "npm run build"
|
|
3
3
|
publish = "build"
|
|
4
4
|
|
|
5
|
+
[build.environment]
|
|
6
|
+
NODE_VERSION = "22"
|
|
7
|
+
|
|
8
|
+
[dev]
|
|
9
|
+
command = "npm run dev"
|
|
10
|
+
targetPort = 5173
|
|
11
|
+
port = 8888
|
|
12
|
+
|
|
13
|
+
[functions."*"]
|
|
14
|
+
node_bundler = "esbuild"
|
|
15
|
+
included_files = ["netlify-functions/**"]
|
|
16
|
+
|
|
5
17
|
[[plugins]]
|
|
6
18
|
package = "netlify-plugin-submit-sitemap"
|
|
7
19
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
"google",
|
|
14
|
-
"yandex"
|
|
15
|
-
]
|
|
20
|
+
[plugins.inputs]
|
|
21
|
+
baseUrl = "https://netwk.pro"
|
|
22
|
+
sitemapPath = "/sitemap.xml"
|
|
23
|
+
ignorePeriod = 0
|
|
24
|
+
providers = ["google", "yandex"]
|
package/package.json
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@networkpro/web",
|
|
3
3
|
"private": false,
|
|
4
|
-
"sideEffects":
|
|
5
|
-
|
|
4
|
+
"sideEffects": [
|
|
5
|
+
"./.netlify/shims.js"
|
|
6
|
+
],
|
|
7
|
+
"version": "1.6.0",
|
|
6
8
|
"description": "Locking Down Networks, Unlocking Confidence | Security, Networking, Privacy — Network Pro Strategies",
|
|
7
9
|
"keywords": [
|
|
8
10
|
"advisory",
|
|
@@ -37,9 +39,10 @@
|
|
|
37
39
|
"style": "src/lib/styles/index.js",
|
|
38
40
|
"scripts": {
|
|
39
41
|
"dev": "vite dev",
|
|
40
|
-
"preview": "vite preview",
|
|
41
42
|
"start": "npm run dev",
|
|
43
|
+
"dev:netlify": "netlify dev",
|
|
42
44
|
"build": "vite build",
|
|
45
|
+
"preview": "vite preview",
|
|
43
46
|
"build:netlify": "netlify build",
|
|
44
47
|
"css:bundle": "node scripts/bundleCss.js",
|
|
45
48
|
"prepare": "svelte-kit sync || echo ''",
|
|
@@ -62,7 +65,7 @@
|
|
|
62
65
|
"lint:fix": "eslint . --ext .mjs,.js,.svelte --fix",
|
|
63
66
|
"lint:jsdoc": "eslint . --ext .js,.mjs,.svelte --max-warnings=0",
|
|
64
67
|
"lint:css": "stylelint \"**/*.{css,svelte}\" --ignore-path .stylelintignore",
|
|
65
|
-
"lint:md": "npx markdownlint-cli2 \"**/*.{md,markdown}\" \"#node_modules/**\" \"#build/**\"",
|
|
68
|
+
"lint:md": "npx markdownlint-cli2 \"**/*.{md,markdown}\" \"#node_modules/**\" \"#build/**\" \"#.netlify/**\"",
|
|
66
69
|
"lint:all": "npm run lint && npm run lint:md && npm run lint:css && npm run format",
|
|
67
70
|
"format": "prettier --check .",
|
|
68
71
|
"format:fix": "prettier --write .",
|
|
@@ -74,13 +77,15 @@
|
|
|
74
77
|
"postinstall": "npm run check:node"
|
|
75
78
|
},
|
|
76
79
|
"dependencies": {
|
|
80
|
+
"nodemailer": "^7.0.3",
|
|
81
|
+
"playwright": "^1.52.0",
|
|
82
|
+
"semver": "^7.7.2",
|
|
77
83
|
"svelte": "5.33.1"
|
|
78
84
|
},
|
|
79
85
|
"devDependencies": {
|
|
80
86
|
"@eslint/compat": "^1.2.9",
|
|
81
87
|
"@eslint/js": "^9.27.0",
|
|
82
88
|
"@lhci/cli": "^0.14.0",
|
|
83
|
-
"@netlify/plugin-sitemap": "^0.8.1",
|
|
84
89
|
"@playwright/test": "^1.52.0",
|
|
85
90
|
"@sveltejs/adapter-netlify": "^5.0.2",
|
|
86
91
|
"@sveltejs/kit": "2.21.1",
|
|
@@ -102,10 +107,8 @@
|
|
|
102
107
|
"mdsvex": "^0.12.6",
|
|
103
108
|
"normalize.css": "^8.0.1",
|
|
104
109
|
"postcss": "^8.5.3",
|
|
105
|
-
"postcss-html": "^1.8.0",
|
|
106
110
|
"prettier": "^3.5.3",
|
|
107
111
|
"prettier-plugin-svelte": "^3.4.0",
|
|
108
|
-
"semver": "^7.7.2",
|
|
109
112
|
"stylelint": "^16.19.1",
|
|
110
113
|
"stylelint-config-html": "^1.1.0",
|
|
111
114
|
"stylelint-config-recommended": "^16.0.0",
|
package/playwright.config.js
CHANGED
|
@@ -33,11 +33,9 @@ export default defineConfig({
|
|
|
33
33
|
|
|
34
34
|
/* Shared settings for all projects */
|
|
35
35
|
use: {
|
|
36
|
-
|
|
37
|
-
baseURL: "http://localhost:5173",
|
|
38
|
-
|
|
39
|
-
/* Collect trace when retrying the failed test. */
|
|
36
|
+
baseURL: "http://localhost:4173?nosw", // Update to use preview server URL
|
|
40
37
|
trace: "on-first-retry",
|
|
38
|
+
timeout: 60000, // Default action timeout of 60 seconds for each step
|
|
41
39
|
},
|
|
42
40
|
|
|
43
41
|
/* Configure projects */
|
|
@@ -56,12 +54,13 @@ export default defineConfig({
|
|
|
56
54
|
...devices["Desktop Firefox"], // Use default Firefox settings
|
|
57
55
|
},
|
|
58
56
|
},
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
},
|
|
57
|
+
// FIXME: Webkit and Safari consistently failing, disabled for now
|
|
58
|
+
// {
|
|
59
|
+
// name: "webkit",
|
|
60
|
+
// use: {
|
|
61
|
+
// ...devices["Desktop Safari"], // Use default WebKit settings
|
|
62
|
+
// },
|
|
63
|
+
// },
|
|
65
64
|
|
|
66
65
|
// Mobile Browsers
|
|
67
66
|
{
|
|
@@ -71,18 +70,20 @@ export default defineConfig({
|
|
|
71
70
|
headless: true, // Enable true headless mode
|
|
72
71
|
},
|
|
73
72
|
},
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
},
|
|
73
|
+
// FIXME: Webkit and Safari consistently failing, disabled for now
|
|
74
|
+
// {
|
|
75
|
+
// name: "Mobile Safari",
|
|
76
|
+
// use: {
|
|
77
|
+
// ...devices["iPhone 14"], // Use the iPhone 14 device profile
|
|
78
|
+
// },
|
|
79
|
+
// },
|
|
80
80
|
],
|
|
81
81
|
|
|
82
|
-
/* Run your local
|
|
82
|
+
/* Run your local preview server before starting the tests */
|
|
83
83
|
webServer: {
|
|
84
|
-
command: "npm run
|
|
85
|
-
url: "http://localhost:
|
|
84
|
+
command: "npm run preview", // Use preview server
|
|
85
|
+
url: "http://localhost:4173?nosw", // Match the preview server URL
|
|
86
86
|
reuseExistingServer: !process.env.CI,
|
|
87
|
+
timeout: 60 * 1000, // wait up to 60 seconds for preview to be ready
|
|
87
88
|
},
|
|
88
89
|
});
|
package/scripts/checkNode.js
CHANGED
|
@@ -23,9 +23,15 @@ import { execSync } from "child_process";
|
|
|
23
23
|
import fs from "fs";
|
|
24
24
|
import path from "path";
|
|
25
25
|
import semver from "semver";
|
|
26
|
+
import { fileURLToPath } from "url";
|
|
27
|
+
|
|
28
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
29
|
+
const __dirname = path.dirname(__filename);
|
|
26
30
|
|
|
27
31
|
// Load engines from package.json
|
|
28
|
-
const pkg = JSON.parse(
|
|
32
|
+
const pkg = JSON.parse(
|
|
33
|
+
fs.readFileSync(path.resolve(__dirname, "../package.json"), "utf8"),
|
|
34
|
+
);
|
|
29
35
|
const { node: nodeRange, npm: npmRange } = pkg.engines;
|
|
30
36
|
|
|
31
37
|
// Determine if this is running as part of npm's postinstall hook
|
package/src/app.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* ==========================================================================
|
|
2
|
-
src/
|
|
2
|
+
src/app.d.ts
|
|
3
3
|
|
|
4
4
|
Copyright © 2025 Network Pro Strategies (Network Pro™)
|
|
5
5
|
SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
|
|
@@ -9,10 +9,14 @@ This file is part of Network Pro.
|
|
|
9
9
|
/// <reference types="svelte" />
|
|
10
10
|
// See https://svelte.dev/docs/kit/types#app.d.ts
|
|
11
11
|
// for information about these interfaces
|
|
12
|
+
|
|
12
13
|
declare global {
|
|
13
14
|
namespace App {
|
|
14
|
-
//
|
|
15
|
-
// interface Locals {
|
|
15
|
+
// Remove nonce from Locals as it is no longer needed
|
|
16
|
+
// interface Locals {
|
|
17
|
+
// nonce: string;
|
|
18
|
+
// }
|
|
19
|
+
|
|
16
20
|
// interface PageData {}
|
|
17
21
|
// interface PageState {}
|
|
18
22
|
// interface Platform {}
|
|
@@ -20,4 +24,3 @@ declare global {
|
|
|
20
24
|
}
|
|
21
25
|
|
|
22
26
|
export { };
|
|
23
|
-
|
package/src/app.html
CHANGED
|
@@ -17,11 +17,6 @@
|
|
|
17
17
|
content="index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1" />
|
|
18
18
|
<meta name="author" content="Network Pro Strategies" />
|
|
19
19
|
|
|
20
|
-
<!-- CSP for Dev -->
|
|
21
|
-
<meta
|
|
22
|
-
http-equiv="Content-Security-Policy"
|
|
23
|
-
content="default-src 'self'; script-src 'self' 'unsafe-inline' https://snap.licdn.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https://px.ads.linkedin.com; connect-src 'self' https://px.ads.linkedin.com;" />
|
|
24
|
-
|
|
25
20
|
<!-- Favicon: Keep only ICO for max compatibility -->
|
|
26
21
|
<link
|
|
27
22
|
rel="icon"
|
|
@@ -29,9 +24,7 @@
|
|
|
29
24
|
sizes="any"
|
|
30
25
|
type="image/x-icon" />
|
|
31
26
|
|
|
32
|
-
<!--
|
|
33
|
-
<link rel="preconnect" href="https://snap.licdn.com" crossorigin />
|
|
34
|
-
<link rel="preconnect" href="https://px.ads.linkedin.com" crossorigin />
|
|
27
|
+
<!-- LinkedIn preconnects removed 2025-05-26 by SunDevil311 -->
|
|
35
28
|
|
|
36
29
|
<!-- Preload FontAwesome webfonts -->
|
|
37
30
|
<link
|
|
@@ -56,59 +49,23 @@
|
|
|
56
49
|
name="apple-mobile-web-app-status-bar-style"
|
|
57
50
|
content="black-translucent" />
|
|
58
51
|
|
|
52
|
+
<!-- cspell:disable -->
|
|
59
53
|
<meta
|
|
60
54
|
name="facebook-domain-verification"
|
|
61
55
|
content="bx4ham0zkpvzztzu213bhpt76m9siq" />
|
|
56
|
+
<!-- cspell:enable -->
|
|
62
57
|
|
|
63
58
|
<meta name="generator" content="SvelteKit 2.21.1" />
|
|
64
59
|
|
|
65
|
-
<script>
|
|
66
|
-
if (location.search.includes("nosw")) {
|
|
67
|
-
window.__DISABLE_SW__ = true;
|
|
68
|
-
console.warn("🧪 Service worker disabled via ?nosw flag in URL.");
|
|
69
|
-
}
|
|
70
|
-
</script>
|
|
60
|
+
<script src="/disableSw.js"></script>
|
|
71
61
|
|
|
72
62
|
%sveltekit.head%
|
|
73
63
|
</head>
|
|
74
64
|
<body>
|
|
75
65
|
<div id="svelte">%sveltekit.body%</div>
|
|
76
66
|
|
|
77
|
-
<!-- LinkedIn Insight Tag
|
|
78
|
-
<!-- Load LinkedIn script only after page content is fully loaded -->
|
|
79
|
-
<script type="text/javascript">
|
|
80
|
-
// Wait for window load event for optimal performance
|
|
81
|
-
window.addEventListener("load", function () {
|
|
82
|
-
// LinkedIn Partner ID
|
|
83
|
-
window._linkedin_partner_id = "7223748";
|
|
84
|
-
window._linkedin_data_partner_ids =
|
|
85
|
-
window._linkedin_data_partner_ids || [];
|
|
86
|
-
window._linkedin_data_partner_ids.push(window._linkedin_partner_id);
|
|
87
|
-
|
|
88
|
-
// Initialize lintrk if not already initialized
|
|
89
|
-
if (!window.lintrk) {
|
|
90
|
-
window.lintrk = function (a, b) {
|
|
91
|
-
window.lintrk.q.push([a, b]);
|
|
92
|
-
};
|
|
93
|
-
window.lintrk.q = [];
|
|
94
|
-
}
|
|
67
|
+
<!-- LinkedIn Insight Tag removed 2025-05-26 by SunDevil311 -->
|
|
95
68
|
|
|
96
|
-
|
|
97
|
-
var s = document.getElementsByTagName("script")[0];
|
|
98
|
-
var b = document.createElement("script");
|
|
99
|
-
b.type = "text/javascript";
|
|
100
|
-
b.async = true;
|
|
101
|
-
b.src = "https://snap.licdn.com/li.lms-analytics/insight.min.js";
|
|
102
|
-
s.parentNode.insertBefore(b, s);
|
|
103
|
-
});
|
|
104
|
-
</script>
|
|
105
|
-
<noscript>
|
|
106
|
-
<img
|
|
107
|
-
height="1"
|
|
108
|
-
width="1"
|
|
109
|
-
style="display: none"
|
|
110
|
-
alt=""
|
|
111
|
-
src="https://px.ads.linkedin.com/collect/?pid=7223748&fmt=gif" />
|
|
112
|
-
</noscript>
|
|
69
|
+
<!-- cspell:ignore preconnects webfonts lintrk -->
|
|
113
70
|
</body>
|
|
114
71
|
</html>
|
package/src/hooks.client.ts
CHANGED
|
@@ -6,12 +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
|
-
|
|
10
|
-
// Prevent default install prompt
|
|
11
|
-
e.preventDefault();
|
|
9
|
+
// Client-only lifecycle hooks
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
});
|
|
11
|
+
// Optional: Used if you later need client boot logic
|
|
12
|
+
export const init = undefined;
|
|
16
13
|
|
|
17
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Client-side error handler for SvelteKit. Captures uncaught errors
|
|
16
|
+
* during client-side navigation or hydration.
|
|
17
|
+
*
|
|
18
|
+
* @param error - The uncaught error object
|
|
19
|
+
*/
|
|
20
|
+
export function handleError(error: Error) {
|
|
21
|
+
console.error("[CLIENT] Unhandled error:", error);
|
|
22
|
+
|
|
23
|
+
// Future: send to error reporting service
|
|
24
|
+
// e.g., Sentry.captureException(error);
|
|
25
|
+
}
|