MkCodeのパースエンジンをShikiに変更 (#12102)
* (swap) prism -> shiki * fix styles * (bump) aiscript-vscode to v0.0.5 * refactor * replace prism-editor (beta) * Update scratchpad.vue * (enhance) MkCodeEditor自動インデント改行 * (fix) lint * (add) scratchpad: MkStickyContainer * Update CHANGELOG.md * clean up --------- Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
This commit is contained in:
		
							parent
							
								
									feedad7d8b
								
							
						
					
					
						commit
						1a8243f1ca
					
				|  | @ -24,6 +24,9 @@ | |||
| - Feat: プラグイン・テーマを外部サイトから直接インストールできるようになりました | ||||
| 	- 外部サイトでの実装が必要です。詳細は Misskey Hub をご覧ください | ||||
| 	  https://misskey-hub.net/docs/advanced/publish-on-your-website.html | ||||
| - Enhance: コードのシンタックスハイライトエンジンをShikiに変更 | ||||
|   - AiScriptのシンタックスハイライトに対応 | ||||
|   - MFMでAiScriptをハイライトする場合、コードブロックの開始部分を ` ```is ` もしくは ` ```aiscript ` としてください | ||||
| - Enhance: データセーバー有効時はアニメーション付きのアバター画像が停止するように | ||||
| - Enhance: プラグインを削除した際には、使用されていたアクセストークンも同時に削除されるようになりました | ||||
| - Enhance: プラグインで`Plugin:register_note_view_interruptor`を用いてnoteの代わりにnullを返却することでノートを非表示にできるようになりました | ||||
|  |  | |||
|  | @ -29,6 +29,7 @@ | |||
| 		"@vue/compiler-sfc": "3.3.7", | ||||
| 		"astring": "1.8.6", | ||||
| 		"autosize": "6.0.1", | ||||
| 		"aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.0.5", | ||||
| 		"broadcast-channel": "5.5.1", | ||||
| 		"browser-image-resizer": "github:misskey-dev/browser-image-resizer#v2.2.1-misskey.3", | ||||
| 		"buraha": "0.0.1", | ||||
|  | @ -54,11 +55,11 @@ | |||
| 		"mfm-js": "0.23.3", | ||||
| 		"misskey-js": "workspace:*", | ||||
| 		"photoswipe": "5.4.2", | ||||
| 		"prismjs": "1.29.0", | ||||
| 		"punycode": "2.3.0", | ||||
| 		"querystring": "0.2.1", | ||||
| 		"rollup": "4.1.4", | ||||
| 		"sanitize-html": "2.11.0", | ||||
| 		"shiki": "^0.14.5", | ||||
| 		"sass": "1.69.5", | ||||
| 		"strict-event-emitter-types": "2.0.0", | ||||
| 		"textarea-caret": "3.1.0", | ||||
|  | @ -74,7 +75,6 @@ | |||
| 		"vanilla-tilt": "1.8.1", | ||||
| 		"vite": "4.5.0", | ||||
| 		"vue": "3.3.7", | ||||
| 		"vue-prism-editor": "2.0.0-alpha.2", | ||||
| 		"vuedraggable": "next" | ||||
| 	}, | ||||
| 	"devDependencies": { | ||||
|  |  | |||
|  | @ -5,21 +5,90 @@ SPDX-License-Identifier: AGPL-3.0-only | |||
| 
 | ||||
| <!-- eslint-disable vue/no-v-html --> | ||||
| <template> | ||||
| <code v-if="inline" :class="`language-${prismLang}`" style="overflow-wrap: anywhere;" v-html="html"></code> | ||||
| <pre v-else :class="`language-${prismLang}`"><code :class="`language-${prismLang}`" v-html="html"></code></pre> | ||||
| <div :class="['codeBlockRoot', { 'codeEditor': codeEditor }]" v-html="html"></div> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts" setup> | ||||
| import { computed } from 'vue'; | ||||
| import Prism from 'prismjs'; | ||||
| import 'prismjs/themes/prism-okaidia.css'; | ||||
| import { ref, computed, watch } from 'vue'; | ||||
| import { BUNDLED_LANGUAGES } from 'shiki'; | ||||
| import type { Lang as ShikiLang } from 'shiki'; | ||||
| import { getHighlighter } from '@/scripts/code-highlighter.js'; | ||||
| 
 | ||||
| const props = defineProps<{ | ||||
| 	code: string; | ||||
| 	lang?: string; | ||||
| 	inline?: boolean; | ||||
| 	codeEditor?: boolean; | ||||
| }>(); | ||||
| 
 | ||||
| const prismLang = computed(() => Prism.languages[props.lang] ? props.lang : 'js'); | ||||
| const html = computed(() => Prism.highlight(props.code, Prism.languages[prismLang.value], prismLang.value)); | ||||
| const highlighter = await getHighlighter(); | ||||
| 
 | ||||
| const codeLang = ref<ShikiLang | 'aiscript'>('js'); | ||||
| const html = computed(() => highlighter.codeToHtml(props.code, { | ||||
| 	lang: codeLang.value, | ||||
| 	theme: 'dark-plus', | ||||
| })); | ||||
| 
 | ||||
| async function fetchLanguage(to: string): Promise<void> { | ||||
| 	const language = to as ShikiLang; | ||||
| 
 | ||||
| 	// Check for the loaded languages, and load the language if it's not loaded yet. | ||||
| 	if (!highlighter.getLoadedLanguages().includes(language)) { | ||||
| 		// Check if the language is supported by Shiki | ||||
| 		const bundles = BUNDLED_LANGUAGES.filter((bundle) => { | ||||
| 			// Languages are specified by their id, they can also have aliases (i. e. "js" and "javascript") | ||||
| 			return bundle.id === language || bundle.aliases?.includes(language); | ||||
| 		}); | ||||
| 		if (bundles.length > 0) { | ||||
| 			await highlighter.loadLanguage(language); | ||||
| 			codeLang.value = language; | ||||
| 		} else { | ||||
| 			codeLang.value = 'js'; | ||||
| 		} | ||||
| 	} else { | ||||
| 		codeLang.value = language; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| watch(() => props.lang, (to) => { | ||||
| 	if (codeLang.value === to || !to) return; | ||||
| 	return new Promise((resolve) => { | ||||
| 		fetchLanguage(to).then(() => resolve); | ||||
| 	}); | ||||
| }, { immediate: true, }); | ||||
| </script> | ||||
| 
 | ||||
| <style scoped lang="scss"> | ||||
| .codeBlockRoot :deep(.shiki) { | ||||
| 	padding: 1em; | ||||
| 	margin: .5em 0; | ||||
| 	overflow: auto; | ||||
| 	border-radius: .3em; | ||||
| 
 | ||||
| 	& pre, | ||||
| 	& code { | ||||
| 		font-family: Consolas, Monaco, Andale Mono, Ubuntu Mono, monospace; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| .codeBlockRoot.codeEditor { | ||||
| 	min-width: 100%; | ||||
| 	height: 100%; | ||||
| 
 | ||||
| 	& :deep(.shiki) { | ||||
| 		padding: 12px; | ||||
| 		margin: 0; | ||||
| 		border-radius: 6px; | ||||
| 		min-height: 130px; | ||||
| 		pointer-events: none; | ||||
| 		min-width: calc(100% - 24px); | ||||
| 		height: 100%; | ||||
| 		display: inline-block; | ||||
| 		line-height: 1.5em; | ||||
| 		font-size: 1em; | ||||
| 		overflow: visible; | ||||
| 		text-rendering: inherit; | ||||
|     text-transform: inherit; | ||||
|     white-space: pre; | ||||
| 	} | ||||
| } | ||||
| </style> | ||||
|  |  | |||
|  | @ -4,11 +4,18 @@ SPDX-License-Identifier: AGPL-3.0-only | |||
| --> | ||||
| 
 | ||||
| <template> | ||||
| <XCode :code="code" :lang="lang" :inline="inline"/> | ||||
| 	<Suspense> | ||||
| 		<template #fallback> | ||||
| 			<MkLoading v-if="!inline ?? true" /> | ||||
| 		</template> | ||||
| 		<code v-if="inline" :class="$style.codeInlineRoot">{{ code }}</code> | ||||
| 		<XCode v-else :code="code" :lang="lang"/> | ||||
| 	</Suspense> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts" setup> | ||||
| import { defineAsyncComponent } from 'vue'; | ||||
| import MkLoading from '@/components/global/MkLoading.vue'; | ||||
| 
 | ||||
| defineProps<{ | ||||
| 	code: string; | ||||
|  | @ -18,3 +25,15 @@ defineProps<{ | |||
| 
 | ||||
| const XCode = defineAsyncComponent(() => import('@/components/MkCode.core.vue')); | ||||
| </script> | ||||
| 
 | ||||
| <style module lang="scss"> | ||||
| .codeInlineRoot { | ||||
| 	display: inline-block; | ||||
| 	font-family: Consolas, Monaco, Andale Mono, Ubuntu Mono, monospace; | ||||
| 	overflow-wrap: anywhere; | ||||
| 	color: #D4D4D4; | ||||
| 	background: #1E1E1E; | ||||
| 	padding: .1em; | ||||
| 	border-radius: .3em; | ||||
| } | ||||
| </style> | ||||
|  |  | |||
|  | @ -0,0 +1,166 @@ | |||
| <!-- | ||||
| SPDX-FileCopyrightText: syuilo and other misskey contributors | ||||
| SPDX-License-Identifier: AGPL-3.0-only | ||||
| --> | ||||
| 
 | ||||
| <template> | ||||
| <div :class="[$style.codeEditorRoot, { [$style.disabled]: disabled, [$style.focused]: focused }]"> | ||||
| 	<div :class="$style.codeEditorScroller"> | ||||
| 		<textarea | ||||
| 			ref="inputEl" | ||||
| 			v-model="vModel" | ||||
| 			:class="[$style.textarea]" | ||||
| 			:disabled="disabled" | ||||
| 			:required="required" | ||||
| 			:readonly="readonly" | ||||
| 			autocomplete="off" | ||||
| 			wrap="off" | ||||
| 			spellcheck="false" | ||||
| 			@focus="focused = true" | ||||
| 			@blur="focused = false" | ||||
| 			@keydown="onKeydown($event)" | ||||
| 			@input="onInput" | ||||
| 		></textarea> | ||||
| 		<XCode :class="$style.codeEditorHighlighter" :codeEditor="true" :code="v" :lang="lang"/> | ||||
| 	</div> | ||||
| </div> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts" setup> | ||||
| import { ref, watch, toRefs, shallowRef, nextTick } from 'vue'; | ||||
| import XCode from '@/components/MkCode.core.vue'; | ||||
| 
 | ||||
| const props = withDefaults(defineProps<{ | ||||
| 	modelValue: string | null; | ||||
| 	lang: string; | ||||
| 	required?: boolean; | ||||
| 	readonly?: boolean; | ||||
| 	disabled?: boolean; | ||||
| }>(), { | ||||
| 	lang: 'js', | ||||
| }); | ||||
| 
 | ||||
| const emit = defineEmits<{ | ||||
| 	(ev: 'change', _ev: KeyboardEvent): void; | ||||
| 	(ev: 'keydown', _ev: KeyboardEvent): void; | ||||
| 	(ev: 'enter'): void; | ||||
| 	(ev: 'update:modelValue', value: string): void; | ||||
| }>(); | ||||
| 
 | ||||
| const { modelValue } = toRefs(props); | ||||
| const vModel = ref<string>(modelValue.value ?? ''); | ||||
| const v = ref<string>(modelValue.value ?? ''); | ||||
| const focused = ref(false); | ||||
| const changed = ref(false); | ||||
| const inputEl = shallowRef<HTMLTextAreaElement>(); | ||||
| 
 | ||||
| const onInput = (ev) => { | ||||
| 	v.value = ev.target?.value ?? v.value; | ||||
| 	changed.value = true; | ||||
| 	emit('change', ev); | ||||
| }; | ||||
| 
 | ||||
| const onKeydown = (ev: KeyboardEvent) => { | ||||
| 	if (ev.isComposing || ev.key === 'Process' || ev.keyCode === 229) return; | ||||
| 
 | ||||
| 	emit('keydown', ev); | ||||
| 
 | ||||
| 	if (ev.code === 'Enter') { | ||||
| 		const pos = inputEl.value?.selectionStart ?? 0; | ||||
| 		const posEnd = inputEl.value?.selectionEnd ?? vModel.value.length; | ||||
| 		if (pos === posEnd) { | ||||
| 			const lines = vModel.value.slice(0, pos).split('\n'); | ||||
| 			const currentLine = lines[lines.length - 1]; | ||||
| 			const currentLineSpaces = currentLine.match(/^\s+/); | ||||
| 			const posDelta = currentLineSpaces ? currentLineSpaces[0].length : 0; | ||||
| 			ev.preventDefault(); | ||||
| 			vModel.value = vModel.value.slice(0, pos) + '\n' + (currentLineSpaces ? currentLineSpaces[0] : '') + vModel.value.slice(pos); | ||||
| 			v.value = vModel.value; | ||||
| 			nextTick(() => { | ||||
| 				inputEl.value?.setSelectionRange(pos + 1 + posDelta, pos + 1 + posDelta); | ||||
| 			}); | ||||
| 		} | ||||
| 		emit('enter'); | ||||
| 	} | ||||
| 
 | ||||
| 	if (ev.key === 'Tab') { | ||||
| 		const pos = inputEl.value?.selectionStart ?? 0; | ||||
| 		const posEnd = inputEl.value?.selectionEnd ?? vModel.value.length; | ||||
| 		vModel.value = vModel.value.slice(0, pos) + '\t' + vModel.value.slice(posEnd); | ||||
| 		v.value = vModel.value; | ||||
| 		nextTick(() => { | ||||
| 			inputEl.value?.setSelectionRange(pos + 1, pos + 1); | ||||
| 		}); | ||||
| 		ev.preventDefault(); | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| const updated = () => { | ||||
| 	changed.value = false; | ||||
| 	emit('update:modelValue', v.value); | ||||
| }; | ||||
| 
 | ||||
| watch(modelValue, newValue => { | ||||
| 	v.value = newValue ?? ''; | ||||
| }); | ||||
| 
 | ||||
| watch(v, () => { | ||||
| 	updated(); | ||||
| }); | ||||
| </script> | ||||
| 
 | ||||
| <style lang="scss" module> | ||||
| .codeEditorRoot { | ||||
| 	min-width: 100%; | ||||
| 	max-width: 100%; | ||||
| 	overflow-x: auto; | ||||
| 	overflow-y: hidden; | ||||
| 	box-sizing: border-box; | ||||
| 	margin: 0; | ||||
| 	padding: 0; | ||||
| 	color: var(--fg); | ||||
| 	border: solid 1px var(--panel); | ||||
| 	transition: border-color 0.1s ease-out; | ||||
| 	font-family: Consolas, Monaco, Andale Mono, Ubuntu Mono, monospace; | ||||
| 	&:hover { | ||||
| 		border-color: var(--inputBorderHover) !important; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| .focused.codeEditorRoot { | ||||
| 	border-color: var(--accent) !important; | ||||
| 	border-radius: 6px; | ||||
| } | ||||
| 
 | ||||
| .codeEditorScroller { | ||||
| 	position: relative; | ||||
| 	display: inline-block; | ||||
| 	min-width: 100%; | ||||
| 	height: 100%; | ||||
| } | ||||
| 
 | ||||
| .textarea { | ||||
| 	position: absolute; | ||||
| 	top: 0; | ||||
| 	left: 0; | ||||
| 	right: 0; | ||||
| 	bottom: 0; | ||||
| 	display: inline-block; | ||||
| 	appearance: none; | ||||
| 	resize: none; | ||||
| 	text-align: left; | ||||
| 	color: transparent; | ||||
| 	caret-color: rgb(225, 228, 232); | ||||
| 	background-color: transparent; | ||||
| 	border: 0; | ||||
| 	outline: 0; | ||||
| 	padding: 12px; | ||||
| 	line-height: 1.5em; | ||||
| 	font-size: 1em; | ||||
| 	font-family: Consolas, Monaco, Andale Mono, Ubuntu Mono, monospace; | ||||
| } | ||||
| 
 | ||||
| .textarea::selection { | ||||
| 	color: #fff; | ||||
| } | ||||
| </style> | ||||
|  | @ -36,7 +36,7 @@ SPDX-License-Identifier: AGPL-3.0-only | |||
| 					<template #icon><i class="ti ti-code"></i></template> | ||||
| 					<template #label>{{ i18n.ts._play.viewSource }}</template> | ||||
| 
 | ||||
| 					<MkCode :code="flash.script" :inline="false" class="_monospace"/> | ||||
| 					<MkCode :code="flash.script" lang="is" :inline="false" class="_monospace"/> | ||||
| 				</MkFolder> | ||||
| 				<div :class="$style.footer"> | ||||
| 					<Mfm :text="`By @${flash.user.username}`"/> | ||||
|  |  | |||
|  | @ -4,46 +4,46 @@ SPDX-License-Identifier: AGPL-3.0-only | |||
| --> | ||||
| 
 | ||||
| <template> | ||||
| <MkSpacer :contentMax="800"> | ||||
| 	<div :class="$style.root"> | ||||
| 		<div :class="$style.editor" class="_panel"> | ||||
| 			<PrismEditor v-model="code" class="_monospace" :class="$style.code" :highlight="highlighter" :lineNumbers="false"/> | ||||
| 			<MkButton style="position: absolute; top: 8px; right: 8px;" primary @click="run()"><i class="ti ti-player-play"></i></MkButton> | ||||
| 		</div> | ||||
| <MkStickyContainer> | ||||
| 	<template #header><MkPageHeader/></template> | ||||
| 
 | ||||
| 		<MkContainer v-if="root && components.length > 1" :key="uiKey" :foldable="true"> | ||||
| 			<template #header>UI</template> | ||||
| 			<div :class="$style.ui"> | ||||
| 				<MkAsUi :component="root" :components="components" size="small"/> | ||||
| 	<MkSpacer :contentMax="800"> | ||||
| 		<div :class="$style.root"> | ||||
| 			<div class="_gaps_s"> | ||||
| 				<div :class="$style.editor" class="_panel"> | ||||
| 					<MkCodeEditor v-model="code" lang="aiscript"/> | ||||
| 				</div> | ||||
| 				<MkButton primary @click="run()"><i class="ti ti-player-play"></i></MkButton> | ||||
| 			</div> | ||||
| 		</MkContainer> | ||||
| 
 | ||||
| 		<MkContainer :foldable="true" class=""> | ||||
| 			<template #header>{{ i18n.ts.output }}</template> | ||||
| 			<div :class="$style.logs"> | ||||
| 				<div v-for="log in logs" :key="log.id" class="log" :class="{ print: log.print }">{{ log.text }}</div> | ||||
| 			<MkContainer v-if="root && components.length > 1" :key="uiKey" :foldable="true"> | ||||
| 				<template #header>UI</template> | ||||
| 				<div :class="$style.ui"> | ||||
| 					<MkAsUi :component="root" :components="components" size="small"/> | ||||
| 				</div> | ||||
| 			</MkContainer> | ||||
| 
 | ||||
| 			<MkContainer :foldable="true" class=""> | ||||
| 				<template #header>{{ i18n.ts.output }}</template> | ||||
| 				<div :class="$style.logs"> | ||||
| 					<div v-for="log in logs" :key="log.id" class="log" :class="{ print: log.print }">{{ log.text }}</div> | ||||
| 				</div> | ||||
| 			</MkContainer> | ||||
| 
 | ||||
| 			<div class=""> | ||||
| 				{{ i18n.ts.scratchpadDescription }} | ||||
| 			</div> | ||||
| 		</MkContainer> | ||||
| 
 | ||||
| 		<div class=""> | ||||
| 			{{ i18n.ts.scratchpadDescription }} | ||||
| 		</div> | ||||
| 	</div> | ||||
| </MkSpacer> | ||||
| 	</MkSpacer> | ||||
| </MkStickyContainer> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts" setup> | ||||
| import { onDeactivated, onUnmounted, Ref, ref, watch } from 'vue'; | ||||
| import 'prismjs'; | ||||
| import { highlight, languages } from 'prismjs/components/prism-core'; | ||||
| import 'prismjs/components/prism-clike'; | ||||
| import 'prismjs/components/prism-javascript'; | ||||
| import 'prismjs/themes/prism-okaidia.css'; | ||||
| import { PrismEditor } from 'vue-prism-editor'; | ||||
| import 'vue-prism-editor/dist/prismeditor.min.css'; | ||||
| import { Interpreter, Parser, utils } from '@syuilo/aiscript'; | ||||
| import MkContainer from '@/components/MkContainer.vue'; | ||||
| import MkButton from '@/components/MkButton.vue'; | ||||
| import MkCodeEditor from '@/components/MkCodeEditor.vue'; | ||||
| import { createAiScriptEnv } from '@/scripts/aiscript/api.js'; | ||||
| import * as os from '@/os.js'; | ||||
| import { $i } from '@/account.js'; | ||||
|  | @ -152,10 +152,6 @@ async function run() { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| function highlighter(code) { | ||||
| 	return highlight(code, languages.js, 'javascript'); | ||||
| } | ||||
| 
 | ||||
| onDeactivated(() => { | ||||
| 	if (aiscript) aiscript.abort(); | ||||
| }); | ||||
|  |  | |||
|  | @ -50,7 +50,7 @@ SPDX-License-Identifier: AGPL-3.0-only | |||
| 							<MkButton inline @click="copy(plugin)"><i class="ti ti-copy"></i> {{ i18n.ts.copy }}</MkButton> | ||||
| 						</div> | ||||
| 
 | ||||
| 						<MkCode :code="plugin.src ?? ''"/> | ||||
| 						<MkCode :code="plugin.src ?? ''" lang="is"/> | ||||
| 					</div> | ||||
| 				</MkFolder> | ||||
| 			</div> | ||||
|  |  | |||
|  | @ -0,0 +1,31 @@ | |||
| import { setWasm, setCDN, Highlighter, getHighlighter as _getHighlighter } from 'shiki'; | ||||
| 
 | ||||
| setWasm('/assets/shiki/dist/onig.wasm'); | ||||
| setCDN('/assets/shiki/'); | ||||
| 
 | ||||
| let _highlighter: Highlighter | null = null; | ||||
| 
 | ||||
| export async function getHighlighter(): Promise<Highlighter> { | ||||
| 	if (!_highlighter) { | ||||
| 		return await initHighlighter(); | ||||
| 	} | ||||
| 	return _highlighter; | ||||
| } | ||||
| 
 | ||||
| export async function initHighlighter() { | ||||
| 	const highlighter = await _getHighlighter({ | ||||
| 		theme: 'dark-plus', | ||||
| 		langs: ['js'], | ||||
| 	}); | ||||
| 
 | ||||
| 	await highlighter.loadLanguage({ | ||||
| 		path: 'languages/aiscript.tmLanguage.json', | ||||
| 		id: 'aiscript', | ||||
| 		scopeName: 'source.aiscript', | ||||
| 		aliases: ['is', 'ais'], | ||||
| 	}); | ||||
| 
 | ||||
| 	_highlighter = highlighter; | ||||
| 
 | ||||
| 	return highlighter; | ||||
| } | ||||
|  | @ -400,10 +400,6 @@ hr { | |||
| 	font-family: Fira code, Fira Mono, Consolas, Menlo, Courier, monospace !important; | ||||
| } | ||||
| 
 | ||||
| .prism-editor__textarea:focus { | ||||
| 	outline: none; | ||||
| } | ||||
| 
 | ||||
| ._zoom { | ||||
| 	transition-duration: 0.5s, 0.5s; | ||||
| 	transition-property: opacity, transform; | ||||
|  |  | |||
|  | @ -673,6 +673,9 @@ importers: | |||
|       '@vue/compiler-sfc': | ||||
|         specifier: 3.3.7 | ||||
|         version: 3.3.7 | ||||
|       aiscript-vscode: | ||||
|         specifier: github:aiscript-dev/aiscript-vscode#v0.0.5 | ||||
|         version: github.com/aiscript-dev/aiscript-vscode/a8fa5bb41885391cdb6a6e3165eaa6e4868da86e | ||||
|       astring: | ||||
|         specifier: 1.8.6 | ||||
|         version: 1.8.6 | ||||
|  | @ -754,9 +757,6 @@ importers: | |||
|       photoswipe: | ||||
|         specifier: 5.4.2 | ||||
|         version: 5.4.2 | ||||
|       prismjs: | ||||
|         specifier: 1.29.0 | ||||
|         version: 1.29.0 | ||||
|       punycode: | ||||
|         specifier: 2.3.0 | ||||
|         version: 2.3.0 | ||||
|  | @ -772,6 +772,9 @@ importers: | |||
|       sass: | ||||
|         specifier: 1.69.5 | ||||
|         version: 1.69.5 | ||||
|       shiki: | ||||
|         specifier: ^0.14.5 | ||||
|         version: 0.14.5 | ||||
|       strict-event-emitter-types: | ||||
|         specifier: 2.0.0 | ||||
|         version: 2.0.0 | ||||
|  | @ -814,9 +817,6 @@ importers: | |||
|       vue: | ||||
|         specifier: 3.3.7 | ||||
|         version: 3.3.7(typescript@5.2.2) | ||||
|       vue-prism-editor: | ||||
|         specifier: 2.0.0-alpha.2 | ||||
|         version: 2.0.0-alpha.2(vue@3.3.7) | ||||
|       vuedraggable: | ||||
|         specifier: next | ||||
|         version: 4.1.0(vue@3.3.7) | ||||
|  | @ -871,10 +871,10 @@ importers: | |||
|         version: 7.5.1 | ||||
|       '@storybook/vue3': | ||||
|         specifier: 7.5.1 | ||||
|         version: 7.5.1(@vue/compiler-core@3.3.6)(vue@3.3.7) | ||||
|         version: 7.5.1(@vue/compiler-core@3.3.7)(vue@3.3.7) | ||||
|       '@storybook/vue3-vite': | ||||
|         specifier: 7.5.1 | ||||
|         version: 7.5.1(@vue/compiler-core@3.3.6)(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(vite@4.5.0)(vue@3.3.7) | ||||
|         version: 7.5.1(@vue/compiler-core@3.3.7)(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(vite@4.5.0)(vue@3.3.7) | ||||
|       '@testing-library/vue': | ||||
|         specifier: 7.0.0 | ||||
|         version: 7.0.0(@vue/compiler-sfc@3.3.7)(vue@3.3.7) | ||||
|  | @ -6867,7 +6867,7 @@ packages: | |||
|       file-system-cache: 2.3.0 | ||||
|     dev: true | ||||
| 
 | ||||
|   /@storybook/vue3-vite@7.5.1(@vue/compiler-core@3.3.6)(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(vite@4.5.0)(vue@3.3.7): | ||||
|   /@storybook/vue3-vite@7.5.1(@vue/compiler-core@3.3.7)(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2)(vite@4.5.0)(vue@3.3.7): | ||||
|     resolution: {integrity: sha512-5bO5BactTbyOxxeRw8U6t3FqqfTvVLTefzg1NLDkKt2iAL6lGBSsPTKMgpy3dt+cxdiqEis67niQL68ZtW02Zw==} | ||||
|     engines: {node: ^14.18 || >=16} | ||||
|     peerDependencies: | ||||
|  | @ -6877,7 +6877,7 @@ packages: | |||
|     dependencies: | ||||
|       '@storybook/builder-vite': 7.5.1(typescript@5.2.2)(vite@4.5.0) | ||||
|       '@storybook/core-server': 7.5.1 | ||||
|       '@storybook/vue3': 7.5.1(@vue/compiler-core@3.3.6)(vue@3.3.7) | ||||
|       '@storybook/vue3': 7.5.1(@vue/compiler-core@3.3.7)(vue@3.3.7) | ||||
|       '@vitejs/plugin-vue': 4.4.0(vite@4.5.0)(vue@3.3.7) | ||||
|       magic-string: 0.30.3 | ||||
|       react: 18.2.0 | ||||
|  | @ -6896,7 +6896,7 @@ packages: | |||
|       - vue | ||||
|     dev: true | ||||
| 
 | ||||
|   /@storybook/vue3@7.5.1(@vue/compiler-core@3.3.6)(vue@3.3.7): | ||||
|   /@storybook/vue3@7.5.1(@vue/compiler-core@3.3.7)(vue@3.3.7): | ||||
|     resolution: {integrity: sha512-9srw2rnSYaU45kkunXT8+bX3QMO2QPV6MCWRayKo7Pl+B0H/euHvxPSZb1X8mRpgLtYgVgSNJFoNbk/2Fn8z8g==} | ||||
|     engines: {node: '>=16.0.0'} | ||||
|     peerDependencies: | ||||
|  | @ -6908,7 +6908,7 @@ packages: | |||
|       '@storybook/global': 5.0.0 | ||||
|       '@storybook/preview-api': 7.5.1 | ||||
|       '@storybook/types': 7.5.1 | ||||
|       '@vue/compiler-core': 3.3.6 | ||||
|       '@vue/compiler-core': 3.3.7 | ||||
|       lodash: 4.17.21 | ||||
|       ts-dedent: 2.2.0 | ||||
|       type-fest: 2.19.0 | ||||
|  | @ -8367,15 +8367,6 @@ packages: | |||
|       postcss: 8.4.31 | ||||
|       source-map-js: 1.0.2 | ||||
| 
 | ||||
|   /@vue/compiler-ssr@3.3.6: | ||||
|     resolution: {integrity: sha512-QTIHAfDCHhjXlYGkUg5KH7YwYtdUM1vcFl/FxFDlD6d0nXAmnjizka3HITp8DGudzHndv2PjKVS44vqqy0vP4w==} | ||||
|     requiresBuild: true | ||||
|     dependencies: | ||||
|       '@vue/compiler-dom': 3.3.6 | ||||
|       '@vue/shared': 3.3.6 | ||||
|     dev: true | ||||
|     optional: true | ||||
| 
 | ||||
|   /@vue/compiler-ssr@3.3.7: | ||||
|     resolution: {integrity: sha512-TxOfNVVeH3zgBc82kcUv+emNHo+vKnlRrkv8YvQU5+Y5LJGJwSNzcmLUoxD/dNzv0bhQ/F0s+InlgV0NrApJZg==} | ||||
|     dependencies: | ||||
|  | @ -8428,17 +8419,6 @@ packages: | |||
|       '@vue/shared': 3.3.7 | ||||
|       csstype: 3.1.2 | ||||
| 
 | ||||
|   /@vue/server-renderer@3.3.6(vue@3.3.7): | ||||
|     resolution: {integrity: sha512-kgLoN43W4ERdZ6dpyy+gnk2ZHtcOaIr5Uc/WUP5DRwutgvluzu2pudsZGoD2b7AEJHByUVMa9k6Sho5lLRCykw==} | ||||
|     peerDependencies: | ||||
|       vue: 3.3.6 | ||||
|     dependencies: | ||||
|       '@vue/compiler-ssr': 3.3.6 | ||||
|       '@vue/shared': 3.3.6 | ||||
|       vue: 3.3.7(typescript@5.2.2) | ||||
|     dev: true | ||||
|     optional: true | ||||
| 
 | ||||
|   /@vue/server-renderer@3.3.7(vue@3.3.7): | ||||
|     resolution: {integrity: sha512-UlpKDInd1hIZiNuVVVvLgxpfnSouxKQOSE2bOfQpBuGwxRV/JqqTCyyjXUWiwtVMyeRaZhOYYqntxElk8FhBhw==} | ||||
|     peerDependencies: | ||||
|  | @ -8466,8 +8446,8 @@ packages: | |||
|       js-beautify: 1.14.6 | ||||
|       vue: 3.3.7(typescript@5.2.2) | ||||
|     optionalDependencies: | ||||
|       '@vue/compiler-dom': 3.3.6 | ||||
|       '@vue/server-renderer': 3.3.6(vue@3.3.7) | ||||
|       '@vue/compiler-dom': 3.3.7 | ||||
|       '@vue/server-renderer': 3.3.7(vue@3.3.7) | ||||
|     dev: true | ||||
| 
 | ||||
|   /@webgpu/types@0.1.30: | ||||
|  | @ -8687,6 +8667,10 @@ packages: | |||
|     resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} | ||||
|     engines: {node: '>=12'} | ||||
| 
 | ||||
|   /ansi-sequence-parser@1.1.1: | ||||
|     resolution: {integrity: sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==} | ||||
|     dev: false | ||||
| 
 | ||||
|   /ansi-styles@3.2.1: | ||||
|     resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} | ||||
|     engines: {node: '>=4'} | ||||
|  | @ -13942,7 +13926,6 @@ packages: | |||
| 
 | ||||
|   /jsonc-parser@3.2.0: | ||||
|     resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} | ||||
|     dev: true | ||||
| 
 | ||||
|   /jsonfile@4.0.0: | ||||
|     resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} | ||||
|  | @ -16251,6 +16234,7 @@ packages: | |||
|   /prismjs@1.29.0: | ||||
|     resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==} | ||||
|     engines: {node: '>=6'} | ||||
|     dev: true | ||||
| 
 | ||||
|   /private-ip@2.3.3: | ||||
|     resolution: {integrity: sha512-5zyFfekIVUOTVbL92hc8LJOtE/gyGHeREHkJ2yTyByP8Q2YZVoBqLg3EfYLeF0oVvGqtaEX2t2Qovja0/gStXw==} | ||||
|  | @ -17480,6 +17464,15 @@ packages: | |||
|     resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} | ||||
|     engines: {node: '>=8'} | ||||
| 
 | ||||
|   /shiki@0.14.5: | ||||
|     resolution: {integrity: sha512-1gCAYOcmCFONmErGTrS1fjzJLA7MGZmKzrBNX7apqSwhyITJg2O102uFzXUeBxNnEkDA9vHIKLyeKq0V083vIw==} | ||||
|     dependencies: | ||||
|       ansi-sequence-parser: 1.1.1 | ||||
|       jsonc-parser: 3.2.0 | ||||
|       vscode-oniguruma: 1.7.0 | ||||
|       vscode-textmate: 8.0.0 | ||||
|     dev: false | ||||
| 
 | ||||
|   /side-channel@1.0.4: | ||||
|     resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} | ||||
|     dependencies: | ||||
|  | @ -19232,6 +19225,14 @@ packages: | |||
|     resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} | ||||
|     engines: {node: '>=0.10.0'} | ||||
| 
 | ||||
|   /vscode-oniguruma@1.7.0: | ||||
|     resolution: {integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==} | ||||
|     dev: false | ||||
| 
 | ||||
|   /vscode-textmate@8.0.0: | ||||
|     resolution: {integrity: sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==} | ||||
|     dev: false | ||||
| 
 | ||||
|   /vue-component-type-helpers@1.8.22: | ||||
|     resolution: {integrity: sha512-LK3wJHs3vJxHG292C8cnsRusgyC5SEZDCzDCD01mdE/AoREFMl2tzLRuzwyuEsOIz13tqgBcnvysN3Lxsa14Fw==} | ||||
|     dev: true | ||||
|  | @ -19295,15 +19296,6 @@ packages: | |||
|       vue: 3.3.7(typescript@5.2.2) | ||||
|     dev: true | ||||
| 
 | ||||
|   /vue-prism-editor@2.0.0-alpha.2(vue@3.3.7): | ||||
|     resolution: {integrity: sha512-Gu42ba9nosrE+gJpnAEuEkDMqG9zSUysIR8SdXUw8MQKDjBnnNR9lHC18uOr/ICz7yrA/5c7jHJr9lpElODC7w==} | ||||
|     engines: {node: '>=10'} | ||||
|     peerDependencies: | ||||
|       vue: ^3.0.0 | ||||
|     dependencies: | ||||
|       vue: 3.3.7(typescript@5.2.2) | ||||
|     dev: false | ||||
| 
 | ||||
|   /vue-template-compiler@2.7.14: | ||||
|     resolution: {integrity: sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ==} | ||||
|     dependencies: | ||||
|  | @ -19765,6 +19757,13 @@ packages: | |||
|       readable-stream: 3.6.0 | ||||
|     dev: false | ||||
| 
 | ||||
|   github.com/aiscript-dev/aiscript-vscode/a8fa5bb41885391cdb6a6e3165eaa6e4868da86e: | ||||
|     resolution: {tarball: https://codeload.github.com/aiscript-dev/aiscript-vscode/tar.gz/a8fa5bb41885391cdb6a6e3165eaa6e4868da86e} | ||||
|     name: aiscript-vscode | ||||
|     version: 0.0.5 | ||||
|     engines: {vscode: ^1.83.0} | ||||
|     dev: false | ||||
| 
 | ||||
|   github.com/misskey-dev/browser-image-resizer/0227e860621e55cbed0aabe6dc601096a7748c4a: | ||||
|     resolution: {tarball: https://codeload.github.com/misskey-dev/browser-image-resizer/tar.gz/0227e860621e55cbed0aabe6dc601096a7748c4a} | ||||
|     name: browser-image-resizer | ||||
|  |  | |||
|  | @ -33,6 +33,13 @@ async function copyFrontendLocales() { | |||
|   } | ||||
| } | ||||
| 
 | ||||
| async function copyFrontendShikiAssets() { | ||||
|   await fs.cp('./packages/frontend/node_modules/shiki/dist', './built/_frontend_dist_/shiki/dist', { dereference: true, recursive: true }); | ||||
|   await fs.cp('./packages/frontend/node_modules/shiki/languages', './built/_frontend_dist_/shiki/languages', { dereference: true, recursive: true }); | ||||
|   await fs.cp('./packages/frontend/node_modules/aiscript-vscode/aiscript/syntaxes', './built/_frontend_dist_/shiki/languages', { dereference: true, recursive: true }); | ||||
|   await fs.cp('./packages/frontend/node_modules/shiki/themes', './built/_frontend_dist_/shiki/themes', { dereference: true, recursive: true }); | ||||
| } | ||||
| 
 | ||||
| async function copyBackendViews() { | ||||
|   await fs.cp('./packages/backend/src/server/web/views', './packages/backend/built/server/web/views', { recursive: true }); | ||||
| } | ||||
|  | @ -72,6 +79,7 @@ async function build() { | |||
|     copyFrontendFonts(), | ||||
|     copyFrontendTablerIcons(), | ||||
|     copyFrontendLocales(), | ||||
|     copyFrontendShikiAssets(), | ||||
|     copyBackendViews(), | ||||
|     buildBackendScript(), | ||||
|     buildBackendStyle(), | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue