From 9340e16988544a5caecad8054c1868dff8da92b6 Mon Sep 17 00:00:00 2001 From: Hans-christian Date: Thu, 18 Jun 2026 11:14:29 +0200 Subject: [PATCH 01/10] Fix Prism startup crashes --- src/components/FdpFooter/index.vue | 11 ++- src/components/PrismEditor/index.vue | 26 +++++- src/components/VersionInfoTable/index.vue | 11 ++- src/main.ts | 3 - src/prism-languages.ts | 98 +++++++++++++++++++++++ 5 files changed, 138 insertions(+), 11 deletions(-) create mode 100644 src/prism-languages.ts diff --git a/src/components/FdpFooter/index.vue b/src/components/FdpFooter/index.vue index 3879e324..03811f89 100644 --- a/src/components/FdpFooter/index.vue +++ b/src/components/FdpFooter/index.vue @@ -56,8 +56,15 @@ export default defineComponent({ }, methods: { async fetchData(): Promise { - const response = await api.info.getInfo() - this.info = response.data + try { + const response = await api.info.getInfo() + this.info = { + version: response.data?.version || '', + builtAt: response.data?.builtAt || '', + } + } catch (error) { + console.error('Unable to load About dialog info:', error) + } }, }, }) diff --git a/src/components/PrismEditor/index.vue b/src/components/PrismEditor/index.vue index 25c34031..5bf16b4d 100644 --- a/src/components/PrismEditor/index.vue +++ b/src/components/PrismEditor/index.vue @@ -9,6 +9,18 @@ import { defineComponent } from 'vue' import { PrismEditor as BasePrismEditor } from 'vue-prism-editor' import Prism from 'prismjs' +import { registerPrismLanguages } from '@/prism-languages' + +registerPrismLanguages(Prism) + +function escapeHtml(code: string): string { + return code + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, ''') +} export default defineComponent({ name: 'PrismEditor', @@ -26,8 +38,18 @@ export default defineComponent({ const highlight = (code: string) => { const lang = props.language || 'markup' const languages = (Prism as any).languages || {} - const grammar = languages[lang] || languages.markup - return Prism.highlight(code, grammar, lang) + const grammar = languages[lang] + + if (!grammar) { + return escapeHtml(code) + } + + try { + return Prism.highlight(code, grammar, lang) + } catch (error) { + console.warn(`Prism highlighting failed for "${lang}", falling back to plain text.`, error) + return escapeHtml(code) + } } return { diff --git a/src/components/VersionInfoTable/index.vue b/src/components/VersionInfoTable/index.vue index e2105ed2..017e8a86 100644 --- a/src/components/VersionInfoTable/index.vue +++ b/src/components/VersionInfoTable/index.vue @@ -11,7 +11,7 @@ Version - {{ version.slice(0, 36) }} + {{ safeVersion.slice(0, 36) }} Built at @@ -28,12 +28,15 @@ import moment from 'moment' export default defineComponent({ props: { title: { type: String, required: true }, - version: { type: String, required: true }, - builtAt: { type: String, required: true }, + version: { type: String, default: '' }, + builtAt: { type: String, default: '' }, }, computed: { + safeVersion(): string { + return this.version || '' + }, builtAtFormatted() { - return moment(this.builtAt).format('D. M. YYYY, HH:mm') + return this.builtAt ? moment(this.builtAt).format('D. M. YYYY, HH:mm') : 'Unknown' }, }, }) diff --git a/src/main.ts b/src/main.ts index e413bd19..83cf2bde 100644 --- a/src/main.ts +++ b/src/main.ts @@ -8,9 +8,6 @@ import 'bootstrap-vue-next/dist/bootstrap-vue-next.css' import 'prismjs/themes/prism.css' import 'vue-prism-editor/dist/prismeditor.min.css' import 'vue-select/dist/vue-select.css' -import 'prismjs' -import 'prismjs/components/prism-turtle' -import 'prismjs/components/prism-sparql' import { createEntityConfigs } from '@/entity/entityConfigs' import type { EntitySpec } from '@/entity/EntityConfig' import App from './App.vue' diff --git a/src/prism-languages.ts b/src/prism-languages.ts new file mode 100644 index 00000000..a8cccfeb --- /dev/null +++ b/src/prism-languages.ts @@ -0,0 +1,98 @@ +function registerTurtle(Prism: any): void { + const { languages } = Prism + + if (languages.turtle) { + return + } + + languages.turtle = { + comment: { + pattern: /#.*/, + greedy: true, + }, + 'multiline-string': { + pattern: /"""(?:(?:""?)?(?:[^"\\]|\\.))*"""|'''(?:(?:''?)?(?:[^'\\]|\\.))*'''/, + greedy: true, + alias: 'string', + inside: { + comment: /#.*/, + }, + }, + string: { + pattern: /"(?:[^\\"\r\n]|\\.)*"|'(?:[^\\'\r\n]|\\.)*'/, + greedy: true, + }, + url: { + // Prism's Turtle grammar needs the ASCII control-character range here. + // eslint-disable-next-line no-control-regex + pattern: /<(?:[^\x00-\x20<>"{}|^`\\]|\\(?:u[\da-fA-F]{4}|U[\da-fA-F]{8}))*>/, + greedy: true, + inside: { + punctuation: /[<>]/, + }, + }, + function: { + pattern: /(?:(?![-.\d\xB7])[-.\w\xB7\xC0-\uFFFD]+)?:(?:(?![-.])(?:[-.:\w\xC0-\uFFFD]|%[\da-f]{2}|\\.)+)?/i, + inside: { + 'local-name': { + pattern: /([^:]*:)[\s\S]+/, + lookbehind: true, + }, + prefix: { + pattern: /[\s\S]+/, + inside: { + punctuation: /:/, + }, + }, + }, + }, + number: /[+-]?\b\d+(?:\.\d*)?(?:e[+-]?\d+)?/i, + punctuation: /[{}.,;()[\]]|\^\^/, + boolean: /\b(?:false|true)\b/, + keyword: [ + /(?:\ba|@prefix|@base)\b|=/, + /\b(?:base|graph|prefix)\b/i, + ], + tag: { + pattern: /@[a-z]+(?:-[a-z\d]+)*/i, + inside: { + punctuation: /@/, + }, + }, + } + + languages.trig = languages.turtle +} + +function registerSparql(Prism: any): void { + const { languages } = Prism + + if (languages.sparql) { + return + } + + registerTurtle(Prism) + + languages.sparql = languages.extend('turtle', { + boolean: /\b(?:false|true)\b/i, + variable: { + pattern: /[?$]\w+/, + greedy: true, + }, + }) + + Prism.languages.insertBefore('sparql', 'punctuation', { + keyword: [ + /\b(?:A|ADD|ALL|AS|ASC|ASK|BNODE|BY|CLEAR|CONSTRUCT|COPY|CREATE|DATA|DEFAULT|DELETE|DESC|DESCRIBE|DISTINCT|DROP|EXISTS|FILTER|FROM|GROUP|HAVING|INSERT|INTO|LIMIT|LOAD|MINUS|MOVE|NAMED|NOT|NOW|OFFSET|OPTIONAL|ORDER|RAND|REDUCED|SELECT|SEPARATOR|SERVICE|SILENT|STRUUID|UNION|USING|UUID|VALUES|WHERE)\b/i, + /\b(?:ABS|AVG|BIND|BOUND|CEIL|COALESCE|CONCAT|CONTAINS|COUNT|DATATYPE|DAY|ENCODE_FOR_URI|FLOOR|GROUP_CONCAT|HOURS|IF|IRI|isBLANK|isIRI|isLITERAL|isNUMERIC|isURI|LANG|LANGMATCHES|LCASE|MAX|MD5|MIN|MINUTES|MONTH|REGEX|REPLACE|ROUND|sameTerm|SAMPLE|SECONDS|SHA1|SHA256|SHA384|SHA512|STR|STRAFTER|STRBEFORE|STRDT|STRENDS|STRLANG|STRLEN|STRSTARTS|SUBSTR|SUM|TIMEZONE|TZ|UCASE|URI|YEAR)\b(?=\s*\()/i, + /\b(?:BASE|GRAPH|PREFIX)\b/i, + ], + }) + + languages.rq = languages.sparql +} + +export function registerPrismLanguages(Prism: any): void { + registerTurtle(Prism) + registerSparql(Prism) +} From 878b0c18cf40506a8fe114d1ec0330ac341fa79a Mon Sep 17 00:00:00 2001 From: Hans-christian Date: Thu, 18 Jun 2026 11:25:30 +0200 Subject: [PATCH 02/10] docs: add release notes after v1.0.6 --- CHANGELOG.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb18bdc1..07a615bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Release notes since `v1.0.6` + +| Area | Package updates | Impact | +| --- | --- | --- | +| UI components | `bootstrap-vue-next` `0.42.0 -> 0.45.5` | Bootstrap component compatibility and rendering stability. | +| Vue runtime | `vue` `3.5.34 -> 3.5.35`, `vue-router` `4.6.4 -> 5.0.6`, `@fortawesome/vue-fontawesome` `3.1.3 -> 3.2.0` | Framework and router patch updates, plus icon component compatibility. | +| Icons | `@fortawesome/free-regular-svg-icons`, `@fortawesome/free-solid-svg-icons` | Updated icon set used by the UI. | +| RDF and data handling | `rdflib` `2.3.8 -> 2.3.9`, `vis-data` `6.4.1 -> 8.0.4` | RDF parsing and graph/data handling updates. | +| Tooling | `vite` `8.0.13/8.0.14 -> 8.0.16`, `core-js` `3.47.0 -> 3.49.0`, `semver` `7.8.0 -> 7.8.1`, `tmp` `0.2.5 -> 0.2.7`, `form-data` `4.0.5 -> 4.0.6` | Build/runtime and indirect dependency stability and security updates. | + +### Release process fixes since `v1.0.6` + +- `fix: make release tag selection stable` prevented the release workflow from picking the wrong tag. +- `fix: skip existing release versions` prevented duplicate release creation for already published versions. +- The Prism white-screen/startup crash in the current branch is fixed by code in `PrismEditor`, not by an npm package update. + ## [v1.0.6] - 2026-05-05 ### Changed From eb2e379ef08e8a80f693d9e7401eaa1fd1c01be1 Mon Sep 17 00:00:00 2001 From: Hans-christian Date: Thu, 18 Jun 2026 11:36:26 +0200 Subject: [PATCH 03/10] Revert Prism workaround and pin Vite 8.0.14 --- CHANGELOG.md | 4 +- package-lock.json | 164 ++++++++++++--------------- package.json | 2 +- src/components/PrismEditor/index.vue | 26 +---- src/main.ts | 3 + src/prism-languages.ts | 98 ---------------- 6 files changed, 81 insertions(+), 216 deletions(-) delete mode 100644 src/prism-languages.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 07a615bc..363be22a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,13 +15,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | Vue runtime | `vue` `3.5.34 -> 3.5.35`, `vue-router` `4.6.4 -> 5.0.6`, `@fortawesome/vue-fontawesome` `3.1.3 -> 3.2.0` | Framework and router patch updates, plus icon component compatibility. | | Icons | `@fortawesome/free-regular-svg-icons`, `@fortawesome/free-solid-svg-icons` | Updated icon set used by the UI. | | RDF and data handling | `rdflib` `2.3.8 -> 2.3.9`, `vis-data` `6.4.1 -> 8.0.4` | RDF parsing and graph/data handling updates. | -| Tooling | `vite` `8.0.13/8.0.14 -> 8.0.16`, `core-js` `3.47.0 -> 3.49.0`, `semver` `7.8.0 -> 7.8.1`, `tmp` `0.2.5 -> 0.2.7`, `form-data` `4.0.5 -> 4.0.6` | Build/runtime and indirect dependency stability and security updates. | +| Tooling | `vite` `8.0.16 -> 8.0.14`, `core-js` `3.47.0 -> 3.49.0`, `semver` `7.8.0 -> 7.8.1`, `tmp` `0.2.5 -> 0.2.7`, `form-data` `4.0.5 -> 4.0.6` | Build/runtime and indirect dependency stability and security updates. | ### Release process fixes since `v1.0.6` - `fix: make release tag selection stable` prevented the release workflow from picking the wrong tag. - `fix: skip existing release versions` prevented duplicate release creation for already published versions. -- The Prism white-screen/startup crash in the current branch is fixed by code in `PrismEditor`, not by an npm package update. +- The Prism white-screen/startup crash is avoided by rolling Vite back to `8.0.14`, which restores a workable production bundle. ## [v1.0.6] - 2026-05-05 diff --git a/package-lock.json b/package-lock.json index cacd8e00..083969af 100644 --- a/package-lock.json +++ b/package-lock.json @@ -57,7 +57,7 @@ "sass-loader": "^12.6.0", "typescript": "^4.6.2", "url": "^0.11.0", - "vite": "^8.0.16" + "vite": "^8.0.14" } }, "node_modules/@babel/code-frame": { @@ -670,9 +670,9 @@ } }, "node_modules/@oxc-project/types": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.133.0.tgz", - "integrity": "sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==", + "version": "0.132.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.132.0.tgz", + "integrity": "sha512-FESMOxil5Se014ui/Eq8fT5uHJo6nIRwH0PfJrZJXs6Gek3ZVFOrpUv3YIZT20m+extU98Hg1Ym72U58rlsxUQ==", "dev": true, "license": "MIT", "funding": { @@ -1024,9 +1024,9 @@ } }, "node_modules/@rolldown/binding-android-arm64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz", - "integrity": "sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.2.tgz", + "integrity": "sha512-ZS4D1JPGn/MYQN/SYDWftIE/nVsM8j/AFOYEzAoOE2O3NktQOZru+/vYXGbR/qtdLdIfGCP0lcoJiYVzsEz+iQ==", "cpu": [ "arm64" ], @@ -1041,9 +1041,9 @@ } }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.3.tgz", - "integrity": "sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.2.tgz", + "integrity": "sha512-vdFA9+C/rekyGce7WqHs/xoT0ioZEWaOFyZLIV1mEeNFaFDUQrPIo8Vs2GvJ6eetb3rzDUtUBgzto3ExpXJB3w==", "cpu": [ "arm64" ], @@ -1058,9 +1058,9 @@ } }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.3.tgz", - "integrity": "sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.2.tgz", + "integrity": "sha512-BewSOwTHazv77DTYiAZXSqqKZ4KP/KonFisDMVU7PImxoWfB2aepnPhd2E4SWz3zDzYgDNbs6jBmTdgNnF02GA==", "cpu": [ "x64" ], @@ -1075,9 +1075,9 @@ } }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.3.tgz", - "integrity": "sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.2.tgz", + "integrity": "sha512-m41o7M0YWtUdqk61Tb+jnKb2rN++iRdIASlExkUoKfIAH30DOHCB8fVLzSUpbWHHU8esmEioY62PxzexE8MBuA==", "cpu": [ "x64" ], @@ -1092,9 +1092,9 @@ } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.3.tgz", - "integrity": "sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.2.tgz", + "integrity": "sha512-jcojB9H7W/jS29pMKWAK1N+fU99vXodHDTatS3b3y/XSOCiHo0kkA74pL3jJmkoQtYpOCxDvaKs1fo2Ij/1X5w==", "cpu": [ "arm" ], @@ -1109,16 +1109,13 @@ } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.3.tgz", - "integrity": "sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.2.tgz", + "integrity": "sha512-1jn6qDU5iiOgFgygDzKUuKP0maTi0/f1+sBLgvij/76C77Nm3ts6ufz9Bjg5q5dduxiUIxtq86JIoBvo1xQ4Ig==", "cpu": [ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1129,16 +1126,13 @@ } }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.3.tgz", - "integrity": "sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.2.tgz", + "integrity": "sha512-QVLO/czFMdoMFSqlX3bcswcJNm/23r+qoa/jgtmFc/qEp6/jXmIkDjF/XIo8dPfGaiwy1xfQn8o77L79GeXFgw==", "cpu": [ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -1149,16 +1143,13 @@ } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.3.tgz", - "integrity": "sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.2.tgz", + "integrity": "sha512-hgO5Abm0w5UL6FEa2iFnZqo2KlK7TQ5QhV5x09hujBf7t5KzHQ1VmfPuTpqRy/rNlSxua3eWH374xxiVrP+lcA==", "cpu": [ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1169,16 +1160,13 @@ } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.3.tgz", - "integrity": "sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.2.tgz", + "integrity": "sha512-fy8rXxuYEu602abC8MUNaPjYLIFzReOaEIEMKMUa0rFEUxNpVXhs15KSSQ4qlqSaM7B6rcj9rDZgADh/IGDzLQ==", "cpu": [ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1189,16 +1177,13 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.3.tgz", - "integrity": "sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.2.tgz", + "integrity": "sha512-0+bOkiQ779+r1WpoHOWHqncvyySci0vKph+myNDYb+im6meJAzHQXay6oEgnkHuUGouM1LKTZwqKpBow6Kj7CQ==", "cpu": [ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1209,16 +1194,13 @@ } }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.3.tgz", - "integrity": "sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.2.tgz", + "integrity": "sha512-mjSkrzZK5Qsl0a9d1JgILOiuZOSDTVdKENcSXBoqbzSrspLR/4/IRVDo5wd2GgZjNss/viBFJdeq+j7qH2nypw==", "cpu": [ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -1229,9 +1211,9 @@ } }, "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.3.tgz", - "integrity": "sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.2.tgz", + "integrity": "sha512-1v5vHasdfQAZoEHakBV72LIFAC9JjnymsiKxp+GEr/ma3+NJCPSaYK+qavInOovJkgwFrs7GccX2d6IgDA3Z5w==", "cpu": [ "arm64" ], @@ -1246,9 +1228,9 @@ } }, "node_modules/@rolldown/binding-wasm32-wasi": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.3.tgz", - "integrity": "sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.2.tgz", + "integrity": "sha512-mb1VobWn6NheziTk5/WEaR6AKVbrwT5sOi6C7zk3gy/pD1qtJfU1j4PgTo2NJnOtbL9Dl3Aeei8w9jJ7qC2jZQ==", "cpu": [ "wasm32" ], @@ -1265,9 +1247,9 @@ } }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.3.tgz", - "integrity": "sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.2.tgz", + "integrity": "sha512-SqKonF56vA/L2yHwHYcEp2P34URpOZ7d1fS635cTkpDnUtEGdUbhI6NzsPdqeSWvAAeGDrxjWjNmibDIdFf9/A==", "cpu": [ "arm64" ], @@ -1282,9 +1264,9 @@ } }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz", - "integrity": "sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.2.tgz", + "integrity": "sha512-v7qRI7gXLRINcOGXt+7YmAZ6iFuyZVMIoXAxhd8oP+DR9dLfL9GfNIx7PLMxmhZdvq8waUJBQiWN9EKNy+TRBQ==", "cpu": [ "x64" ], @@ -7903,13 +7885,13 @@ } }, "node_modules/rolldown": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.3.tgz", - "integrity": "sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.2.tgz", + "integrity": "sha512-oZx5zVDtVB44AW3eaifgDml1gWRDZGvjcfdxonE4swNPG98PrrXjaO/KrnUjzlMnztCCRVlUueA1kCXhARGk6g==", "dev": true, "license": "MIT", "dependencies": { - "@oxc-project/types": "=0.133.0", + "@oxc-project/types": "=0.132.0", "@rolldown/pluginutils": "^1.0.0" }, "bin": { @@ -7919,21 +7901,21 @@ "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rolldown/binding-android-arm64": "1.0.3", - "@rolldown/binding-darwin-arm64": "1.0.3", - "@rolldown/binding-darwin-x64": "1.0.3", - "@rolldown/binding-freebsd-x64": "1.0.3", - "@rolldown/binding-linux-arm-gnueabihf": "1.0.3", - "@rolldown/binding-linux-arm64-gnu": "1.0.3", - "@rolldown/binding-linux-arm64-musl": "1.0.3", - "@rolldown/binding-linux-ppc64-gnu": "1.0.3", - "@rolldown/binding-linux-s390x-gnu": "1.0.3", - "@rolldown/binding-linux-x64-gnu": "1.0.3", - "@rolldown/binding-linux-x64-musl": "1.0.3", - "@rolldown/binding-openharmony-arm64": "1.0.3", - "@rolldown/binding-wasm32-wasi": "1.0.3", - "@rolldown/binding-win32-arm64-msvc": "1.0.3", - "@rolldown/binding-win32-x64-msvc": "1.0.3" + "@rolldown/binding-android-arm64": "1.0.2", + "@rolldown/binding-darwin-arm64": "1.0.2", + "@rolldown/binding-darwin-x64": "1.0.2", + "@rolldown/binding-freebsd-x64": "1.0.2", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.2", + "@rolldown/binding-linux-arm64-gnu": "1.0.2", + "@rolldown/binding-linux-arm64-musl": "1.0.2", + "@rolldown/binding-linux-ppc64-gnu": "1.0.2", + "@rolldown/binding-linux-s390x-gnu": "1.0.2", + "@rolldown/binding-linux-x64-gnu": "1.0.2", + "@rolldown/binding-linux-x64-musl": "1.0.2", + "@rolldown/binding-openharmony-arm64": "1.0.2", + "@rolldown/binding-wasm32-wasi": "1.0.2", + "@rolldown/binding-win32-arm64-msvc": "1.0.2", + "@rolldown/binding-win32-x64-msvc": "1.0.2" } }, "node_modules/run-parallel": { @@ -9246,17 +9228,17 @@ } }, "node_modules/vite": { - "version": "8.0.16", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.16.tgz", - "integrity": "sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==", + "version": "8.0.14", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.14.tgz", + "integrity": "sha512-s4BJJ+5y1pYL6Otw51FHhVJQhPnuRinKig64g/1+EUNaJsd3gCKdD31IPFvswUgW9/60QT9oFHbZHbQK5imcxw==", "dev": true, "license": "MIT", "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.15", - "rolldown": "1.0.3", - "tinyglobby": "^0.2.17" + "rolldown": "1.0.2", + "tinyglobby": "^0.2.16" }, "bin": { "vite": "bin/vite.js" diff --git a/package.json b/package.json index d614225e..a90cced4 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "sass-loader": "^12.6.0", "typescript": "^4.6.2", "url": "^0.11.0", - "vite": "^8.0.16" + "vite": "^8.0.14" }, "overrides": { "git-up": "^8.1.0", diff --git a/src/components/PrismEditor/index.vue b/src/components/PrismEditor/index.vue index 5bf16b4d..25c34031 100644 --- a/src/components/PrismEditor/index.vue +++ b/src/components/PrismEditor/index.vue @@ -9,18 +9,6 @@ import { defineComponent } from 'vue' import { PrismEditor as BasePrismEditor } from 'vue-prism-editor' import Prism from 'prismjs' -import { registerPrismLanguages } from '@/prism-languages' - -registerPrismLanguages(Prism) - -function escapeHtml(code: string): string { - return code - .replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"') - .replace(/'/g, ''') -} export default defineComponent({ name: 'PrismEditor', @@ -38,18 +26,8 @@ export default defineComponent({ const highlight = (code: string) => { const lang = props.language || 'markup' const languages = (Prism as any).languages || {} - const grammar = languages[lang] - - if (!grammar) { - return escapeHtml(code) - } - - try { - return Prism.highlight(code, grammar, lang) - } catch (error) { - console.warn(`Prism highlighting failed for "${lang}", falling back to plain text.`, error) - return escapeHtml(code) - } + const grammar = languages[lang] || languages.markup + return Prism.highlight(code, grammar, lang) } return { diff --git a/src/main.ts b/src/main.ts index 83cf2bde..e413bd19 100644 --- a/src/main.ts +++ b/src/main.ts @@ -8,6 +8,9 @@ import 'bootstrap-vue-next/dist/bootstrap-vue-next.css' import 'prismjs/themes/prism.css' import 'vue-prism-editor/dist/prismeditor.min.css' import 'vue-select/dist/vue-select.css' +import 'prismjs' +import 'prismjs/components/prism-turtle' +import 'prismjs/components/prism-sparql' import { createEntityConfigs } from '@/entity/entityConfigs' import type { EntitySpec } from '@/entity/EntityConfig' import App from './App.vue' diff --git a/src/prism-languages.ts b/src/prism-languages.ts deleted file mode 100644 index a8cccfeb..00000000 --- a/src/prism-languages.ts +++ /dev/null @@ -1,98 +0,0 @@ -function registerTurtle(Prism: any): void { - const { languages } = Prism - - if (languages.turtle) { - return - } - - languages.turtle = { - comment: { - pattern: /#.*/, - greedy: true, - }, - 'multiline-string': { - pattern: /"""(?:(?:""?)?(?:[^"\\]|\\.))*"""|'''(?:(?:''?)?(?:[^'\\]|\\.))*'''/, - greedy: true, - alias: 'string', - inside: { - comment: /#.*/, - }, - }, - string: { - pattern: /"(?:[^\\"\r\n]|\\.)*"|'(?:[^\\'\r\n]|\\.)*'/, - greedy: true, - }, - url: { - // Prism's Turtle grammar needs the ASCII control-character range here. - // eslint-disable-next-line no-control-regex - pattern: /<(?:[^\x00-\x20<>"{}|^`\\]|\\(?:u[\da-fA-F]{4}|U[\da-fA-F]{8}))*>/, - greedy: true, - inside: { - punctuation: /[<>]/, - }, - }, - function: { - pattern: /(?:(?![-.\d\xB7])[-.\w\xB7\xC0-\uFFFD]+)?:(?:(?![-.])(?:[-.:\w\xC0-\uFFFD]|%[\da-f]{2}|\\.)+)?/i, - inside: { - 'local-name': { - pattern: /([^:]*:)[\s\S]+/, - lookbehind: true, - }, - prefix: { - pattern: /[\s\S]+/, - inside: { - punctuation: /:/, - }, - }, - }, - }, - number: /[+-]?\b\d+(?:\.\d*)?(?:e[+-]?\d+)?/i, - punctuation: /[{}.,;()[\]]|\^\^/, - boolean: /\b(?:false|true)\b/, - keyword: [ - /(?:\ba|@prefix|@base)\b|=/, - /\b(?:base|graph|prefix)\b/i, - ], - tag: { - pattern: /@[a-z]+(?:-[a-z\d]+)*/i, - inside: { - punctuation: /@/, - }, - }, - } - - languages.trig = languages.turtle -} - -function registerSparql(Prism: any): void { - const { languages } = Prism - - if (languages.sparql) { - return - } - - registerTurtle(Prism) - - languages.sparql = languages.extend('turtle', { - boolean: /\b(?:false|true)\b/i, - variable: { - pattern: /[?$]\w+/, - greedy: true, - }, - }) - - Prism.languages.insertBefore('sparql', 'punctuation', { - keyword: [ - /\b(?:A|ADD|ALL|AS|ASC|ASK|BNODE|BY|CLEAR|CONSTRUCT|COPY|CREATE|DATA|DEFAULT|DELETE|DESC|DESCRIBE|DISTINCT|DROP|EXISTS|FILTER|FROM|GROUP|HAVING|INSERT|INTO|LIMIT|LOAD|MINUS|MOVE|NAMED|NOT|NOW|OFFSET|OPTIONAL|ORDER|RAND|REDUCED|SELECT|SEPARATOR|SERVICE|SILENT|STRUUID|UNION|USING|UUID|VALUES|WHERE)\b/i, - /\b(?:ABS|AVG|BIND|BOUND|CEIL|COALESCE|CONCAT|CONTAINS|COUNT|DATATYPE|DAY|ENCODE_FOR_URI|FLOOR|GROUP_CONCAT|HOURS|IF|IRI|isBLANK|isIRI|isLITERAL|isNUMERIC|isURI|LANG|LANGMATCHES|LCASE|MAX|MD5|MIN|MINUTES|MONTH|REGEX|REPLACE|ROUND|sameTerm|SAMPLE|SECONDS|SHA1|SHA256|SHA384|SHA512|STR|STRAFTER|STRBEFORE|STRDT|STRENDS|STRLANG|STRLEN|STRSTARTS|SUBSTR|SUM|TIMEZONE|TZ|UCASE|URI|YEAR)\b(?=\s*\()/i, - /\b(?:BASE|GRAPH|PREFIX)\b/i, - ], - }) - - languages.rq = languages.sparql -} - -export function registerPrismLanguages(Prism: any): void { - registerTurtle(Prism) - registerSparql(Prism) -} From 15e1b4cba478229bc12061b137cd468e51b43853 Mon Sep 17 00:00:00 2001 From: Hans-christian Date: Thu, 18 Jun 2026 11:42:48 +0200 Subject: [PATCH 04/10] chore: limit dependabot version updates --- .github/dependabot.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index a1046b83..e0e5f819 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,8 +9,20 @@ updates: directory: "/" schedule: interval: "weekly" + open-pull-requests-limit: 0 + groups: + npm-security-updates: + applies-to: security-updates + patterns: + - "*" - package-ecosystem: "github-actions" directory: "/" schedule: interval: "weekly" + open-pull-requests-limit: 0 + groups: + github-actions-security-updates: + applies-to: security-updates + patterns: + - "*" From 5791cc4fa2923dc567f551f7830af5fa7f798eea Mon Sep 17 00:00:00 2001 From: Hans-christian Date: Thu, 18 Jun 2026 11:53:54 +0200 Subject: [PATCH 05/10] fix: load prism languages at runtime --- CHANGELOG.md | 4 +- package-lock.json | 162 ++++++++++++++++++++++++---------------------- package.json | 2 +- src/main.ts | 20 ++++-- 4 files changed, 105 insertions(+), 83 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 363be22a..35fcde50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,13 +15,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | Vue runtime | `vue` `3.5.34 -> 3.5.35`, `vue-router` `4.6.4 -> 5.0.6`, `@fortawesome/vue-fontawesome` `3.1.3 -> 3.2.0` | Framework and router patch updates, plus icon component compatibility. | | Icons | `@fortawesome/free-regular-svg-icons`, `@fortawesome/free-solid-svg-icons` | Updated icon set used by the UI. | | RDF and data handling | `rdflib` `2.3.8 -> 2.3.9`, `vis-data` `6.4.1 -> 8.0.4` | RDF parsing and graph/data handling updates. | -| Tooling | `vite` `8.0.16 -> 8.0.14`, `core-js` `3.47.0 -> 3.49.0`, `semver` `7.8.0 -> 7.8.1`, `tmp` `0.2.5 -> 0.2.7`, `form-data` `4.0.5 -> 4.0.6` | Build/runtime and indirect dependency stability and security updates. | +| Tooling | `vite` `8.0.14 -> 8.0.16`, `core-js` `3.47.0 -> 3.49.0`, `semver` `7.8.0 -> 7.8.1`, `tmp` `0.2.5 -> 0.2.7`, `form-data` `4.0.5 -> 4.0.6` | Build/runtime and indirect dependency stability and security updates. | ### Release process fixes since `v1.0.6` - `fix: make release tag selection stable` prevented the release workflow from picking the wrong tag. - `fix: skip existing release versions` prevented duplicate release creation for already published versions. -- The Prism white-screen/startup crash is avoided by rolling Vite back to `8.0.14`, which restores a workable production bundle. +- The Prism white-screen/startup crash is avoided by loading Prism language modules at runtime after `globalThis.Prism` is initialized, which keeps the patched Vite build workable. ## [v1.0.6] - 2026-05-05 diff --git a/package-lock.json b/package-lock.json index 083969af..8dd26245 100644 --- a/package-lock.json +++ b/package-lock.json @@ -57,7 +57,7 @@ "sass-loader": "^12.6.0", "typescript": "^4.6.2", "url": "^0.11.0", - "vite": "^8.0.14" + "vite": "^8.0.16" } }, "node_modules/@babel/code-frame": { @@ -670,9 +670,9 @@ } }, "node_modules/@oxc-project/types": { - "version": "0.132.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.132.0.tgz", - "integrity": "sha512-FESMOxil5Se014ui/Eq8fT5uHJo6nIRwH0PfJrZJXs6Gek3ZVFOrpUv3YIZT20m+extU98Hg1Ym72U58rlsxUQ==", + "version": "0.133.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.133.0.tgz", + "integrity": "sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==", "dev": true, "license": "MIT", "funding": { @@ -1024,9 +1024,9 @@ } }, "node_modules/@rolldown/binding-android-arm64": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.2.tgz", - "integrity": "sha512-ZS4D1JPGn/MYQN/SYDWftIE/nVsM8j/AFOYEzAoOE2O3NktQOZru+/vYXGbR/qtdLdIfGCP0lcoJiYVzsEz+iQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz", + "integrity": "sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==", "cpu": [ "arm64" ], @@ -1041,9 +1041,9 @@ } }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.2.tgz", - "integrity": "sha512-vdFA9+C/rekyGce7WqHs/xoT0ioZEWaOFyZLIV1mEeNFaFDUQrPIo8Vs2GvJ6eetb3rzDUtUBgzto3ExpXJB3w==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.3.tgz", + "integrity": "sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==", "cpu": [ "arm64" ], @@ -1058,9 +1058,9 @@ } }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.2.tgz", - "integrity": "sha512-BewSOwTHazv77DTYiAZXSqqKZ4KP/KonFisDMVU7PImxoWfB2aepnPhd2E4SWz3zDzYgDNbs6jBmTdgNnF02GA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.3.tgz", + "integrity": "sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==", "cpu": [ "x64" ], @@ -1075,9 +1075,9 @@ } }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.2.tgz", - "integrity": "sha512-m41o7M0YWtUdqk61Tb+jnKb2rN++iRdIASlExkUoKfIAH30DOHCB8fVLzSUpbWHHU8esmEioY62PxzexE8MBuA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.3.tgz", + "integrity": "sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==", "cpu": [ "x64" ], @@ -1092,9 +1092,9 @@ } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.2.tgz", - "integrity": "sha512-jcojB9H7W/jS29pMKWAK1N+fU99vXodHDTatS3b3y/XSOCiHo0kkA74pL3jJmkoQtYpOCxDvaKs1fo2Ij/1X5w==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.3.tgz", + "integrity": "sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==", "cpu": [ "arm" ], @@ -1109,9 +1109,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.2.tgz", - "integrity": "sha512-1jn6qDU5iiOgFgygDzKUuKP0maTi0/f1+sBLgvij/76C77Nm3ts6ufz9Bjg5q5dduxiUIxtq86JIoBvo1xQ4Ig==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.3.tgz", + "integrity": "sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==", "cpu": [ "arm64" ], @@ -1126,9 +1126,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.2.tgz", - "integrity": "sha512-QVLO/czFMdoMFSqlX3bcswcJNm/23r+qoa/jgtmFc/qEp6/jXmIkDjF/XIo8dPfGaiwy1xfQn8o77L79GeXFgw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.3.tgz", + "integrity": "sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==", "cpu": [ "arm64" ], @@ -1143,9 +1143,9 @@ } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.2.tgz", - "integrity": "sha512-hgO5Abm0w5UL6FEa2iFnZqo2KlK7TQ5QhV5x09hujBf7t5KzHQ1VmfPuTpqRy/rNlSxua3eWH374xxiVrP+lcA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.3.tgz", + "integrity": "sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==", "cpu": [ "ppc64" ], @@ -1160,9 +1160,9 @@ } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.2.tgz", - "integrity": "sha512-fy8rXxuYEu602abC8MUNaPjYLIFzReOaEIEMKMUa0rFEUxNpVXhs15KSSQ4qlqSaM7B6rcj9rDZgADh/IGDzLQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.3.tgz", + "integrity": "sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==", "cpu": [ "s390x" ], @@ -1177,9 +1177,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.2.tgz", - "integrity": "sha512-0+bOkiQ779+r1WpoHOWHqncvyySci0vKph+myNDYb+im6meJAzHQXay6oEgnkHuUGouM1LKTZwqKpBow6Kj7CQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.3.tgz", + "integrity": "sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==", "cpu": [ "x64" ], @@ -1194,9 +1194,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.2.tgz", - "integrity": "sha512-mjSkrzZK5Qsl0a9d1JgILOiuZOSDTVdKENcSXBoqbzSrspLR/4/IRVDo5wd2GgZjNss/viBFJdeq+j7qH2nypw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.3.tgz", + "integrity": "sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==", "cpu": [ "x64" ], @@ -1211,9 +1211,9 @@ } }, "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.2.tgz", - "integrity": "sha512-1v5vHasdfQAZoEHakBV72LIFAC9JjnymsiKxp+GEr/ma3+NJCPSaYK+qavInOovJkgwFrs7GccX2d6IgDA3Z5w==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.3.tgz", + "integrity": "sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==", "cpu": [ "arm64" ], @@ -1228,9 +1228,9 @@ } }, "node_modules/@rolldown/binding-wasm32-wasi": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.2.tgz", - "integrity": "sha512-mb1VobWn6NheziTk5/WEaR6AKVbrwT5sOi6C7zk3gy/pD1qtJfU1j4PgTo2NJnOtbL9Dl3Aeei8w9jJ7qC2jZQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.3.tgz", + "integrity": "sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==", "cpu": [ "wasm32" ], @@ -1247,9 +1247,9 @@ } }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.2.tgz", - "integrity": "sha512-SqKonF56vA/L2yHwHYcEp2P34URpOZ7d1fS635cTkpDnUtEGdUbhI6NzsPdqeSWvAAeGDrxjWjNmibDIdFf9/A==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.3.tgz", + "integrity": "sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==", "cpu": [ "arm64" ], @@ -1264,9 +1264,9 @@ } }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.2.tgz", - "integrity": "sha512-v7qRI7gXLRINcOGXt+7YmAZ6iFuyZVMIoXAxhd8oP+DR9dLfL9GfNIx7PLMxmhZdvq8waUJBQiWN9EKNy+TRBQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz", + "integrity": "sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==", "cpu": [ "x64" ], @@ -6079,10 +6079,20 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz", + "integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -7885,13 +7895,13 @@ } }, "node_modules/rolldown": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.2.tgz", - "integrity": "sha512-oZx5zVDtVB44AW3eaifgDml1gWRDZGvjcfdxonE4swNPG98PrrXjaO/KrnUjzlMnztCCRVlUueA1kCXhARGk6g==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.3.tgz", + "integrity": "sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==", "dev": true, "license": "MIT", "dependencies": { - "@oxc-project/types": "=0.132.0", + "@oxc-project/types": "=0.133.0", "@rolldown/pluginutils": "^1.0.0" }, "bin": { @@ -7901,21 +7911,21 @@ "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rolldown/binding-android-arm64": "1.0.2", - "@rolldown/binding-darwin-arm64": "1.0.2", - "@rolldown/binding-darwin-x64": "1.0.2", - "@rolldown/binding-freebsd-x64": "1.0.2", - "@rolldown/binding-linux-arm-gnueabihf": "1.0.2", - "@rolldown/binding-linux-arm64-gnu": "1.0.2", - "@rolldown/binding-linux-arm64-musl": "1.0.2", - "@rolldown/binding-linux-ppc64-gnu": "1.0.2", - "@rolldown/binding-linux-s390x-gnu": "1.0.2", - "@rolldown/binding-linux-x64-gnu": "1.0.2", - "@rolldown/binding-linux-x64-musl": "1.0.2", - "@rolldown/binding-openharmony-arm64": "1.0.2", - "@rolldown/binding-wasm32-wasi": "1.0.2", - "@rolldown/binding-win32-arm64-msvc": "1.0.2", - "@rolldown/binding-win32-x64-msvc": "1.0.2" + "@rolldown/binding-android-arm64": "1.0.3", + "@rolldown/binding-darwin-arm64": "1.0.3", + "@rolldown/binding-darwin-x64": "1.0.3", + "@rolldown/binding-freebsd-x64": "1.0.3", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.3", + "@rolldown/binding-linux-arm64-gnu": "1.0.3", + "@rolldown/binding-linux-arm64-musl": "1.0.3", + "@rolldown/binding-linux-ppc64-gnu": "1.0.3", + "@rolldown/binding-linux-s390x-gnu": "1.0.3", + "@rolldown/binding-linux-x64-gnu": "1.0.3", + "@rolldown/binding-linux-x64-musl": "1.0.3", + "@rolldown/binding-openharmony-arm64": "1.0.3", + "@rolldown/binding-wasm32-wasi": "1.0.3", + "@rolldown/binding-win32-arm64-msvc": "1.0.3", + "@rolldown/binding-win32-x64-msvc": "1.0.3" } }, "node_modules/run-parallel": { @@ -9228,17 +9238,17 @@ } }, "node_modules/vite": { - "version": "8.0.14", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.14.tgz", - "integrity": "sha512-s4BJJ+5y1pYL6Otw51FHhVJQhPnuRinKig64g/1+EUNaJsd3gCKdD31IPFvswUgW9/60QT9oFHbZHbQK5imcxw==", + "version": "8.0.16", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.16.tgz", + "integrity": "sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==", "dev": true, "license": "MIT", "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.15", - "rolldown": "1.0.2", - "tinyglobby": "^0.2.16" + "rolldown": "1.0.3", + "tinyglobby": "^0.2.17" }, "bin": { "vite": "bin/vite.js" diff --git a/package.json b/package.json index a90cced4..d614225e 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "sass-loader": "^12.6.0", "typescript": "^4.6.2", "url": "^0.11.0", - "vite": "^8.0.14" + "vite": "^8.0.16" }, "overrides": { "git-up": "^8.1.0", diff --git a/src/main.ts b/src/main.ts index e413bd19..3b8d337a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -8,9 +8,7 @@ import 'bootstrap-vue-next/dist/bootstrap-vue-next.css' import 'prismjs/themes/prism.css' import 'vue-prism-editor/dist/prismeditor.min.css' import 'vue-select/dist/vue-select.css' -import 'prismjs' -import 'prismjs/components/prism-turtle' -import 'prismjs/components/prism-sparql' +import Prism from 'prismjs' import { createEntityConfigs } from '@/entity/entityConfigs' import type { EntitySpec } from '@/entity/EntityConfig' import App from './App.vue' @@ -23,6 +21,18 @@ console.log('🚀 FDP Client Starting...') let entitySpecs: EntitySpec[] = [] +async function loadPrismLanguages(): Promise { + try { + (globalThis as any).Prism = Prism + await Promise.all([ + import('prismjs/components/prism-turtle'), + import('prismjs/components/prism-sparql'), + ]) + } catch (error) { + console.warn('Failed to load Prism languages dynamically.', error) + } +} + api.configs.getBootstrap() .then((response: any) => { console.log('Bootstrap config loaded successfully:', response.data) @@ -50,7 +60,9 @@ api.configs.getBootstrap() }) // Continue with empty specs to allow error message to be shown in UI }) - .finally(() => { + .finally(async () => { + await loadPrismLanguages() + const entityConfigs = createEntityConfigs(entitySpecs) const store = createStore(entityConfigs) const router = createRouter(store) From a7ebaaa468af9d3addb0b0c08c04b8bc167ae552 Mon Sep 17 00:00:00 2001 From: Hans-christian Date: Thu, 18 Jun 2026 12:08:57 +0200 Subject: [PATCH 06/10] fix prism startup crash --- CHANGELOG.md | 2 +- src/main.ts | 20 ++------- src/prism-languages.ts | 100 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 17 deletions(-) create mode 100644 src/prism-languages.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 35fcde50..6735bd95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,7 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `fix: make release tag selection stable` prevented the release workflow from picking the wrong tag. - `fix: skip existing release versions` prevented duplicate release creation for already published versions. -- The Prism white-screen/startup crash is avoided by loading Prism language modules at runtime after `globalThis.Prism` is initialized, which keeps the patched Vite build workable. +- The Prism white-screen/startup crash is avoided by registering the Turtle and SPARQL grammars locally in the app, which keeps the patched Vite build workable. ## [v1.0.6] - 2026-05-05 diff --git a/src/main.ts b/src/main.ts index 3b8d337a..324690d1 100644 --- a/src/main.ts +++ b/src/main.ts @@ -8,9 +8,9 @@ import 'bootstrap-vue-next/dist/bootstrap-vue-next.css' import 'prismjs/themes/prism.css' import 'vue-prism-editor/dist/prismeditor.min.css' import 'vue-select/dist/vue-select.css' -import Prism from 'prismjs' import { createEntityConfigs } from '@/entity/entityConfigs' import type { EntitySpec } from '@/entity/EntityConfig' +import { registerPrismLanguages } from '@/prism-languages' import App from './App.vue' import { createRouter } from './router' import { createStore } from './store' @@ -21,18 +21,6 @@ console.log('🚀 FDP Client Starting...') let entitySpecs: EntitySpec[] = [] -async function loadPrismLanguages(): Promise { - try { - (globalThis as any).Prism = Prism - await Promise.all([ - import('prismjs/components/prism-turtle'), - import('prismjs/components/prism-sparql'), - ]) - } catch (error) { - console.warn('Failed to load Prism languages dynamically.', error) - } -} - api.configs.getBootstrap() .then((response: any) => { console.log('Bootstrap config loaded successfully:', response.data) @@ -60,13 +48,13 @@ api.configs.getBootstrap() }) // Continue with empty specs to allow error message to be shown in UI }) - .finally(async () => { - await loadPrismLanguages() - + .finally(() => { const entityConfigs = createEntityConfigs(entitySpecs) const store = createStore(entityConfigs) const router = createRouter(store) + registerPrismLanguages() + const app = createApp(App) registerFontAwesome(app) diff --git a/src/prism-languages.ts b/src/prism-languages.ts new file mode 100644 index 00000000..79e23e4b --- /dev/null +++ b/src/prism-languages.ts @@ -0,0 +1,100 @@ +import PrismJs from 'prismjs' + +function registerTurtle(prism: any): void { + const { languages } = prism + + if (languages.turtle) { + return + } + + languages.turtle = { + comment: { + pattern: /#.*/, + greedy: true, + }, + 'multiline-string': { + pattern: /"""(?:(?:""?)?(?:[^"\\]|\\.))*"""|'''(?:(?:''?)?(?:[^'\\]|\\.))*'''/, + greedy: true, + alias: 'string', + inside: { + comment: /#.*/, + }, + }, + string: { + pattern: /"(?:[^\\"\r\n]|\\.)*"|'(?:[^\\'\r\n]|\\.)*'/, + greedy: true, + }, + url: { + // Prism's Turtle grammar needs the ASCII control-character range here. + // eslint-disable-next-line no-control-regex + pattern: /<(?:[^\x00-\x20<>"{}|^`\\]|\\(?:u[\da-fA-F]{4}|U[\da-fA-F]{8}))*>/, + greedy: true, + inside: { + punctuation: /[<>]/, + }, + }, + function: { + pattern: /(?:(?![-.\d\xB7])[-.\w\xB7\xC0-\uFFFD]+)?:(?:(?![-.])(?:[-.:\w\xC0-\uFFFD]|%[\da-f]{2}|\\.)+)?/i, + inside: { + 'local-name': { + pattern: /([^:]*:)[\s\S]+/, + lookbehind: true, + }, + prefix: { + pattern: /[\s\S]+/, + inside: { + punctuation: /:/, + }, + }, + }, + }, + number: /[+-]?\b\d+(?:\.\d*)?(?:e[+-]?\d+)?/i, + punctuation: /[{}.,;()[\]]|\^\^/, + boolean: /\b(?:false|true)\b/, + keyword: [ + /(?:\ba|@prefix|@base)\b|=/, + /\b(?:base|graph|prefix)\b/i, + ], + tag: { + pattern: /@[a-z]+(?:-[a-z\d]+)*/i, + inside: { + punctuation: /@/, + }, + }, + } + + languages.trig = languages.turtle +} + +function registerSparql(prism: any): void { + const { languages } = prism + + if (languages.sparql) { + return + } + + registerTurtle(prism) + + languages.sparql = languages.extend('turtle', { + boolean: /\b(?:false|true)\b/i, + variable: { + pattern: /[?$]\w+/, + greedy: true, + }, + }) + + languages.insertBefore('sparql', 'punctuation', { + keyword: [ + /\b(?:A|ADD|ALL|AS|ASC|ASK|BNODE|BY|CLEAR|CONSTRUCT|COPY|CREATE|DATA|DEFAULT|DELETE|DESC|DESCRIBE|DISTINCT|DROP|EXISTS|FILTER|FROM|GROUP|HAVING|INSERT|INTO|LIMIT|LOAD|MINUS|MOVE|NAMED|NOT|NOW|OFFSET|OPTIONAL|ORDER|RAND|REDUCED|SELECT|SEPARATOR|SERVICE|SILENT|STRUUID|UNION|USING|UUID|VALUES|WHERE)\b/i, + /\b(?:ABS|AVG|BIND|BOUND|CEIL|COALESCE|CONCAT|CONTAINS|COUNT|DATATYPE|DAY|ENCODE_FOR_URI|FLOOR|GROUP_CONCAT|HOURS|IF|IRI|isBLANK|isIRI|isLITERAL|isNUMERIC|isURI|LANG|LANGMATCHES|LCASE|MAX|MD5|MIN|MINUTES|MONTH|REGEX|REPLACE|ROUND|sameTerm|SAMPLE|SECONDS|SHA1|SHA256|SHA384|SHA512|STR|STRAFTER|STRBEFORE|STRDT|STRENDS|STRLANG|STRLEN|STRSTARTS|SUBSTR|SUM|TIMEZONE|TZ|UCASE|URI|YEAR)\b(?=\s*\()/i, + /\b(?:BASE|GRAPH|PREFIX)\b/i, + ], + }) + + languages.rq = languages.sparql +} + +export function registerPrismLanguages(): void { + registerTurtle(PrismJs) + registerSparql(PrismJs) +} From f2092dbe2d89571a824bc2e4f271e42491bf8e94 Mon Sep 17 00:00:00 2001 From: Hans-christian Date: Thu, 18 Jun 2026 12:38:01 +0200 Subject: [PATCH 07/10] fix Prisma reference error --- src/prism-languages.ts | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/prism-languages.ts b/src/prism-languages.ts index 79e23e4b..5325d4ce 100644 --- a/src/prism-languages.ts +++ b/src/prism-languages.ts @@ -1,13 +1,14 @@ import PrismJs from 'prismjs' -function registerTurtle(prism: any): void { - const { languages } = prism +// PrismJS component files (prism-turtle.js, prism-sparql.js) reference a bare +// global `Prism` variable. When bundled by Vite they would produce a +// ReferenceError because no such global exists in module scope. We therefore +// register the languages programmatically via the imported Prism instance. - if (languages.turtle) { - return - } +function registerTurtle(prism: typeof PrismJs): void { + if (prism.languages['turtle']) return - languages.turtle = { + prism.languages['turtle'] = { comment: { pattern: /#.*/, greedy: true, @@ -25,7 +26,7 @@ function registerTurtle(prism: any): void { greedy: true, }, url: { - // Prism's Turtle grammar needs the ASCII control-character range here. + // ASCII control-character range required by the Turtle spec. // eslint-disable-next-line no-control-regex pattern: /<(?:[^\x00-\x20<>"{}|^`\\]|\\(?:u[\da-fA-F]{4}|U[\da-fA-F]{8}))*>/, greedy: true, @@ -63,19 +64,15 @@ function registerTurtle(prism: any): void { }, } - languages.trig = languages.turtle + prism.languages['trig'] = prism.languages['turtle'] } -function registerSparql(prism: any): void { - const { languages } = prism - - if (languages.sparql) { - return - } +function registerSparql(prism: typeof PrismJs): void { + if (prism.languages['sparql']) return registerTurtle(prism) - languages.sparql = languages.extend('turtle', { + prism.languages['sparql'] = prism.languages.extend('turtle', { boolean: /\b(?:false|true)\b/i, variable: { pattern: /[?$]\w+/, @@ -83,7 +80,7 @@ function registerSparql(prism: any): void { }, }) - languages.insertBefore('sparql', 'punctuation', { + prism.languages.insertBefore('sparql', 'punctuation', { keyword: [ /\b(?:A|ADD|ALL|AS|ASC|ASK|BNODE|BY|CLEAR|CONSTRUCT|COPY|CREATE|DATA|DEFAULT|DELETE|DESC|DESCRIBE|DISTINCT|DROP|EXISTS|FILTER|FROM|GROUP|HAVING|INSERT|INTO|LIMIT|LOAD|MINUS|MOVE|NAMED|NOT|NOW|OFFSET|OPTIONAL|ORDER|RAND|REDUCED|SELECT|SEPARATOR|SERVICE|SILENT|STRUUID|UNION|USING|UUID|VALUES|WHERE)\b/i, /\b(?:ABS|AVG|BIND|BOUND|CEIL|COALESCE|CONCAT|CONTAINS|COUNT|DATATYPE|DAY|ENCODE_FOR_URI|FLOOR|GROUP_CONCAT|HOURS|IF|IRI|isBLANK|isIRI|isLITERAL|isNUMERIC|isURI|LANG|LANGMATCHES|LCASE|MAX|MD5|MIN|MINUTES|MONTH|REGEX|REPLACE|ROUND|sameTerm|SAMPLE|SECONDS|SHA1|SHA256|SHA384|SHA512|STR|STRAFTER|STRBEFORE|STRDT|STRENDS|STRLANG|STRLEN|STRSTARTS|SUBSTR|SUM|TIMEZONE|TZ|UCASE|URI|YEAR)\b(?=\s*\()/i, @@ -91,7 +88,7 @@ function registerSparql(prism: any): void { ], }) - languages.rq = languages.sparql + prism.languages['rq'] = prism.languages['sparql'] } export function registerPrismLanguages(): void { From 1b42344107d098055b5624dfecbba0f76fc633b1 Mon Sep 17 00:00:00 2001 From: Hans-christian Date: Fri, 19 Jun 2026 10:04:24 +0200 Subject: [PATCH 08/10] reuse prism package languages --- src/prism-languages.ts | 96 ++---------------------------------------- vite.config.ts | 26 +++++++++++- 2 files changed, 29 insertions(+), 93 deletions(-) diff --git a/src/prism-languages.ts b/src/prism-languages.ts index 5325d4ce..993a541d 100644 --- a/src/prism-languages.ts +++ b/src/prism-languages.ts @@ -1,97 +1,9 @@ import PrismJs from 'prismjs' +import 'prismjs/components/prism-turtle' +import 'prismjs/components/prism-sparql' -// PrismJS component files (prism-turtle.js, prism-sparql.js) reference a bare -// global `Prism` variable. When bundled by Vite they would produce a -// ReferenceError because no such global exists in module scope. We therefore -// register the languages programmatically via the imported Prism instance. - -function registerTurtle(prism: typeof PrismJs): void { - if (prism.languages['turtle']) return - - prism.languages['turtle'] = { - comment: { - pattern: /#.*/, - greedy: true, - }, - 'multiline-string': { - pattern: /"""(?:(?:""?)?(?:[^"\\]|\\.))*"""|'''(?:(?:''?)?(?:[^'\\]|\\.))*'''/, - greedy: true, - alias: 'string', - inside: { - comment: /#.*/, - }, - }, - string: { - pattern: /"(?:[^\\"\r\n]|\\.)*"|'(?:[^\\'\r\n]|\\.)*'/, - greedy: true, - }, - url: { - // ASCII control-character range required by the Turtle spec. - // eslint-disable-next-line no-control-regex - pattern: /<(?:[^\x00-\x20<>"{}|^`\\]|\\(?:u[\da-fA-F]{4}|U[\da-fA-F]{8}))*>/, - greedy: true, - inside: { - punctuation: /[<>]/, - }, - }, - function: { - pattern: /(?:(?![-.\d\xB7])[-.\w\xB7\xC0-\uFFFD]+)?:(?:(?![-.])(?:[-.:\w\xC0-\uFFFD]|%[\da-f]{2}|\\.)+)?/i, - inside: { - 'local-name': { - pattern: /([^:]*:)[\s\S]+/, - lookbehind: true, - }, - prefix: { - pattern: /[\s\S]+/, - inside: { - punctuation: /:/, - }, - }, - }, - }, - number: /[+-]?\b\d+(?:\.\d*)?(?:e[+-]?\d+)?/i, - punctuation: /[{}.,;()[\]]|\^\^/, - boolean: /\b(?:false|true)\b/, - keyword: [ - /(?:\ba|@prefix|@base)\b|=/, - /\b(?:base|graph|prefix)\b/i, - ], - tag: { - pattern: /@[a-z]+(?:-[a-z\d]+)*/i, - inside: { - punctuation: /@/, - }, - }, - } - - prism.languages['trig'] = prism.languages['turtle'] -} - -function registerSparql(prism: typeof PrismJs): void { - if (prism.languages['sparql']) return - - registerTurtle(prism) - - prism.languages['sparql'] = prism.languages.extend('turtle', { - boolean: /\b(?:false|true)\b/i, - variable: { - pattern: /[?$]\w+/, - greedy: true, - }, - }) - - prism.languages.insertBefore('sparql', 'punctuation', { - keyword: [ - /\b(?:A|ADD|ALL|AS|ASC|ASK|BNODE|BY|CLEAR|CONSTRUCT|COPY|CREATE|DATA|DEFAULT|DELETE|DESC|DESCRIBE|DISTINCT|DROP|EXISTS|FILTER|FROM|GROUP|HAVING|INSERT|INTO|LIMIT|LOAD|MINUS|MOVE|NAMED|NOT|NOW|OFFSET|OPTIONAL|ORDER|RAND|REDUCED|SELECT|SEPARATOR|SERVICE|SILENT|STRUUID|UNION|USING|UUID|VALUES|WHERE)\b/i, - /\b(?:ABS|AVG|BIND|BOUND|CEIL|COALESCE|CONCAT|CONTAINS|COUNT|DATATYPE|DAY|ENCODE_FOR_URI|FLOOR|GROUP_CONCAT|HOURS|IF|IRI|isBLANK|isIRI|isLITERAL|isNUMERIC|isURI|LANG|LANGMATCHES|LCASE|MAX|MD5|MIN|MINUTES|MONTH|REGEX|REPLACE|ROUND|sameTerm|SAMPLE|SECONDS|SHA1|SHA256|SHA384|SHA512|STR|STRAFTER|STRBEFORE|STRDT|STRENDS|STRLANG|STRLEN|STRSTARTS|SUBSTR|SUM|TIMEZONE|TZ|UCASE|URI|YEAR)\b(?=\s*\()/i, - /\b(?:BASE|GRAPH|PREFIX)\b/i, - ], - }) - - prism.languages['rq'] = prism.languages['sparql'] -} +const prismGlobal = globalThis as typeof globalThis & { Prism?: typeof PrismJs } export function registerPrismLanguages(): void { - registerTurtle(PrismJs) - registerSparql(PrismJs) + prismGlobal.Prism = PrismJs } diff --git a/vite.config.ts b/vite.config.ts index f6670aaf..13f26760 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -2,9 +2,33 @@ import path from 'path' import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' +const prismGlobalComponents = new Set([ + 'prism-turtle.js', + 'prism-sparql.js', +]) + +function prismComponentGlobalPlugin() { + return { + name: 'prism-component-global', + transform(code: string, id: string) { + const normalizedId = id.replaceAll('\\', '/') + + if (!normalizedId.includes('/node_modules/prismjs/components/')) { + return undefined + } + + if (!prismGlobalComponents.has(path.basename(normalizedId))) { + return undefined + } + + return `import Prism from 'prismjs'\n${code}` + }, + } +} + export default defineConfig(({ mode }) => ({ base: mode === 'production' ? '/app/' : '/', - plugins: [vue()], + plugins: [prismComponentGlobalPlugin(), vue()], define: { global: 'globalThis', 'process.env': {}, From bd12002b260937fa84e2c1ddfe8b32dd46713507 Mon Sep 17 00:00:00 2001 From: Hans-christian Date: Mon, 22 Jun 2026 12:53:21 +0200 Subject: [PATCH 09/10] Remove unrelated footer changes --- src/components/FdpFooter/index.vue | 11 ++--------- src/components/VersionInfoTable/index.vue | 11 ++++------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/src/components/FdpFooter/index.vue b/src/components/FdpFooter/index.vue index 03811f89..3879e324 100644 --- a/src/components/FdpFooter/index.vue +++ b/src/components/FdpFooter/index.vue @@ -56,15 +56,8 @@ export default defineComponent({ }, methods: { async fetchData(): Promise { - try { - const response = await api.info.getInfo() - this.info = { - version: response.data?.version || '', - builtAt: response.data?.builtAt || '', - } - } catch (error) { - console.error('Unable to load About dialog info:', error) - } + const response = await api.info.getInfo() + this.info = response.data }, }, }) diff --git a/src/components/VersionInfoTable/index.vue b/src/components/VersionInfoTable/index.vue index 017e8a86..e2105ed2 100644 --- a/src/components/VersionInfoTable/index.vue +++ b/src/components/VersionInfoTable/index.vue @@ -11,7 +11,7 @@ Version - {{ safeVersion.slice(0, 36) }} + {{ version.slice(0, 36) }} Built at @@ -28,15 +28,12 @@ import moment from 'moment' export default defineComponent({ props: { title: { type: String, required: true }, - version: { type: String, default: '' }, - builtAt: { type: String, default: '' }, + version: { type: String, required: true }, + builtAt: { type: String, required: true }, }, computed: { - safeVersion(): string { - return this.version || '' - }, builtAtFormatted() { - return this.builtAt ? moment(this.builtAt).format('D. M. YYYY, HH:mm') : 'Unknown' + return moment(this.builtAt).format('D. M. YYYY, HH:mm') }, }, }) From 8dd4cd5d76203e3f42c1214fdbcd59dc25bec6e6 Mon Sep 17 00:00:00 2001 From: Hans-christian Date: Mon, 22 Jun 2026 12:57:35 +0200 Subject: [PATCH 10/10] Document Prism component bundler workaround --- src/main.ts | 4 +--- src/prism-languages.ts | 7 ------- vite.config.ts | 9 ++++++--- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/main.ts b/src/main.ts index 324690d1..969a625b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -6,11 +6,11 @@ import vSelect from 'vue-select' import 'bootstrap/dist/css/bootstrap.css' import 'bootstrap-vue-next/dist/bootstrap-vue-next.css' import 'prismjs/themes/prism.css' +import '@/prism-languages' import 'vue-prism-editor/dist/prismeditor.min.css' import 'vue-select/dist/vue-select.css' import { createEntityConfigs } from '@/entity/entityConfigs' import type { EntitySpec } from '@/entity/EntityConfig' -import { registerPrismLanguages } from '@/prism-languages' import App from './App.vue' import { createRouter } from './router' import { createStore } from './store' @@ -53,8 +53,6 @@ api.configs.getBootstrap() const store = createStore(entityConfigs) const router = createRouter(store) - registerPrismLanguages() - const app = createApp(App) registerFontAwesome(app) diff --git a/src/prism-languages.ts b/src/prism-languages.ts index 993a541d..2af84fb2 100644 --- a/src/prism-languages.ts +++ b/src/prism-languages.ts @@ -1,9 +1,2 @@ -import PrismJs from 'prismjs' import 'prismjs/components/prism-turtle' import 'prismjs/components/prism-sparql' - -const prismGlobal = globalThis as typeof globalThis & { Prism?: typeof PrismJs } - -export function registerPrismLanguages(): void { - prismGlobal.Prism = PrismJs -} diff --git a/vite.config.ts b/vite.config.ts index 13f26760..9506f255 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -7,9 +7,9 @@ const prismGlobalComponents = new Set([ 'prism-sparql.js', ]) -function prismComponentGlobalPlugin() { +function prismComponentImportPlugin() { return { - name: 'prism-component-global', + name: 'prism-component-import', transform(code: string, id: string) { const normalizedId = id.replaceAll('\\', '/') @@ -21,6 +21,9 @@ function prismComponentGlobalPlugin() { return undefined } + // Prism language components expect a free global `Prism` script variable. + // Make it explicit for Vite/Rolldown module builds. Upstream issue: + // https://github.com/PrismJS/prism/issues/4088 return `import Prism from 'prismjs'\n${code}` }, } @@ -28,7 +31,7 @@ function prismComponentGlobalPlugin() { export default defineConfig(({ mode }) => ({ base: mode === 'production' ? '/app/' : '/', - plugins: [prismComponentGlobalPlugin(), vue()], + plugins: [prismComponentImportPlugin(), vue()], define: { global: 'globalThis', 'process.env': {},