@networkpro/web 1.12.9 → 1.13.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/CHANGELOG.md +26 -1
- package/README.md +8 -8
- package/eslint.config.mjs +48 -48
- package/netlify/edge-functions/csp-report.js +31 -31
- package/package.json +1 -1
- package/playwright.config.js +14 -14
- package/postcss.config.mjs +1 -1
- package/scripts/auditScripts.js +16 -16
- package/scripts/bundleCss.js +5 -5
- package/scripts/checkEnv.js +6 -6
- package/scripts/checkNode.js +10 -10
- package/scripts/checkVersions.js +6 -6
- package/scripts/flattenHeaders.js +13 -13
- package/scripts/generateTest.js +5 -5
- package/scripts/openReport.js +3 -3
- package/scripts/validateHeaders.js +13 -13
- package/src/hooks.client.ts +1 -1
- package/src/hooks.server.js +31 -31
- package/src/lib/components/Badges.svelte +9 -9
- package/src/lib/components/CodeBlock.svelte +1 -1
- package/src/lib/components/ContainerSection.svelte +1 -1
- package/src/lib/components/FullWidthSection.svelte +3 -3
- package/src/lib/components/LegalNav.svelte +6 -6
- package/src/lib/components/Logo.svelte +9 -9
- package/src/lib/components/MetaTags.svelte +3 -3
- package/src/lib/components/PWAInstallButton.svelte +4 -4
- package/src/lib/components/RedirectPage.svelte +4 -4
- package/src/lib/components/SocialMedia.svelte +16 -16
- package/src/lib/components/foss/FossItemContent.svelte +18 -18
- package/src/lib/components/layout/Footer.svelte +17 -17
- package/src/lib/components/layout/HeaderDefault.svelte +16 -16
- package/src/lib/components/layout/HeaderHome.svelte +14 -14
- package/src/lib/images.js +34 -34
- package/src/lib/index.js +15 -15
- package/src/lib/meta.js +29 -29
- package/src/lib/pages/AboutContent.svelte +24 -24
- package/src/lib/pages/FossContent.svelte +12 -12
- package/src/lib/pages/HomeContent.svelte +6 -6
- package/src/lib/pages/LicenseContent.svelte +38 -38
- package/src/lib/pages/PGPContent.svelte +23 -23
- package/src/lib/pages/PrivacyContent.svelte +39 -39
- package/src/lib/pages/PrivacyDashboard.svelte +12 -12
- package/src/lib/pages/TermsConditionsContent.svelte +28 -28
- package/src/lib/pages/TermsUseContent.svelte +26 -26
- package/src/lib/registerServiceWorker.js +25 -25
- package/src/lib/stores/posthog.js +13 -13
- package/src/lib/stores/trackingPreferences.js +19 -19
- package/src/lib/unregisterServiceWorker.js +1 -1
- package/src/lib/utils/purify.js +4 -4
- package/src/lib/utils/utm.js +2 -2
- package/src/routes/+error.svelte +4 -4
- package/src/routes/+layout.js +6 -6
- package/src/routes/+layout.svelte +29 -29
- package/src/routes/+page.server.js +2 -2
- package/src/routes/+page.svelte +9 -9
- package/src/routes/about/+page.server.js +2 -2
- package/src/routes/about/+page.svelte +7 -7
- package/src/routes/api/mock-csp/+server.js +3 -3
- package/src/routes/consultation/+page.svelte +5 -5
- package/src/routes/contact/+page.svelte +5 -5
- package/src/routes/foss-spotlight/+page.server.js +2 -2
- package/src/routes/foss-spotlight/+page.svelte +7 -7
- package/src/routes/license/+page.server.js +2 -2
- package/src/routes/license/+page.svelte +7 -7
- package/src/routes/pgp/+page.server.js +2 -2
- package/src/routes/pgp/+page.svelte +7 -7
- package/src/routes/pgp/[key]/+server.js +9 -9
- package/src/routes/privacy/+page.server.js +2 -2
- package/src/routes/privacy/+page.svelte +7 -7
- package/src/routes/privacy-dashboard/+page.server.js +2 -2
- package/src/routes/privacy-dashboard/+page.svelte +8 -8
- package/src/routes/privacy-rights/+page.svelte +5 -5
- package/src/routes/status/+page.server.js +2 -2
- package/src/routes/terms-conditions/+page.server.js +2 -2
- package/src/routes/terms-conditions/+page.svelte +7 -7
- package/src/routes/terms-of-use/+page.server.js +2 -2
- package/src/routes/terms-of-use/+page.svelte +7 -7
- package/src/service-worker.js +86 -86
- package/static/disableSw.js +2 -2
- package/static/offline.html +7 -7
- package/stylelint.config.js +56 -56
- package/svelte.config.js +6 -6
- package/tests/e2e/app.spec.js +25 -25
- package/tests/e2e/mobile.spec.js +18 -18
- package/tests/e2e/shared/helpers.js +4 -4
- package/tests/internal/auditCoverage.test.js +24 -24
- package/tests/unit/checkEnv.test.js +10 -10
- package/tests/unit/checkVersions.test.js +4 -4
- package/tests/unit/csp-report.test.js +24 -24
- package/tests/unit/demo.test.js +3 -3
- package/tests/unit/lib/utils/purify.test.js +12 -12
- package/tests/unit/routes/page.svelte.test.js +10 -10
- package/tests/unit/unregisterServiceWorker.test.js +5 -5
- package/tests/unit/utm.test.js +13 -13
- package/vite.config.js +5 -5
- package/vitest-setup-client.js +4 -4
- package/vitest.config.client.js +15 -15
- package/vitest.config.server.js +13 -13
package/src/service-worker.js
CHANGED
|
@@ -13,13 +13,13 @@ const sw = /** @type {ServiceWorkerGlobalScope} */ (
|
|
|
13
13
|
|
|
14
14
|
/// <reference types="vite/client" />
|
|
15
15
|
|
|
16
|
-
const isDev = location.hostname ===
|
|
16
|
+
const isDev = location.hostname === 'localhost';
|
|
17
17
|
const disallowedHosts = [
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
'us.i.posthog.com', // Add PostHog to disallowed hosts
|
|
19
|
+
'posthog.com', // Add PostHog to disallowed hosts
|
|
20
20
|
];
|
|
21
21
|
|
|
22
|
-
import { build, files, version } from
|
|
22
|
+
import { build, files, version } from '$service-worker';
|
|
23
23
|
|
|
24
24
|
/** @type {string} */
|
|
25
25
|
const CACHE = `cache-${version}`;
|
|
@@ -28,38 +28,38 @@ const CACHE = `cache-${version}`;
|
|
|
28
28
|
const excludedAssets = [];
|
|
29
29
|
|
|
30
30
|
const IGNORE_PATHS = new Set([
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
31
|
+
'/.well-known/security.txt.asc',
|
|
32
|
+
'/img/banner-1280x640.png',
|
|
33
|
+
'/img/logo-transparent.png',
|
|
34
|
+
'/img/logo.png',
|
|
35
|
+
'/img/svelte.png',
|
|
36
|
+
'/pgp/pgp-github.png',
|
|
37
|
+
'/pgp/pgp-github.webp',
|
|
38
|
+
'/pgp/contact@s.neteng.pro.asc',
|
|
39
|
+
'/pgp/github@sl.neteng.cc.asc',
|
|
40
|
+
'/pgp/security@s.neteng.pro.asc',
|
|
41
|
+
'/pgp/support@neteng.pro.asc',
|
|
42
|
+
'/pgp/vcard.png',
|
|
43
|
+
'/pgp/vcard.webp',
|
|
44
|
+
'/screenshots/desktop-foss.png',
|
|
45
|
+
'/webfonts/fa-brands-400.ttf',
|
|
46
|
+
'/webfonts/fa-solid-900.ttf',
|
|
47
|
+
'/robots.txt',
|
|
48
|
+
'/sitemap.xml',
|
|
49
|
+
'/CNAME',
|
|
50
50
|
]);
|
|
51
51
|
|
|
52
52
|
/** @type {string[]} */
|
|
53
53
|
const ASSETS = [
|
|
54
54
|
...new Set(
|
|
55
|
-
[...build, ...files,
|
|
55
|
+
[...build, ...files, '/offline.html'].filter((path) => {
|
|
56
56
|
try {
|
|
57
57
|
const url = new URL(path, location.origin);
|
|
58
58
|
const hostname = url.hostname;
|
|
59
59
|
|
|
60
60
|
const shouldExclude =
|
|
61
|
-
path.startsWith(
|
|
62
|
-
path.startsWith(
|
|
61
|
+
path.startsWith('http') ||
|
|
62
|
+
path.startsWith('/bin/') ||
|
|
63
63
|
disallowedHosts.some(
|
|
64
64
|
(host) => hostname === host || hostname.endsWith(`.${host}`),
|
|
65
65
|
) ||
|
|
@@ -69,7 +69,7 @@ const ASSETS = [
|
|
|
69
69
|
return !shouldExclude;
|
|
70
70
|
} catch (err) {
|
|
71
71
|
if (isDev)
|
|
72
|
-
console.warn(
|
|
72
|
+
console.warn('[SW] URL parse failed, skipping path:', path, err);
|
|
73
73
|
excludedAssets.push(path);
|
|
74
74
|
return true;
|
|
75
75
|
}
|
|
@@ -81,41 +81,41 @@ const uniqueExcludedAssets = [...new Set(excludedAssets)].sort();
|
|
|
81
81
|
|
|
82
82
|
/** @type {string[]} */
|
|
83
83
|
const REQUIRED_ASSETS = [
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
84
|
+
'/disableSw.js',
|
|
85
|
+
'/favicon.ico',
|
|
86
|
+
'/icon-192x192.png',
|
|
87
|
+
'/icon-512x512-maskable.png',
|
|
88
|
+
'/icon-512x512.png',
|
|
89
|
+
'/icon-contact.png',
|
|
90
|
+
'/icon-services.png',
|
|
91
|
+
'/icon-splash.png',
|
|
92
|
+
'/img/banner-og-1200x630.png',
|
|
93
|
+
'/pgp/pgp-contact.png',
|
|
94
|
+
'/pgp/pgp-contact.webp',
|
|
95
|
+
'/pgp/pgp-security.png',
|
|
96
|
+
'/pgp/pgp-security.webp',
|
|
97
|
+
'/pgp/pgp-support.png',
|
|
98
|
+
'/pgp/pgp-support.webp',
|
|
99
|
+
'/manifest.json',
|
|
100
|
+
'/offline.html',
|
|
101
|
+
'/offline.min.css',
|
|
102
|
+
'/screenshots/desktop-about.png',
|
|
103
|
+
'/screenshots/desktop-home.png',
|
|
104
|
+
'/screenshots/mobile-foss.png',
|
|
105
|
+
'/screenshots/mobile-home.png',
|
|
106
|
+
'/styles/brands.min.css',
|
|
107
|
+
'/styles/fontawesome.min.css',
|
|
108
|
+
'/styles/global.min.css',
|
|
109
|
+
'/styles/solid.min.css',
|
|
110
|
+
'/webfonts/fa-brands-400.woff2',
|
|
111
|
+
'/webfonts/fa-solid-900.woff2',
|
|
112
|
+
'/.well-known/dnt-policy.txt',
|
|
113
|
+
'/.well-known/gpc.json',
|
|
114
114
|
];
|
|
115
115
|
|
|
116
116
|
if (isDev) {
|
|
117
|
-
console.log(
|
|
118
|
-
console.log(
|
|
117
|
+
console.log('[SW] Assets to precache:', ASSETS);
|
|
118
|
+
console.log('[SW] Excluded assets:', uniqueExcludedAssets);
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
/**
|
|
@@ -152,7 +152,7 @@ async function cacheAssetsSafely(cache, assets, required = []) {
|
|
|
152
152
|
|
|
153
153
|
const missing = required.filter((req) => !cachedPaths.includes(req));
|
|
154
154
|
if (missing.length > 0) {
|
|
155
|
-
const errorMsg = `[SW] ⚠️ Missing required assets: ${missing.join(
|
|
155
|
+
const errorMsg = `[SW] ⚠️ Missing required assets: ${missing.join(', ')}`;
|
|
156
156
|
if (isDev) throw new Error(errorMsg);
|
|
157
157
|
console.error(errorMsg);
|
|
158
158
|
}
|
|
@@ -161,8 +161,8 @@ async function cacheAssetsSafely(cache, assets, required = []) {
|
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
// 🔹 Install event
|
|
164
|
-
sw.addEventListener(
|
|
165
|
-
if (isDev) console.log(
|
|
164
|
+
sw.addEventListener('install', (event) => {
|
|
165
|
+
if (isDev) console.log('[SW] Install event');
|
|
166
166
|
|
|
167
167
|
event.waitUntil(
|
|
168
168
|
(async () => {
|
|
@@ -172,29 +172,29 @@ sw.addEventListener("install", (event) => {
|
|
|
172
172
|
try {
|
|
173
173
|
cachedPaths = await cacheAssetsSafely(cache, ASSETS, REQUIRED_ASSETS);
|
|
174
174
|
if (isDev) {
|
|
175
|
-
console.log(
|
|
175
|
+
console.log('[SW] Cached assets:', cachedPaths);
|
|
176
176
|
}
|
|
177
177
|
} catch (err) {
|
|
178
178
|
if (isDev) throw err;
|
|
179
|
-
console.warn(
|
|
179
|
+
console.warn('[SW] Error while precaching (non-fatal in prod):', err);
|
|
180
180
|
}
|
|
181
181
|
|
|
182
182
|
await sw.skipWaiting();
|
|
183
|
-
if (isDev) console.log(
|
|
183
|
+
if (isDev) console.log('[SW] skipWaiting() called');
|
|
184
184
|
})(),
|
|
185
185
|
);
|
|
186
186
|
});
|
|
187
187
|
|
|
188
188
|
// 🔹 Activate event
|
|
189
|
-
sw.addEventListener(
|
|
190
|
-
if (isDev) console.log(
|
|
189
|
+
sw.addEventListener('activate', (event) => {
|
|
190
|
+
if (isDev) console.log('[SW] Activate event');
|
|
191
191
|
event.waitUntil(
|
|
192
192
|
(async () => {
|
|
193
193
|
const tasks = [];
|
|
194
194
|
|
|
195
195
|
if (sw.registration.navigationPreload) {
|
|
196
196
|
tasks.push(sw.registration.navigationPreload.enable());
|
|
197
|
-
if (isDev) console.log(
|
|
197
|
+
if (isDev) console.log('[SW] Navigation preload enabled');
|
|
198
198
|
}
|
|
199
199
|
|
|
200
200
|
tasks.push(
|
|
@@ -203,7 +203,7 @@ sw.addEventListener("activate", (event) => {
|
|
|
203
203
|
keys
|
|
204
204
|
.filter((key) => key !== CACHE)
|
|
205
205
|
.map((key) => {
|
|
206
|
-
if (isDev) console.log(
|
|
206
|
+
if (isDev) console.log('[SW] Deleting old cache:', key);
|
|
207
207
|
return caches.delete(key);
|
|
208
208
|
}),
|
|
209
209
|
),
|
|
@@ -213,8 +213,8 @@ sw.addEventListener("activate", (event) => {
|
|
|
213
213
|
await Promise.all(tasks);
|
|
214
214
|
await sw.clients.claim();
|
|
215
215
|
if (isDev) {
|
|
216
|
-
console.log(
|
|
217
|
-
console.log(
|
|
216
|
+
console.log('[SW] clients.claim() called');
|
|
217
|
+
console.log('[SW] Scope:', sw.registration.scope);
|
|
218
218
|
}
|
|
219
219
|
})(),
|
|
220
220
|
);
|
|
@@ -232,16 +232,16 @@ function shouldSkipDevModule(url) {
|
|
|
232
232
|
if (!isDev) return false;
|
|
233
233
|
|
|
234
234
|
return (
|
|
235
|
-
url.pathname.startsWith(
|
|
236
|
-
url.pathname.startsWith(
|
|
237
|
-
url.pathname.includes(
|
|
238
|
-
url.pathname.includes(
|
|
235
|
+
url.pathname.startsWith('/@fs') ||
|
|
236
|
+
url.pathname.startsWith('/node_modules') ||
|
|
237
|
+
url.pathname.includes('.vite') ||
|
|
238
|
+
url.pathname.includes('.svelte-kit') ||
|
|
239
239
|
!!url.pathname.match(/\.(js|ts|svelte)$/)
|
|
240
240
|
);
|
|
241
241
|
}
|
|
242
242
|
|
|
243
243
|
// 🔹 Fetch event
|
|
244
|
-
sw.addEventListener(
|
|
244
|
+
sw.addEventListener('fetch', (event) => {
|
|
245
245
|
const requestUrl = new URL(event.request.url);
|
|
246
246
|
|
|
247
247
|
// ✅ Skip cross-origin requests
|
|
@@ -250,23 +250,23 @@ sw.addEventListener("fetch", (event) => {
|
|
|
250
250
|
// ✅ Skip internal dev/module files (only in dev)
|
|
251
251
|
if (shouldSkipDevModule(requestUrl)) return;
|
|
252
252
|
|
|
253
|
-
if (isDev) console.log(
|
|
253
|
+
if (isDev) console.log('[SW] Fetch intercepted:', event.request.url);
|
|
254
254
|
|
|
255
255
|
event.respondWith(
|
|
256
256
|
(async () => {
|
|
257
257
|
const cached = await caches.match(event.request);
|
|
258
258
|
if (cached) {
|
|
259
|
-
if (isDev) console.log(
|
|
259
|
+
if (isDev) console.log('[SW] Serving from cache:', event.request.url);
|
|
260
260
|
return cached;
|
|
261
261
|
}
|
|
262
262
|
|
|
263
263
|
try {
|
|
264
|
-
if (event.request.mode ===
|
|
264
|
+
if (event.request.mode === 'navigate') {
|
|
265
265
|
const preloadResponse = await event.preloadResponse;
|
|
266
266
|
if (preloadResponse) {
|
|
267
267
|
if (isDev) {
|
|
268
268
|
console.log(
|
|
269
|
-
|
|
269
|
+
'[SW] Using preload response for:',
|
|
270
270
|
event.request.url,
|
|
271
271
|
);
|
|
272
272
|
}
|
|
@@ -275,23 +275,23 @@ sw.addEventListener("fetch", (event) => {
|
|
|
275
275
|
}
|
|
276
276
|
|
|
277
277
|
if (isDev)
|
|
278
|
-
console.log(
|
|
278
|
+
console.log('[SW] Fetching from network:', event.request.url);
|
|
279
279
|
|
|
280
280
|
return await fetch(event.request);
|
|
281
281
|
} catch (err) {
|
|
282
282
|
if (isDev) {
|
|
283
283
|
console.warn(
|
|
284
|
-
|
|
284
|
+
'[SW] Fetch failed; offline fallback used:',
|
|
285
285
|
event.request.url,
|
|
286
286
|
err,
|
|
287
287
|
);
|
|
288
288
|
}
|
|
289
289
|
|
|
290
|
-
if (event.request.mode ===
|
|
291
|
-
const offline = await caches.match(
|
|
290
|
+
if (event.request.mode === 'navigate') {
|
|
291
|
+
const offline = await caches.match('/offline.html');
|
|
292
292
|
if (offline) return offline;
|
|
293
|
-
return new Response(
|
|
294
|
-
headers: {
|
|
293
|
+
return new Response('<h1>Offline</h1>', {
|
|
294
|
+
headers: { 'Content-Type': 'text/html' },
|
|
295
295
|
});
|
|
296
296
|
}
|
|
297
297
|
|
package/static/disableSw.js
CHANGED
|
@@ -14,7 +14,7 @@ This file is part of Network Pro.
|
|
|
14
14
|
* @updated 2025-05-29
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
if (location.search.includes(
|
|
17
|
+
if (location.search.includes('nosw')) {
|
|
18
18
|
window.__DISABLE_SW__ = true;
|
|
19
|
-
console.warn(
|
|
19
|
+
console.warn('🧪 Service worker disabled via ?nosw flag in URL.');
|
|
20
20
|
}
|
package/static/offline.html
CHANGED
|
@@ -43,10 +43,10 @@
|
|
|
43
43
|
function updateTimestamp() {
|
|
44
44
|
const now = new Date();
|
|
45
45
|
const timeStr = now.toLocaleTimeString([], {
|
|
46
|
-
hour:
|
|
47
|
-
minute:
|
|
46
|
+
hour: '2-digit',
|
|
47
|
+
minute: '2-digit',
|
|
48
48
|
});
|
|
49
|
-
document.getElementById(
|
|
49
|
+
document.getElementById('timestamp').textContent = timeStr;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
// Check connection status periodically
|
|
@@ -64,17 +64,17 @@
|
|
|
64
64
|
setInterval(updateTimestamp, 60000);
|
|
65
65
|
|
|
66
66
|
// Also listen for online event
|
|
67
|
-
window.addEventListener(
|
|
67
|
+
window.addEventListener('online', () => {
|
|
68
68
|
window.location.reload();
|
|
69
69
|
});
|
|
70
70
|
|
|
71
71
|
// Prevent default action for offline links
|
|
72
72
|
document
|
|
73
|
-
.getElementById(
|
|
74
|
-
.addEventListener(
|
|
73
|
+
.getElementById('contact-link')
|
|
74
|
+
.addEventListener('click', function (e) {
|
|
75
75
|
if (!navigator.onLine) {
|
|
76
76
|
e.preventDefault();
|
|
77
|
-
alert(
|
|
77
|
+
alert('This link will be available when you are back online.');
|
|
78
78
|
}
|
|
79
79
|
});
|
|
80
80
|
</script>
|
package/stylelint.config.js
CHANGED
|
@@ -9,101 +9,101 @@ This file is part of Network Pro
|
|
|
9
9
|
/** @type {import('stylelint').Config} */
|
|
10
10
|
export default {
|
|
11
11
|
extends: [
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
'stylelint-config-recommended', // Base recommended config
|
|
13
|
+
'stylelint-config-html/html', // For linting HTML files
|
|
14
|
+
'stylelint-config-html/svelte', // For linting HTML within Svelte or similar frameworks
|
|
15
|
+
'stylelint-config-html', // For linting HTML files
|
|
16
16
|
],
|
|
17
|
-
plugins: [
|
|
17
|
+
plugins: ['stylelint-order'], // Add stylelint-order plugin
|
|
18
18
|
ignoreFiles: [
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
'./src/lib/styles/fa-global.css', // Ignore CSS import files
|
|
20
|
+
'./src/lib/styles/css/global.css', // Ignore CSS import files
|
|
21
|
+
'./src/lib/styles/css/brands.css', // Ignore FontAwesome CSS files
|
|
22
|
+
'**/*.min.css', // Also ignore minified CSS files as a best practice
|
|
23
23
|
],
|
|
24
24
|
rules: {
|
|
25
|
-
|
|
25
|
+
'selector-pseudo-class-no-unknown': [
|
|
26
26
|
true,
|
|
27
27
|
{
|
|
28
|
-
ignorePseudoClasses: [
|
|
28
|
+
ignorePseudoClasses: [':global'], // Allow :global for Svelte scoped styles
|
|
29
29
|
},
|
|
30
30
|
],
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
'property-no-vendor-prefix': null, // Allow vendor prefixes
|
|
32
|
+
'selector-no-vendor-prefix': null,
|
|
33
|
+
'selector-pseudo-element-colon-notation': [
|
|
34
|
+
'double',
|
|
35
35
|
{
|
|
36
|
-
severity:
|
|
36
|
+
severity: 'warning',
|
|
37
37
|
},
|
|
38
38
|
],
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
'media-feature-name-no-vendor-prefix': null,
|
|
40
|
+
'font-family-no-duplicate-names': [
|
|
41
41
|
true,
|
|
42
42
|
{
|
|
43
|
-
ignoreFontFamilyNames: [
|
|
43
|
+
ignoreFontFamilyNames: ['monospace'],
|
|
44
44
|
},
|
|
45
45
|
],
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
'selector-class-pattern': [
|
|
47
|
+
'^(?!fa-).*$', // Disallow classes starting with "fa-"
|
|
48
48
|
{
|
|
49
49
|
message:
|
|
50
50
|
"Class names must not start with 'fa-' (FontAwesome classes are ignored)",
|
|
51
51
|
},
|
|
52
52
|
],
|
|
53
|
-
|
|
53
|
+
'order/properties-order': [
|
|
54
54
|
[
|
|
55
55
|
{
|
|
56
|
-
groupName:
|
|
57
|
-
properties: [
|
|
56
|
+
groupName: 'Positioning',
|
|
57
|
+
properties: ['position', 'top', 'right', 'bottom', 'left', 'z-index'],
|
|
58
58
|
},
|
|
59
59
|
{
|
|
60
|
-
groupName:
|
|
60
|
+
groupName: 'Box Model',
|
|
61
61
|
properties: [
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
62
|
+
'display',
|
|
63
|
+
'flex',
|
|
64
|
+
'flex-grow',
|
|
65
|
+
'flex-shrink',
|
|
66
|
+
'flex-basis',
|
|
67
|
+
'justify-content',
|
|
68
|
+
'align-items',
|
|
69
|
+
'align-self',
|
|
70
|
+
'width',
|
|
71
|
+
'height',
|
|
72
|
+
'padding',
|
|
73
|
+
'margin',
|
|
74
|
+
'border',
|
|
75
|
+
'box-shadow',
|
|
76
76
|
],
|
|
77
77
|
},
|
|
78
78
|
{
|
|
79
|
-
groupName:
|
|
79
|
+
groupName: 'Typography',
|
|
80
80
|
properties: [
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
81
|
+
'font',
|
|
82
|
+
'font-size',
|
|
83
|
+
'font-weight',
|
|
84
|
+
'line-height',
|
|
85
|
+
'letter-spacing',
|
|
86
|
+
'color',
|
|
87
|
+
'text-align',
|
|
88
88
|
],
|
|
89
89
|
},
|
|
90
90
|
{
|
|
91
|
-
groupName:
|
|
91
|
+
groupName: 'Visual',
|
|
92
92
|
properties: [
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
93
|
+
'background',
|
|
94
|
+
'background-color',
|
|
95
|
+
'background-image',
|
|
96
|
+
'opacity',
|
|
97
|
+
'visibility',
|
|
98
98
|
],
|
|
99
99
|
},
|
|
100
100
|
{
|
|
101
|
-
groupName:
|
|
102
|
-
properties: [
|
|
101
|
+
groupName: 'Animation & Transform',
|
|
102
|
+
properties: ['transition', 'transform', 'animation'],
|
|
103
103
|
},
|
|
104
104
|
],
|
|
105
105
|
{
|
|
106
|
-
unspecified:
|
|
106
|
+
unspecified: 'bottomAlphabetical', // Place unspecified properties alphabetically at the bottom
|
|
107
107
|
},
|
|
108
108
|
],
|
|
109
109
|
},
|
package/svelte.config.js
CHANGED
|
@@ -6,8 +6,8 @@ SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
|
|
|
6
6
|
This file is part of Network Pro.
|
|
7
7
|
========================================================================= */
|
|
8
8
|
|
|
9
|
-
import adapter from
|
|
10
|
-
import { vitePreprocess } from
|
|
9
|
+
import adapter from '@sveltejs/adapter-netlify'; // Netlify adapter for deployment
|
|
10
|
+
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; // Vite preprocessor for Svelte
|
|
11
11
|
|
|
12
12
|
const config = {
|
|
13
13
|
// Preprocessors for enhanced functionality (vitePreprocess + mdsvex for Markdown support + svelte-preprocess for PostCSS)
|
|
@@ -15,7 +15,7 @@ const config = {
|
|
|
15
15
|
vitePreprocess({
|
|
16
16
|
postcss: true,
|
|
17
17
|
mdsvex: {
|
|
18
|
-
extensions: [
|
|
18
|
+
extensions: ['.svx', '.md'],
|
|
19
19
|
},
|
|
20
20
|
}),
|
|
21
21
|
],
|
|
@@ -29,14 +29,14 @@ const config = {
|
|
|
29
29
|
|
|
30
30
|
// Paths configuration for deployment
|
|
31
31
|
paths: {
|
|
32
|
-
base:
|
|
32
|
+
base: '', // Always deploy to the root of the domain
|
|
33
33
|
},
|
|
34
34
|
|
|
35
35
|
prerender: {
|
|
36
36
|
// Handle HTTP errors during prerendering
|
|
37
37
|
handleHttpError: ({ path, _referrer, message }) => {
|
|
38
38
|
// Paths to ignore and warn about
|
|
39
|
-
const warnList = [
|
|
39
|
+
const warnList = ['/...404'];
|
|
40
40
|
|
|
41
41
|
if (warnList.includes(path)) {
|
|
42
42
|
console.warn(`Prerender error at path: ${path}, message: ${message}`);
|
|
@@ -50,7 +50,7 @@ const config = {
|
|
|
50
50
|
},
|
|
51
51
|
|
|
52
52
|
// File extensions for Svelte and mdsvex
|
|
53
|
-
extensions: [
|
|
53
|
+
extensions: ['.svelte', '.svx', '.md'], // Added .md for Markdown support
|
|
54
54
|
};
|
|
55
55
|
|
|
56
56
|
export default config;
|