@networkpro/web 1.1.3 → 1.4.2
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/_redirects +1 -0
- package/eslint.config.mjs +11 -0
- package/package.json +61 -38
- package/playwright.config.js +9 -1
- package/scripts/auditScripts.js +94 -0
- package/scripts/checkEnv.js +66 -0
- package/scripts/checkNode.js +54 -0
- package/scripts/checkVersions.js +58 -0
- package/src/global.d.ts +15 -0
- package/src/lib/components/PWAInstallButton.svelte +93 -0
- package/src/lib/components/foss/FossItemContent.svelte +6 -1
- package/src/lib/registerServiceWorker.js +22 -8
- package/src/routes/+layout.svelte +3 -2
- package/src/service-worker.js +57 -9
- package/static/manifest.json +9 -5
- package/static/robots.txt +19 -4
- package/tests/{app.spec.js → e2e/app.spec.js} +1 -1
- package/tests/{mobile.spec.js → e2e/mobile.spec.js} +1 -1
- package/tests/unit/auditScripts.test.js +42 -0
- package/tests/unit/checkEnv.test.js +48 -0
- package/tests/unit/checkVersions.test.js +24 -0
- package/{src/demo.spec.js → tests/unit/demo.test.js} +1 -1
- package/{src → tests/unit}/routes/page.svelte.test.js +2 -2
- package/vite.config.js +7 -0
- package/vitest.config.client.js +9 -2
- package/vitest.config.server.js +9 -2
- package/tests-examples/demo-todo-app.spec.js +0 -504
|
@@ -12,8 +12,8 @@ This file is part of Network Pro.
|
|
|
12
12
|
import Footer from "$lib/components/layout/Footer.svelte";
|
|
13
13
|
import HeaderDefault from "$lib/components/layout/HeaderDefault.svelte";
|
|
14
14
|
import HeaderHome from "$lib/components/layout/HeaderHome.svelte";
|
|
15
|
+
import PWAInstallButton from "$lib/components/PWAInstallButton.svelte";
|
|
15
16
|
import { browser } from "$app/environment";
|
|
16
|
-
// TODO: Testing in progress
|
|
17
17
|
import { registerServiceWorker } from "$lib/registerServiceWorker.js";
|
|
18
18
|
import "$lib/styles";
|
|
19
19
|
|
|
@@ -47,7 +47,6 @@ This file is part of Network Pro.
|
|
|
47
47
|
// Preload Apple Touch icon
|
|
48
48
|
touchImg.src = appleTouchIcon;
|
|
49
49
|
|
|
50
|
-
// TODO: Testing in progress
|
|
51
50
|
// Register the service worker
|
|
52
51
|
registerServiceWorker();
|
|
53
52
|
}
|
|
@@ -92,9 +91,11 @@ This file is part of Network Pro.
|
|
|
92
91
|
{#if data.pathname === "/"}
|
|
93
92
|
<!-- Render the Home Header for the root route -->
|
|
94
93
|
<HeaderHome />
|
|
94
|
+
<PWAInstallButton />
|
|
95
95
|
{:else}
|
|
96
96
|
<!-- Render the Default Header for all other routes -->
|
|
97
97
|
<HeaderDefault />
|
|
98
|
+
<PWAInstallButton />
|
|
98
99
|
{/if}
|
|
99
100
|
</ContainerSection>
|
|
100
101
|
</header>
|
package/src/service-worker.js
CHANGED
|
@@ -8,25 +8,71 @@ This file is part of Network Pro.
|
|
|
8
8
|
/** @type {ServiceWorkerGlobalScope} */
|
|
9
9
|
const sw = self;
|
|
10
10
|
|
|
11
|
+
const disallowedHosts = ["licdn.com", "googletagmanager.com"];
|
|
12
|
+
|
|
11
13
|
import { build, files, version } from "$service-worker";
|
|
12
14
|
|
|
13
15
|
/** @type {string} */
|
|
14
16
|
const CACHE = `cache-${version}`;
|
|
15
17
|
|
|
16
18
|
/** @type {string[]} */
|
|
17
|
-
const
|
|
19
|
+
const excludedAssets = [];
|
|
20
|
+
|
|
21
|
+
/** @type {string[]} */
|
|
22
|
+
const ASSETS = Array.from(
|
|
23
|
+
new Set(
|
|
24
|
+
[...build, ...files, "/offline.html"].filter((path) => {
|
|
25
|
+
try {
|
|
26
|
+
const url = new URL(path, location.origin);
|
|
27
|
+
const hostname = url.hostname;
|
|
28
|
+
|
|
29
|
+
const shouldExclude =
|
|
30
|
+
path.startsWith("http") ||
|
|
31
|
+
disallowedHosts.some(
|
|
32
|
+
(host) => hostname === host || hostname.endsWith(`.${host}`),
|
|
33
|
+
) ||
|
|
34
|
+
[
|
|
35
|
+
"/img/banner-1280x640.png",
|
|
36
|
+
"/img/banner-og-1200x630.png",
|
|
37
|
+
"/img/logo-transparent.png",
|
|
38
|
+
"/img/logo.png",
|
|
39
|
+
"/img/svelte.png",
|
|
40
|
+
"/robots.txt",
|
|
41
|
+
"/screenshots/desktop-foss.png",
|
|
42
|
+
"/sitemap.xml",
|
|
43
|
+
"/CNAME",
|
|
44
|
+
].includes(path);
|
|
45
|
+
|
|
46
|
+
if (shouldExclude) excludedAssets.push(path);
|
|
47
|
+
return !shouldExclude;
|
|
48
|
+
} catch (err) {
|
|
49
|
+
console.warn("[SW] URL parse failed, skipping path:", path, err);
|
|
50
|
+
excludedAssets.push(path);
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
}),
|
|
54
|
+
),
|
|
55
|
+
);
|
|
18
56
|
|
|
19
|
-
|
|
57
|
+
const uniqueExcludedAssets = [...new Set(excludedAssets)].sort();
|
|
58
|
+
|
|
59
|
+
console.log("[SW] Assets to precache:", ASSETS);
|
|
60
|
+
console.log("[SW] Excluded assets:", uniqueExcludedAssets);
|
|
20
61
|
|
|
21
62
|
/**
|
|
22
63
|
* @param {ExtendableEvent} event
|
|
23
64
|
*/
|
|
24
65
|
sw.addEventListener("install", (event) => {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
.open(CACHE)
|
|
28
|
-
|
|
29
|
-
|
|
66
|
+
event.waitUntil(
|
|
67
|
+
(async () => {
|
|
68
|
+
const cache = await caches.open(CACHE);
|
|
69
|
+
try {
|
|
70
|
+
await cache.addAll(ASSETS);
|
|
71
|
+
sw.skipWaiting();
|
|
72
|
+
} catch (err) {
|
|
73
|
+
console.warn("[SW] Failed to precache some assets:", err);
|
|
74
|
+
}
|
|
75
|
+
})(),
|
|
30
76
|
);
|
|
31
77
|
});
|
|
32
78
|
|
|
@@ -64,8 +110,10 @@ sw.addEventListener("activate", (event) => {
|
|
|
64
110
|
sw.addEventListener("fetch", (event) => {
|
|
65
111
|
/** @type {FetchEvent} */ (event).respondWith(
|
|
66
112
|
(async () => {
|
|
67
|
-
|
|
68
|
-
|
|
113
|
+
if (new URL(event.request.url).origin === location.origin) {
|
|
114
|
+
const cached = await caches.match(event.request);
|
|
115
|
+
if (cached) return cached;
|
|
116
|
+
}
|
|
69
117
|
|
|
70
118
|
try {
|
|
71
119
|
if (event.request.mode === "navigate") {
|
package/static/manifest.json
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
{
|
|
2
|
+
"id": "/",
|
|
3
|
+
"start_url": "/?utm_source=homescreen",
|
|
4
|
+
"scope": "/",
|
|
2
5
|
"name": "Network Pro Strategies",
|
|
3
6
|
"short_name": "Network Pro",
|
|
4
7
|
"description": "Access our expert cybersecurity services anytime, anywhere with our streamlined Progressive Web App. Optimized for speed, security, and mobile use, this app offers a seamless experience to explore our solutions, view project highlights, and get in touch—all in one place.",
|
|
5
|
-
"
|
|
8
|
+
"lang": "en-US",
|
|
9
|
+
"dir": "ltr",
|
|
6
10
|
"display": "standalone",
|
|
7
11
|
"display_override": ["window-controls-overlay", "minimal-ui"],
|
|
12
|
+
"orientation": "any",
|
|
8
13
|
"background_color": "#191919",
|
|
9
14
|
"theme_color": "#ffc627",
|
|
10
15
|
"icons": [
|
|
@@ -22,7 +27,7 @@
|
|
|
22
27
|
"src": "/icon-512x512-maskable.png",
|
|
23
28
|
"type": "image/png",
|
|
24
29
|
"sizes": "512x512",
|
|
25
|
-
"purpose": "maskable"
|
|
30
|
+
"purpose": "any maskable"
|
|
26
31
|
},
|
|
27
32
|
{
|
|
28
33
|
"src": "/icon-splash.png",
|
|
@@ -30,6 +35,8 @@
|
|
|
30
35
|
"sizes": "512x512"
|
|
31
36
|
}
|
|
32
37
|
],
|
|
38
|
+
"categories": ["business", "security", "technology", "network", "privacy"],
|
|
39
|
+
"prefer_related_applications": false,
|
|
33
40
|
"screenshots": [
|
|
34
41
|
{
|
|
35
42
|
"src": "/screenshots/desktop-home.png",
|
|
@@ -60,9 +67,6 @@
|
|
|
60
67
|
"label": "FOSS Spotlight on mobile"
|
|
61
68
|
}
|
|
62
69
|
],
|
|
63
|
-
"orientation": "any",
|
|
64
|
-
"scope": "/",
|
|
65
|
-
"categories": ["business", "security", "technology", "network", "privacy"],
|
|
66
70
|
"shortcuts": [
|
|
67
71
|
{
|
|
68
72
|
"name": "Consulting Services",
|
package/static/robots.txt
CHANGED
|
@@ -6,7 +6,22 @@
|
|
|
6
6
|
# www.robotstxt.org/
|
|
7
7
|
|
|
8
8
|
User-agent: *
|
|
9
|
-
|
|
10
|
-
Disallow
|
|
11
|
-
Disallow:
|
|
12
|
-
Disallow:
|
|
9
|
+
|
|
10
|
+
# Disallow dev and CI/CD artifacts
|
|
11
|
+
Disallow: /tests/
|
|
12
|
+
Disallow: /scripts/
|
|
13
|
+
Disallow: /playwright-report/
|
|
14
|
+
Disallow: /reports/
|
|
15
|
+
Disallow: /coverage/
|
|
16
|
+
Disallow: /build/
|
|
17
|
+
Disallow: /.lighthouseci/
|
|
18
|
+
|
|
19
|
+
# Disallow stub routes that redirect externally
|
|
20
|
+
Disallow: /contact
|
|
21
|
+
Disallow: /privacy-rights
|
|
22
|
+
|
|
23
|
+
# Allow everything else
|
|
24
|
+
Allow: /
|
|
25
|
+
|
|
26
|
+
# Inform bots where to find the sitemap
|
|
27
|
+
Sitemap: https://netwk.pro/sitemap.xml
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/* ==========================================================================
|
|
2
|
+
tests/unit/auditScripts.test.js
|
|
3
|
+
|
|
4
|
+
SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
|
|
5
|
+
This file is part of Network Pro.
|
|
6
|
+
========================================================================== */
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Unit test for scripts/auditScripts.js
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import fs from "fs";
|
|
13
|
+
import path from "path";
|
|
14
|
+
import { describe, expect, it } from "vitest";
|
|
15
|
+
|
|
16
|
+
describe("auditScripts.js", () => {
|
|
17
|
+
it("should identify untested scripts correctly", () => {
|
|
18
|
+
const scriptsDir = path.resolve("./scripts");
|
|
19
|
+
const testsDir = path.resolve("./tests");
|
|
20
|
+
|
|
21
|
+
const allowList = new Set(["checkNode.js", "auditScripts.js"]);
|
|
22
|
+
|
|
23
|
+
const scriptFiles = fs
|
|
24
|
+
.readdirSync(scriptsDir)
|
|
25
|
+
.filter((file) => file.endsWith(".js"));
|
|
26
|
+
|
|
27
|
+
const testFiles = fs
|
|
28
|
+
.readdirSync(testsDir)
|
|
29
|
+
.filter((file) => file.endsWith(".test.js") || file.endsWith(".spec.js"));
|
|
30
|
+
|
|
31
|
+
const testedModules = new Set(
|
|
32
|
+
testFiles.map((f) => f.replace(/\.test\.js$|\.spec\.js$/, "")),
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
const untested = scriptFiles.filter((file) => {
|
|
36
|
+
const base = file.replace(/\.js$/, "");
|
|
37
|
+
return !allowList.has(file) && !testedModules.has(base);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
expect(untested).not.toContain("auditScripts.js");
|
|
41
|
+
});
|
|
42
|
+
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/* ==========================================================================
|
|
2
|
+
tests/unit/checkEnv.test.js
|
|
3
|
+
|
|
4
|
+
SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
|
|
5
|
+
This file is part of Network Pro.
|
|
6
|
+
========================================================================== */
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Unit test for scripts/checkEnv.js
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
13
|
+
import { checkEnv } from "../../scripts/checkEnv.js";
|
|
14
|
+
|
|
15
|
+
describe("checkEnv()", () => {
|
|
16
|
+
const originalEnv = process.env.ENV_MODE;
|
|
17
|
+
|
|
18
|
+
afterEach(() => {
|
|
19
|
+
if (originalEnv === undefined) {
|
|
20
|
+
delete process.env.ENV_MODE;
|
|
21
|
+
} else {
|
|
22
|
+
process.env.ENV_MODE = originalEnv;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("should default to 'dev' if ENV_MODE is not set", () => {
|
|
27
|
+
delete process.env.ENV_MODE;
|
|
28
|
+
const result = checkEnv();
|
|
29
|
+
expect(result.mode).toBe("dev");
|
|
30
|
+
expect(result.valid).toBe(true);
|
|
31
|
+
expect(result.wasDefaulted).toBe(true);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("should validate a correct ENV_MODE", () => {
|
|
35
|
+
process.env.ENV_MODE = "ci";
|
|
36
|
+
const result = checkEnv();
|
|
37
|
+
expect(result.mode).toBe("ci");
|
|
38
|
+
expect(result.valid).toBe(true);
|
|
39
|
+
expect(result.wasDefaulted).toBe(false);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it("should return invalid for an unknown ENV_MODE", () => {
|
|
43
|
+
process.env.ENV_MODE = "banana";
|
|
44
|
+
const result = checkEnv();
|
|
45
|
+
expect(result.valid).toBe(false);
|
|
46
|
+
expect(result.allowed).toContain("dev");
|
|
47
|
+
});
|
|
48
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/* ==========================================================================
|
|
2
|
+
tests/unit/checkVersions.test.js
|
|
3
|
+
|
|
4
|
+
SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
|
|
5
|
+
This file is part of Network Pro.
|
|
6
|
+
========================================================================== */
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Unit test for scripts/checkVersions.js
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { describe, expect, it } from "vitest";
|
|
13
|
+
import { checkVersions } from "../../scripts/checkVersions.js";
|
|
14
|
+
|
|
15
|
+
describe("checkVersions()", () => {
|
|
16
|
+
it("should match current Node and NPM versions to engine ranges", () => {
|
|
17
|
+
const result = checkVersions();
|
|
18
|
+
|
|
19
|
+
expect(result.nodeVersion).toMatch(/^v\d+\.\d+\.\d+$/);
|
|
20
|
+
expect(result.npmVersion).toMatch(/^\d+\.\d+\.\d+$/);
|
|
21
|
+
expect(result.nodeValid).toBe(true);
|
|
22
|
+
expect(result.npmValid).toBe(true);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* ==========================================================================
|
|
2
|
-
|
|
2
|
+
tests/unit/routes/page.svelte.test.js
|
|
3
3
|
|
|
4
4
|
SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
|
|
5
5
|
This file is part of Network Pro.
|
|
@@ -8,7 +8,7 @@ This file is part of Network Pro.
|
|
|
8
8
|
import "@testing-library/jest-dom/vitest";
|
|
9
9
|
import { render, screen } from "@testing-library/svelte";
|
|
10
10
|
import { describe, expect, test } from "vitest";
|
|
11
|
-
import Page from "
|
|
11
|
+
import Page from "../../../src/routes/+page.svelte";
|
|
12
12
|
|
|
13
13
|
describe("/+page.svelte", () => {
|
|
14
14
|
test("should render the home page section", () => {
|
package/vite.config.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/* =========================================================================
|
|
2
|
+
vite.config.js
|
|
3
|
+
|
|
4
|
+
SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
|
|
5
|
+
This file is part of Network Pro.
|
|
6
|
+
========================================================================= */
|
|
7
|
+
|
|
1
8
|
import { sveltekit } from "@sveltejs/kit/vite";
|
|
2
9
|
import { defineConfig } from "vite";
|
|
3
10
|
import lightningcssPlugin from "vite-plugin-lightningcss";
|
package/vitest.config.client.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/* =========================================================================
|
|
2
|
+
vitest.config.client.js
|
|
3
|
+
|
|
4
|
+
SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
|
|
5
|
+
This file is part of Network Pro.
|
|
6
|
+
========================================================================= */
|
|
7
|
+
|
|
1
8
|
import { sveltekit } from "@sveltejs/kit/vite";
|
|
2
9
|
import { svelteTesting } from "@testing-library/svelte/vite";
|
|
3
10
|
import lightningcssPlugin from "vite-plugin-lightningcss";
|
|
@@ -18,8 +25,8 @@ export default defineConfig({
|
|
|
18
25
|
name: "client",
|
|
19
26
|
environment: "jsdom",
|
|
20
27
|
clearMocks: true,
|
|
21
|
-
include: ["
|
|
22
|
-
exclude: [
|
|
28
|
+
include: ["tests/unit/**/*.svelte.test.{js,mjs}"],
|
|
29
|
+
exclude: [],
|
|
23
30
|
setupFiles: ["./vitest-setup-client.js"],
|
|
24
31
|
reporters: ["default", "json"],
|
|
25
32
|
outputFile: {
|
package/vitest.config.server.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/* =========================================================================
|
|
2
|
+
vitest.config.server.js
|
|
3
|
+
|
|
4
|
+
SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
|
|
5
|
+
This file is part of Network Pro.
|
|
6
|
+
========================================================================= */
|
|
7
|
+
|
|
1
8
|
import { sveltekit } from "@sveltejs/kit/vite";
|
|
2
9
|
import lightningcssPlugin from "vite-plugin-lightningcss";
|
|
3
10
|
import { defineConfig } from "vitest/config";
|
|
@@ -15,8 +22,8 @@ export default defineConfig({
|
|
|
15
22
|
test: {
|
|
16
23
|
name: "server",
|
|
17
24
|
environment: "node",
|
|
18
|
-
include: ["
|
|
19
|
-
exclude: ["
|
|
25
|
+
include: ["tests/unit/**/*.test.{js,mjs}"],
|
|
26
|
+
exclude: ["tests/unit/**/*.svelte.test.{js,mjs}"],
|
|
20
27
|
reporters: ["default", "json"],
|
|
21
28
|
outputFile: {
|
|
22
29
|
json: "./reports/server/results.json",
|