@adminforth/markdown 1.0.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/.woodpecker/buildRelease.sh +13 -0
- package/.woodpecker/buildSlackNotify.sh +44 -0
- package/.woodpecker/release.yml +44 -0
- package/build.log +14 -0
- package/custom/MarkdownEditor.vue +137 -0
- package/custom/MarkdownRenderer.vue +110 -0
- package/custom/package-lock.json +4100 -0
- package/custom/package.json +22 -0
- package/custom/tsconfig.json +20 -0
- package/dist/custom/MarkdownEditor.vue +137 -0
- package/dist/custom/MarkdownRenderer.vue +110 -0
- package/dist/custom/package-lock.json +4100 -0
- package/dist/custom/package.json +22 -0
- package/dist/custom/tsconfig.json +20 -0
- package/dist/index.js +77 -0
- package/dist/types.js +1 -0
- package/index.ts +79 -0
- package/package.json +58 -0
- package/tsconfig.json +112 -0
- package/types.ts +4 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
|
|
2
|
+
#!/bin/bash
|
|
3
|
+
|
|
4
|
+
# write npm run output both to console and to build.log
|
|
5
|
+
npm run build 2>&1 | tee build.log
|
|
6
|
+
build_status=${PIPESTATUS[0]}
|
|
7
|
+
|
|
8
|
+
# if exist status from the npm run build is not 0
|
|
9
|
+
# then exit with the status code from the npm run build
|
|
10
|
+
if [ $build_status -ne 0 ]; then
|
|
11
|
+
echo "Build failed. Exiting with status code $build_status"
|
|
12
|
+
exit $build_status
|
|
13
|
+
fi
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
|
|
3
|
+
set -x
|
|
4
|
+
|
|
5
|
+
COMMIT_SHORT_SHA=$(echo $CI_COMMIT_SHA | cut -c1-8)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
if [ "$CI_STEP_STATUS" = "success" ]; then
|
|
9
|
+
MESSAGE="Did a build without issues on \`$CI_REPO_NAME/$CI_COMMIT_BRANCH\`. Commit: _${CI_COMMIT_MESSAGE}_ (<$CI_COMMIT_URL|$COMMIT_SHORT_SHA>)"
|
|
10
|
+
|
|
11
|
+
curl -s -X POST -H "Content-Type: application/json" -d '{
|
|
12
|
+
"username": "'"$CI_COMMIT_AUTHOR"'",
|
|
13
|
+
"icon_url": "'"$CI_COMMIT_AUTHOR_AVATAR"'",
|
|
14
|
+
"attachments": [
|
|
15
|
+
{
|
|
16
|
+
"mrkdwn_in": ["text", "pretext"],
|
|
17
|
+
"color": "#36a64f",
|
|
18
|
+
"text": "'"$MESSAGE"'"
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
}' "$DEVELOPERS_SLACK_WEBHOOK"
|
|
22
|
+
exit 0
|
|
23
|
+
fi
|
|
24
|
+
export BUILD_LOG=$(cat ./build.log)
|
|
25
|
+
|
|
26
|
+
BUILD_LOG=$(echo $BUILD_LOG | sed 's/"/\\"/g')
|
|
27
|
+
|
|
28
|
+
MESSAGE="Broke \`$CI_REPO_NAME/$CI_COMMIT_BRANCH\` with commit _${CI_COMMIT_MESSAGE}_ (<$CI_COMMIT_URL|$COMMIT_SHORT_SHA>)"
|
|
29
|
+
CODE_BLOCK="\`\`\`$BUILD_LOG\n\`\`\`"
|
|
30
|
+
|
|
31
|
+
echo "Sending slack message to developers $MESSAGE"
|
|
32
|
+
# Send the message
|
|
33
|
+
curl -sS -X POST -H "Content-Type: application/json" -d '{
|
|
34
|
+
"username": "'"$CI_COMMIT_AUTHOR"'",
|
|
35
|
+
"icon_url": "'"$CI_COMMIT_AUTHOR_AVATAR"'",
|
|
36
|
+
"attachments": [
|
|
37
|
+
{
|
|
38
|
+
"mrkdwn_in": ["text", "pretext"],
|
|
39
|
+
"color": "#8A1C12",
|
|
40
|
+
"text": "'"$CODE_BLOCK"'",
|
|
41
|
+
"pretext": "'"$MESSAGE"'"
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
}' "$DEVELOPERS_SLACK_WEBHOOK" 2>&1
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
clone:
|
|
2
|
+
git:
|
|
3
|
+
image: woodpeckerci/plugin-git
|
|
4
|
+
settings:
|
|
5
|
+
partial: false
|
|
6
|
+
depth: 5
|
|
7
|
+
|
|
8
|
+
steps:
|
|
9
|
+
init-secrets:
|
|
10
|
+
when:
|
|
11
|
+
- event: push
|
|
12
|
+
image: infisical/cli
|
|
13
|
+
environment:
|
|
14
|
+
INFISICAL_TOKEN:
|
|
15
|
+
from_secret: VAULT_TOKEN
|
|
16
|
+
commands:
|
|
17
|
+
- infisical export --domain https://vault.devforth.io/api --format=dotenv-export --env="prod" > /woodpecker/deploy.vault.env
|
|
18
|
+
secrets:
|
|
19
|
+
- VAULT_TOKEN
|
|
20
|
+
|
|
21
|
+
release:
|
|
22
|
+
image: node:20
|
|
23
|
+
when:
|
|
24
|
+
- event: push
|
|
25
|
+
volumes:
|
|
26
|
+
- /var/run/docker.sock:/var/run/docker.sock
|
|
27
|
+
commands:
|
|
28
|
+
- apt update && apt install -y rsync
|
|
29
|
+
- export $(cat /woodpecker/deploy.vault.env | xargs)
|
|
30
|
+
- npm clean-install
|
|
31
|
+
- /bin/bash ./.woodpecker/buildRelease.sh
|
|
32
|
+
- npm audit signatures
|
|
33
|
+
- npx semantic-release
|
|
34
|
+
|
|
35
|
+
slack-on-failure:
|
|
36
|
+
when:
|
|
37
|
+
- event: push
|
|
38
|
+
status: [failure, success]
|
|
39
|
+
- event: push
|
|
40
|
+
image: curlimages/curl
|
|
41
|
+
commands:
|
|
42
|
+
- export $(cat /woodpecker/deploy.vault.env | xargs)
|
|
43
|
+
- /bin/sh ./.woodpecker/buildSlackNotify.sh
|
|
44
|
+
|
package/build.log
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
|
|
2
|
+
> @adminforth/markdown@1.0.0 build
|
|
3
|
+
> tsc && rsync -av --exclude 'node_modules' custom dist/
|
|
4
|
+
|
|
5
|
+
sending incremental file list
|
|
6
|
+
custom/
|
|
7
|
+
custom/MarkdownEditor.vue
|
|
8
|
+
custom/MarkdownRenderer.vue
|
|
9
|
+
custom/package-lock.json
|
|
10
|
+
custom/package.json
|
|
11
|
+
custom/tsconfig.json
|
|
12
|
+
|
|
13
|
+
sent 169,522 bytes received 115 bytes 339,274.00 bytes/sec
|
|
14
|
+
total size is 169,062 speedup is 1.00
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="mb-2"></div>
|
|
3
|
+
<div ref="editorContainer" id="editor" :class="[
|
|
4
|
+
'text-sm rounded-lg block w-full transition-all box-border',
|
|
5
|
+
isFocused
|
|
6
|
+
? 'ring-1 ring-lightPrimary border ring-lightPrimary border-lightPrimary dark:ring-darkPrimary dark:border-darkPrimary bg-white dark:bg-gray-700 text-gray-900 dark:text-white'
|
|
7
|
+
: 'bg-gray-50 border border-gray-300 text-gray-900 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white',
|
|
8
|
+
]"></div>
|
|
9
|
+
</template>
|
|
10
|
+
|
|
11
|
+
<script setup lang="ts">
|
|
12
|
+
import { ref, watch, onMounted, onBeforeUnmount } from 'vue';
|
|
13
|
+
|
|
14
|
+
import { Editor, rootCtx, defaultValueCtx } from '@milkdown/core';
|
|
15
|
+
import { gfm } from '@milkdown/kit/preset/gfm';
|
|
16
|
+
import { commonmark } from '@milkdown/preset-commonmark';
|
|
17
|
+
import { listener, listenerCtx } from '@milkdown/plugin-listener';
|
|
18
|
+
import { Crepe } from '@milkdown/crepe';
|
|
19
|
+
|
|
20
|
+
import '@milkdown/crepe/theme/common/style.css';
|
|
21
|
+
import '@milkdown/crepe/theme/frame-dark.css';
|
|
22
|
+
|
|
23
|
+
const props = defineProps<{ column: any; record: any }>();
|
|
24
|
+
const emit = defineEmits(['update:value']);
|
|
25
|
+
const editorContainer = ref<HTMLElement | null>(null);
|
|
26
|
+
const content = ref(props.record[props.column.name] || '');
|
|
27
|
+
|
|
28
|
+
const isFocused = ref(false);
|
|
29
|
+
|
|
30
|
+
let milkdownInstance: Editor | null = null;
|
|
31
|
+
let crepeInstance: Crepe | null = null;
|
|
32
|
+
|
|
33
|
+
onMounted(async () => {
|
|
34
|
+
if (!editorContainer.value) return;
|
|
35
|
+
try {
|
|
36
|
+
// Milkdown
|
|
37
|
+
// console.log('props.cole', props.column)
|
|
38
|
+
// if (props.column.components.edit.meta.pluginType === 'milkdown' || props.column.components.create.meta.pluginType === 'milkdown') {
|
|
39
|
+
// milkdownInstance = await Editor.make()
|
|
40
|
+
// .config((ctx) => {
|
|
41
|
+
// ctx.set(rootCtx, editorContainer.value!);
|
|
42
|
+
// ctx.set(defaultValueCtx, content.value);
|
|
43
|
+
// ctx.get(listenerCtx).markdownUpdated((_ctx, markdown) => {
|
|
44
|
+
// content.value = markdown;
|
|
45
|
+
// emit('update:value', markdown);
|
|
46
|
+
// });
|
|
47
|
+
// ctx.get(listenerCtx).focus(() => {
|
|
48
|
+
// isFocused.value = true;
|
|
49
|
+
// });
|
|
50
|
+
|
|
51
|
+
// ctx.get(listenerCtx).blur(() => {
|
|
52
|
+
// isFocused.value = false;
|
|
53
|
+
// });
|
|
54
|
+
// })
|
|
55
|
+
// .use(commonmark)
|
|
56
|
+
// .use(gfm)
|
|
57
|
+
// .use(listener)
|
|
58
|
+
// .create();
|
|
59
|
+
|
|
60
|
+
// console.log('Milkdown editor created');
|
|
61
|
+
// }
|
|
62
|
+
|
|
63
|
+
// Crepe
|
|
64
|
+
if (props.column.components.edit.meta.pluginType === 'crepe' || props.column.components.create.meta.pluginType === 'crepe') {
|
|
65
|
+
crepeInstance = await new Crepe({
|
|
66
|
+
root: editorContainer.value,
|
|
67
|
+
defaultValue: content.value,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
crepeInstance.on((listener) => {
|
|
71
|
+
listener.markdownUpdated(() => {
|
|
72
|
+
const markdownContent = crepeInstance.getMarkdown();
|
|
73
|
+
emit('update:value', markdownContent);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
listener.focus(() => {
|
|
77
|
+
isFocused.value = true;
|
|
78
|
+
});
|
|
79
|
+
listener.blur(() => {
|
|
80
|
+
isFocused.value = false;
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
await crepeInstance.create();
|
|
85
|
+
console.log('Crepe editor created');
|
|
86
|
+
}
|
|
87
|
+
} catch (error) {
|
|
88
|
+
console.error('Failed to initialize editor:', error);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
onBeforeUnmount(() => {
|
|
93
|
+
milkdownInstance?.destroy();
|
|
94
|
+
crepeInstance?.destroy();
|
|
95
|
+
console.log('Editor destroyed');
|
|
96
|
+
});
|
|
97
|
+
</script>
|
|
98
|
+
|
|
99
|
+
<style>
|
|
100
|
+
#editor [contenteditable="true"] {
|
|
101
|
+
@apply bg-transparent outline-none border-none shadow-none transition-none min-h-10 p-2 bg-gray-700 dark:placeholder-gray-400;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
#editor [contenteditable="true"].is-focused {
|
|
105
|
+
@apply ring-1 ring-lightPrimary border ring-lightPrimary border-lightPrimary bg-white text-gray-900 dark:ring-darkPrimary dark:border-darkPrimary dark:bg-gray-700 dark:text-white;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
#editor [contenteditable="true"]:not(.is-focused) {
|
|
109
|
+
@apply bg-gray-50 border border-gray-300 text-gray-900 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.milkdown milkdown-slash-menu {
|
|
113
|
+
@apply bg-gray-50 border border-gray-300 text-gray-900 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white z-10;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.milkdown milkdown-slash-menu .menu-groups .menu-group li.hover {
|
|
117
|
+
@apply bg-gray-50 border border-gray-300 text-gray-900 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.milkdown milkdown-slash-menu .tab-group ul li.selected {
|
|
121
|
+
@apply bg-gray-50 border border-gray-300 text-gray-900 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.milkdown-slash-menu .tab-group ul li.selected:hover {
|
|
125
|
+
@apply bg-gray-50 border-gray-300 text-gray-900 dark:bg-gray-700 dark:border-gray-600 dark:text-white;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.milkdown milkdown-code-block {
|
|
129
|
+
@apply bg-gray-50 border border-gray-300 text-gray-900 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.milkdown milkdown-code-block .cm-gutters {
|
|
133
|
+
@apply bg-gray-50 border border-gray-300 text-gray-900 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
</style>
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div v-html="purifiedHtml" class="mdwn"></div>
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script setup lang="ts">
|
|
6
|
+
import { computed } from 'vue';
|
|
7
|
+
import { marked } from "marked";
|
|
8
|
+
import DOMPurify from "dompurify";
|
|
9
|
+
|
|
10
|
+
const props = defineProps<{ column: any; record: any }>();
|
|
11
|
+
|
|
12
|
+
const purifiedHtml = computed(() => {
|
|
13
|
+
|
|
14
|
+
if (!props.record[props.column.name]) return '-';
|
|
15
|
+
const html = marked(String(props.record[props.column.name]));
|
|
16
|
+
if (html instanceof Promise) {
|
|
17
|
+
console.error("Async rendering is not supported in this setup.");
|
|
18
|
+
return '';
|
|
19
|
+
}
|
|
20
|
+
return DOMPurify.sanitize(html);
|
|
21
|
+
});
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<style lang="scss">
|
|
25
|
+
|
|
26
|
+
.mdwn h1 {
|
|
27
|
+
@apply text-2xl font-bold mt-2 mb-2;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.mdwn h2 {
|
|
31
|
+
@apply text-xl font-bold mt-2 mb-2;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.mdwn h3 {
|
|
35
|
+
@apply text-lg font-bold mt-2 mb-2;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.mdwn h4 {
|
|
39
|
+
@apply text-base font-bold mt-2 mb-2;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.mdwn h5 {
|
|
43
|
+
@apply text-sm font-bold mt-2 mb-2;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.mdwn h6 {
|
|
47
|
+
@apply text-xs font-bold mt-2 mb-2;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.mdwn p {
|
|
51
|
+
@apply mb-2 leading-relaxed;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.mdwn ul {
|
|
55
|
+
@apply list-disc pl-5 mb-2;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.mdwn ol {
|
|
59
|
+
@apply list-decimal pl-5 mb-2;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.mdwn li {
|
|
63
|
+
@apply mb-1;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.mdwn blockquote {
|
|
67
|
+
@apply border-l-4 border-gray-300 dark:border-gray-600 pl-4 italic text-gray-600 dark:text-gray-400 mb-2;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.mdwn code {
|
|
71
|
+
@apply bg-gray-100 dark:bg-gray-800 text-red-600 dark:text-red-400 font-mono px-1 py-0.5 rounded;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.mdwn pre {
|
|
75
|
+
@apply bg-gray-100 dark:bg-gray-900 text-sm font-mono p-4 rounded overflow-x-auto mb-2;
|
|
76
|
+
}
|
|
77
|
+
.mdwn pre code {
|
|
78
|
+
@apply bg-transparent p-0 text-inherit;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.mdwn table {
|
|
82
|
+
@apply w-full border-collapse text-left text-sm mb-2;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.mdwn thead {
|
|
86
|
+
@apply bg-gray-100 dark:bg-gray-700;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.mdwn th,
|
|
90
|
+
.mdwn td {
|
|
91
|
+
@apply border border-gray-300 dark:border-gray-700 px-4 py-2;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.mdwn th {
|
|
95
|
+
@apply font-semibold;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.mdwn hr {
|
|
99
|
+
@apply border-t border-gray-300 dark:border-gray-700 my-6;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.mdwn img {
|
|
103
|
+
@apply max-w-full h-auto rounded;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.mdwn a {
|
|
107
|
+
@apply text-blue-600 hover:underline dark:text-blue-400;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
</style>
|