mnfst 0.5.267 → 0.5.268

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.
@@ -2,7 +2,7 @@
2
2
 
3
3
  (function () {
4
4
 
5
- const MANIFEST_BUILD_VERSION = '0.5.267';
5
+ const MANIFEST_BUILD_VERSION = '0.5.268';
6
6
 
7
7
  /* Manifest Data Sources - Appwrite Integration */
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  (function () {
4
4
 
5
- const MANIFEST_BUILD_VERSION = '0.5.267';
5
+ const MANIFEST_BUILD_VERSION = '0.5.268';
6
6
 
7
7
  /* Manifest Data Sources - Configuration */
8
8
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "manifest.appwrite.auth.js": "sha384-gWLSeVPqCLMiUZB8MU7GqMg3x2yULFUsp8nTTZrPp/9Dlkix42rBn9yIimvwrHqZ",
3
- "manifest.appwrite.data.js": "sha384-81l7vI/UteYuZxU0z7NMMOC7nUzu8nMaB4JbGLHUbIxutpjeuD81PYsL7beVKsih",
3
+ "manifest.appwrite.data.js": "sha384-RH/7vbH/n5AA9HcChWPgenc/CLjTw0WmXhExvd9rPvpvLTHcn7a6XnbFj7WgTvh7",
4
4
  "manifest.appwrite.presences.js": "sha384-/CagPsgWhO1sWEevCNGJmZ/ezRK9YCjLjvF7hxNSM4gVlJmEVtfSLfF7wnsRq441",
5
5
  "manifest.bindings.js": "sha384-lPtMf8Ykaic9gNVZKq8Scia1881ZeMAyxer3WCIkUNwwrgzGBWto1OXADUwjvORF",
6
6
  "manifest.charts.js": "sha384-AFbP7mQnigy7DU1s+YE30yKTeQAKfgNazhbfSNbfd9ZpLgeulZKaPi/fAq3gJHDO",
@@ -11,7 +11,7 @@
11
11
  "manifest.combobox.js": "sha384-/lJo6vaxKjgnBSRs/dzkhK1dzGk3GBw8FISoNJZB70mwAVwu1k5veZyBXjOb4keS",
12
12
  "manifest.components.js": "sha384-BUFA8h+G5Plr82sV7bKzO42pPoiRZwRQcKj1lt2ROFiKjjlkayU/vmkAFqEsdBA+",
13
13
  "manifest.computed.js": "sha384-GYML/e81gQfN+iDbqhPUgny8bINCyL+SrbTofoGk4hlCnLLjv51mCv42JMqq+ku5",
14
- "manifest.data.js": "sha384-aEAnoRnpJZaXR0AWUZ+pGF9Cu8qlPpFzlcT58DnMkaZuKC9yL0l36LdRPGlkPIx0",
14
+ "manifest.data.js": "sha384-0zOYRKpPT5mGZjqprhfxadWH+wgMRZD6EfWoSUNToxUu8khleX0Is2yF8pItoLZ5",
15
15
  "manifest.datepicker.js": "sha384-EzlMwvIxlla/0BuyhAEqxN0M8TGcWIWgEIg840V0akKQQK1uY648wPWMkobvtq/o",
16
16
  "manifest.defer.js": "sha384-5cHzFTbx+cZmGpk9FuiUtW3ciC9NvvHwJeHP7xL5yiZVp9PhMWVdQ7L9y6ju2yoo",
17
17
  "manifest.device.js": "sha384-YeQaS56L8IILqrQNBSeAOLwIh5DuAOrE60cYLK1+46qJtUrXlAvqGe2j5mbV4Vq7",
@@ -20,7 +20,7 @@
20
20
  "manifest.export.js": "sha384-C4W5LrGQFnSILRWoWOCliajUK6rAzNW+EliogRx72vD1cUOYScSdfzHNbjSWv5XU",
21
21
  "manifest.icons.js": "sha384-kKOINpX70YzNO3FvkV6umrmO3f0KIu0DNbwB+ej55a7y/lhU7v/myQtXL0bwCTbt",
22
22
  "manifest.localization.js": "sha384-EImsIw8Z3l13V5eH9ZJF/yfsOfIvR1oPRNSArANkPji7V8O3IRf6zMwsNiAGj3Hk",
23
- "manifest.markdown.js": "sha384-8bZCrYOZ/s0lcZIU79YmB6U7/XOS0UgdjxNvWIVc/aSdQxPTXTCuFfkbvkS0DnPG",
23
+ "manifest.markdown.js": "sha384-icbpHC8dIijEJSaW3CODo4Ft7dBQz53pUh/2OYVBEFrLQbrFs370D+eMygJx5cW8",
24
24
  "manifest.native.js": "sha384-YeQaS56L8IILqrQNBSeAOLwIh5DuAOrE60cYLK1+46qJtUrXlAvqGe2j5mbV4Vq7",
25
25
  "manifest.payments.js": "sha384-8pofk2zhxtapPMpwnFyTelPMrYhShNhDCE722uQh/EYFvZFuPLmSdgunqsarVQjv",
26
26
  "manifest.rich.text.js": "sha384-ZBV9jXmu2nmprEHicddRE/m7nR4RPZtVc969Jte0+EJYBcVph7itkjcgN/61PyeC",
@@ -28,7 +28,7 @@
28
28
  "manifest.slides.js": "sha384-3uRTkyK9XPLmnxI2+igZlpi4EyPlU/7IHj5j3BZJJ2KN455vXyk99fiXV3feO/XY",
29
29
  "manifest.status.js": "sha384-ofu7nBnVIGZ1U1o2R9d2H3V8aEMPUCVbl5FO3gIToXqi0oa36fTviEdh5UU7Kitw",
30
30
  "manifest.svg.js": "sha384-qr/8H9+2cIhSXNbRWRtIdrDlTOxKlNJqwEefHvCYoiBNW/kKhPTFa109Orv/EBnb",
31
- "manifest.sw.js": "sha384-BWZsM4KfbumoQMhr8aGWLpUgTDfWHEW6thJ4TbBoR/hA/clJcUbXNearDmqTK5vM",
31
+ "manifest.sw.js": "sha384-hH5Xmqs5NY7oWLl+NYD6exIoqg9TDi8HPHB3Jg/sWnHEZUJWNJwlXlMkAvbCSfu5",
32
32
  "manifest.tabs.js": "sha384-otU09H7jnawVKQdLAYpMCd3jx00tgyPVr42D2hLIBzN5dG4se505YesavdnMqEi1",
33
33
  "manifest.tailwind.js": "sha384-yuP3LEvWU+QVjxjkZ0YhErtC9RrGmhOmHjjFjhS9obqZbp5/KTIEnSR0CXDvHE0B",
34
34
  "manifest.toasts.js": "sha384-UpOz9fAdGeGUhL0NamBg5iPepEfIy73p9HYdcxfOQC5b7CVsl7Our0skdZzaLNcC",
@@ -15,8 +15,35 @@ if (typeof window !== 'undefined') {
15
15
  });
16
16
  }
17
17
 
18
- // DOMPurify defaults for .safe: no custom elements, no directive or event attributes
19
- const MARKDOWN_PURIFY_CONFIG = {};
18
+ // .safe: HTML only (no SVG/MathML, custom elements, directives or handlers), minus page-level styling, forms and media
19
+ const MARKDOWN_PURIFY_CONFIG = {
20
+ USE_PROFILES: { html: true },
21
+ FORBID_TAGS: ['style', 'form', 'template', 'dialog', 'video', 'audio'],
22
+ FORBID_ATTR: ['style', 'popover', 'popovertarget', 'popovertargetaction', 'formaction', 'command', 'commandfor', 'autoplay', 'background'],
23
+ ALLOW_DATA_ATTR: false,
24
+ SANITIZE_NAMED_PROPS: true
25
+ };
26
+ // Callout classes only; any other class could compile to a utility (fixed inset-0 …)
27
+ const MARKDOWN_SAFE_CLASSES = new Set(['brand', 'accent', 'positive', 'negative', 'frame']);
28
+
29
+ function restrictSafeClasses(html) {
30
+ const t = document.createElement('template');
31
+ t.innerHTML = html;
32
+ t.content.querySelectorAll('input[type="image" i]').forEach(el => el.remove());
33
+ t.content.querySelectorAll('[class]').forEach(el => {
34
+ const keep = el.tagName === 'ASIDE' ? [...el.classList].filter(c => MARKDOWN_SAFE_CLASSES.has(c)) : [];
35
+ if (keep.length) el.setAttribute('class', keep.join(' '));
36
+ else el.removeAttribute('class');
37
+ });
38
+ // Ids carry DOMPurify's user-content- prefix; follow it in in-content anchors
39
+ t.content.querySelectorAll('a[href^="#"]').forEach(a => {
40
+ const raw = a.getAttribute('href').slice(1);
41
+ let id;
42
+ try { id = decodeURIComponent(raw); } catch { id = raw; }
43
+ if (id && t.content.getElementById('user-content-' + id)) a.setAttribute('href', '#user-content-' + id);
44
+ });
45
+ return t.innerHTML;
46
+ }
20
47
 
21
48
  // Shared DOMPurify loader on window (svg.js or markdown, whichever loads first).
22
49
  // A top-level `let purifyPromise` would collide with svg.js's identical one.
@@ -57,7 +84,7 @@ async function maybeSanitizeMarkdownHtml(html, safe) {
57
84
  if (!safe) return html;
58
85
  try {
59
86
  const DOMPurify = await window.ManifestDOMPurify.load();
60
- return DOMPurify.sanitize(html, MARKDOWN_PURIFY_CONFIG);
87
+ return restrictSafeClasses(DOMPurify.sanitize(html, MARKDOWN_PURIFY_CONFIG));
61
88
  } catch {
62
89
  // Loader failure — escape rather than emit un-sanitized HTML (.safe was asked for).
63
90
  const escaped = String(html)
@@ -16,7 +16,7 @@
16
16
 
17
17
  // Build stamps the published version here; unstamped (dev) falls back to the
18
18
  // registration URL's `v`, then 'dev'.
19
- const BUILD_VERSION = '0.5.267';
19
+ const BUILD_VERSION = '0.5.268';
20
20
  const CACHE_PREFIX = 'mnfst-sw:';
21
21
  const META_CACHE = CACHE_PREFIX + 'meta';
22
22
  // Sized to hold a full precache.json warm-up (PRECACHE_MAX_ENTRIES server-side)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mnfst",
3
- "version": "0.5.267",
3
+ "version": "0.5.268",
4
4
  "private": false,
5
5
  "workspaces": [
6
6
  "templates/starter",
@@ -48,6 +48,7 @@
48
48
  "test:e2e:sw": "node tests/e2e/sw.e2e.mjs",
49
49
  "test:e2e:settle": "node tests/e2e/render-settle.e2e.mjs",
50
50
  "test:e2e:magic": "node tests/e2e/magic-one-arg.e2e.mjs",
51
+ "test:e2e:markdown-safe": "node tests/e2e/markdown-safe.e2e.mjs",
51
52
  "test:e2e:upload": "node tests/e2e/upload-first-load.e2e.mjs",
52
53
  "lint": "echo 'No linting configured'",
53
54
  "release:docs": "node scripts/release-bump.mjs packages/docs && cd packages/docs && npm publish --auth-type=web",
@@ -60,6 +61,7 @@
60
61
  "@tailwindcss/cli": "^4.2.4",
61
62
  "alpinejs": "3.17.5",
62
63
  "cssnano": "^7.1.1",
64
+ "dompurify": "3.4.10",
63
65
  "entities": "4.5.0",
64
66
  "glob": "^11.0.2",
65
67
  "happy-dom": "^20.11.6",