@tak-ps/vue-tabler 4.21.0 → 4.24.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/.github/workflows/release.yml +9 -1
- package/CHANGELOG.md +13 -1
- package/README.md +1 -0
- package/components/InlineAlert.vue +28 -25
- package/components/Markdown.vue +14 -1
- package/package.json +2 -1
- package/test/Markdown.spec.ts +30 -0
|
@@ -7,7 +7,7 @@ on:
|
|
|
7
7
|
|
|
8
8
|
permissions:
|
|
9
9
|
id-token: write # Required for OIDC
|
|
10
|
-
contents:
|
|
10
|
+
contents: write
|
|
11
11
|
|
|
12
12
|
jobs:
|
|
13
13
|
build:
|
|
@@ -31,3 +31,11 @@ jobs:
|
|
|
31
31
|
|
|
32
32
|
- name: Publish package
|
|
33
33
|
run: npm publish --provenance --access public
|
|
34
|
+
|
|
35
|
+
- name: Generate CHANGELOG
|
|
36
|
+
run: grep -Pzo "### ${{ github.ref_name }}(?s).*?(?=###)" CHANGELOG.md > RELEASE
|
|
37
|
+
|
|
38
|
+
- name: Github Release
|
|
39
|
+
uses: softprops/action-gh-release@v2
|
|
40
|
+
with:
|
|
41
|
+
body_path: RELEASE
|
package/CHANGELOG.md
CHANGED
|
@@ -10,7 +10,19 @@
|
|
|
10
10
|
|
|
11
11
|
## Version History
|
|
12
12
|
|
|
13
|
-
### v4.
|
|
13
|
+
### v4.24.0
|
|
14
|
+
|
|
15
|
+
- :tada: Add `icon` slot to `TablerInlineAlert`
|
|
16
|
+
|
|
17
|
+
### v4.23.1
|
|
18
|
+
|
|
19
|
+
- :bug: Add sanitize helper fn
|
|
20
|
+
|
|
21
|
+
### v4.23.0
|
|
22
|
+
|
|
23
|
+
- :pencil2: Add GH Release system
|
|
24
|
+
|
|
25
|
+
### v4.22.0
|
|
14
26
|
|
|
15
27
|
- :rocket: Migrate to more modern `marked` instead of `showdown`
|
|
16
28
|
|
package/README.md
CHANGED
|
@@ -97,6 +97,7 @@ This library relies on the following core dependencies:
|
|
|
97
97
|
- [Vue 3](https://vuejs.org/)
|
|
98
98
|
- [@tabler/icons-vue](https://www.npmjs.com/package/@tabler/icons-vue)
|
|
99
99
|
- [marked](https://www.npmjs.com/package/marked) (for Markdown rendering)
|
|
100
|
+
- [DOMPurify](https://www.npmjs.com/package/dompurify) (for HTML sanitization)
|
|
100
101
|
|
|
101
102
|
## 📄 License
|
|
102
103
|
|
|
@@ -6,31 +6,33 @@
|
|
|
6
6
|
role='alert'
|
|
7
7
|
>
|
|
8
8
|
<div class='alert-icon'>
|
|
9
|
-
<
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
9
|
+
<slot name='icon'>
|
|
10
|
+
<IconInfoCircle
|
|
11
|
+
v-if='props.severity === "info"'
|
|
12
|
+
:size='24'
|
|
13
|
+
stroke='1'
|
|
14
|
+
/>
|
|
15
|
+
<IconExclamationCircle
|
|
16
|
+
v-else-if='props.severity === "danger"'
|
|
17
|
+
:size='24'
|
|
18
|
+
stroke='1'
|
|
19
|
+
/>
|
|
20
|
+
<IconAlertTriangle
|
|
21
|
+
v-else-if='props.severity === "warning"'
|
|
22
|
+
:size='24'
|
|
23
|
+
stroke='1'
|
|
24
|
+
/>
|
|
25
|
+
<IconCheck
|
|
26
|
+
v-else-if='props.severity === "success"'
|
|
27
|
+
:size='24'
|
|
28
|
+
stroke='1'
|
|
29
|
+
/>
|
|
30
|
+
<IconQuestionMark
|
|
31
|
+
v-else
|
|
32
|
+
:size='24'
|
|
33
|
+
stroke='1'
|
|
34
|
+
/>
|
|
35
|
+
</slot>
|
|
34
36
|
</div>
|
|
35
37
|
|
|
36
38
|
<div>
|
|
@@ -72,6 +74,7 @@ export interface InlineAlertProps {
|
|
|
72
74
|
|
|
73
75
|
const props = withDefaults(defineProps<InlineAlertProps>(), {
|
|
74
76
|
severity: 'info',
|
|
77
|
+
description: undefined,
|
|
75
78
|
dismissable: false,
|
|
76
79
|
});
|
|
77
80
|
</script>
|
package/components/Markdown.vue
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
<template>
|
|
2
|
+
<!-- eslint-disable vue/no-v-html -->
|
|
2
3
|
<div
|
|
3
4
|
:style='autowrap ? `white-space: pre-wrap;` : ``'
|
|
4
5
|
v-html='html'
|
|
5
6
|
/>
|
|
7
|
+
<!-- eslint-enable vue/no-v-html -->
|
|
6
8
|
</template>
|
|
7
9
|
|
|
8
10
|
<script setup lang="ts">
|
|
9
11
|
import { computed } from 'vue'
|
|
12
|
+
import DOMPurify from 'dompurify'
|
|
10
13
|
import { marked } from 'marked'
|
|
11
14
|
|
|
12
15
|
export interface MarkdownProps {
|
|
@@ -18,10 +21,20 @@ const props = withDefaults(defineProps<MarkdownProps>(), {
|
|
|
18
21
|
autowrap: true
|
|
19
22
|
});
|
|
20
23
|
|
|
24
|
+
function sanitizeHtml(html: string): string {
|
|
25
|
+
return DOMPurify.sanitize(html, {
|
|
26
|
+
USE_PROFILES: {
|
|
27
|
+
html: true
|
|
28
|
+
}
|
|
29
|
+
})
|
|
30
|
+
}
|
|
31
|
+
|
|
21
32
|
const html = computed(() => {
|
|
22
|
-
|
|
33
|
+
const rendered = marked.parse(props.markdown, {
|
|
23
34
|
async: false,
|
|
24
35
|
gfm: true
|
|
25
36
|
})
|
|
37
|
+
|
|
38
|
+
return sanitizeHtml(rendered)
|
|
26
39
|
})
|
|
27
40
|
</script>
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tak-ps/vue-tabler",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "4.
|
|
4
|
+
"version": "4.24.0",
|
|
5
5
|
"lib": "lib.ts",
|
|
6
6
|
"main": "lib.ts",
|
|
7
7
|
"module": "lib.ts",
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
"homepage": "https://github.com/tak-ps/vue-tabler#readme",
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@tabler/icons-vue": "^3.0.0",
|
|
30
|
+
"dompurify": "^3.4.1",
|
|
30
31
|
"marked": "^18.0.2"
|
|
31
32
|
},
|
|
32
33
|
"peerDependencies": {
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { mount } from '@vue/test-utils'
|
|
3
|
+
import Markdown from '../components/Markdown.vue'
|
|
4
|
+
|
|
5
|
+
describe('TablerMarkdown', () => {
|
|
6
|
+
it('renders markdown and basic HTML', () => {
|
|
7
|
+
const wrapper = mount(Markdown, {
|
|
8
|
+
props: {
|
|
9
|
+
markdown: '# Title\n\n<div class="note">Allowed HTML</div>'
|
|
10
|
+
}
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
expect(wrapper.html()).toContain('<h1>Title</h1>')
|
|
14
|
+
expect(wrapper.html()).toContain('<div class="note">Allowed HTML</div>')
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
it('sanitizes unsafe HTML before rendering', () => {
|
|
18
|
+
const wrapper = mount(Markdown, {
|
|
19
|
+
props: {
|
|
20
|
+
markdown: '<img src="x" onerror="alert(1)"><script>alert(2)</script><a href="javascript:alert(3)">bad</a>'
|
|
21
|
+
}
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
expect(wrapper.html()).toContain('<img src="x">')
|
|
25
|
+
expect(wrapper.html()).toContain('<a>bad</a>')
|
|
26
|
+
expect(wrapper.html()).not.toContain('onerror')
|
|
27
|
+
expect(wrapper.html()).not.toContain('<script>')
|
|
28
|
+
expect(wrapper.html()).not.toContain('javascript:')
|
|
29
|
+
})
|
|
30
|
+
})
|