Merge remote-tracking branch 'misskey-dev/develop' into io
This commit is contained in:
		
							
								
								
									
										127
									
								
								.github/workflows/check-misskey-js-autogen.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								.github/workflows/check-misskey-js-autogen.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,127 @@ | |||||||
|  | name: Check Misskey JS autogen | ||||||
|  |  | ||||||
|  | on: | ||||||
|  |   pull_request: | ||||||
|  |     branches: | ||||||
|  |       - master | ||||||
|  |       - develop | ||||||
|  |     paths: | ||||||
|  |       - packages/backend/** | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |   check-misskey-js-autogen: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     permissions: | ||||||
|  |       pull-requests: write | ||||||
|  |  | ||||||
|  |     env: | ||||||
|  |       api_json_names: "api-base.json api-head.json" | ||||||
|  |  | ||||||
|  |     steps: | ||||||
|  |       - name: checkout | ||||||
|  |         uses: actions/checkout@v4 | ||||||
|  |         with: | ||||||
|  |           submodules: true | ||||||
|  |  | ||||||
|  |       - name: setup pnpm | ||||||
|  |         uses: pnpm/action-setup@v2 | ||||||
|  |         with: | ||||||
|  |           version: 8 | ||||||
|  |  | ||||||
|  |       - name: setup node | ||||||
|  |         id: setup-node | ||||||
|  |         uses: actions/setup-node@v4 | ||||||
|  |         with: | ||||||
|  |           node-version-file: '.node-version' | ||||||
|  |           cache: pnpm | ||||||
|  |  | ||||||
|  |       - name: install dependencies | ||||||
|  |         run: pnpm i --frozen-lockfile | ||||||
|  |  | ||||||
|  |       - name: wait get-api-diff | ||||||
|  |         uses: lewagon/wait-on-check-action@v1.3.3 | ||||||
|  |         with: | ||||||
|  |           ref: ${{ github.event.pull_request.head.sha }} | ||||||
|  |           check-regexp: get-from-misskey .+ | ||||||
|  |           repo-token: ${{ secrets.GITHUB_TOKEN }} | ||||||
|  |           wait-interval: 30 | ||||||
|  |  | ||||||
|  |       - name: Download artifact | ||||||
|  |         uses: actions/github-script@v7 | ||||||
|  |         with: | ||||||
|  |           script: | | ||||||
|  |             const fs = require('fs'); | ||||||
|  |  | ||||||
|  |             const workflows = await github.rest.actions.listWorkflowRunsForRepo({ | ||||||
|  |               owner: context.repo.owner, | ||||||
|  |               repo: context.repo.repo, | ||||||
|  |               head_sha: `${{ github.event.pull_request.head.sha }}` | ||||||
|  |             }).then(x => x.data.workflow_runs); | ||||||
|  |  | ||||||
|  |             console.log(workflows.map(x => ({name: x.name, title: x.display_title}))); | ||||||
|  |  | ||||||
|  |             const run_id = workflows.find(x => x.name.includes("Get api.json from Misskey")).id; | ||||||
|  |  | ||||||
|  |             let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ | ||||||
|  |                owner: context.repo.owner, | ||||||
|  |                repo: context.repo.repo, | ||||||
|  |                run_id: run_id, | ||||||
|  |             }); | ||||||
|  |  | ||||||
|  |             let matchArtifacts = allArtifacts.data.artifacts.filter((artifact) => { | ||||||
|  |               return artifact.name.startsWith("api-artifact-") || artifact.name == "api-artifact" | ||||||
|  |             }); | ||||||
|  |  | ||||||
|  |             await Promise.all(matchArtifacts.map(async (artifact) => { | ||||||
|  |               let download = await github.rest.actions.downloadArtifact({ | ||||||
|  |                 owner: context.repo.owner, | ||||||
|  |                 repo: context.repo.repo, | ||||||
|  |                 artifact_id: artifact.id, | ||||||
|  |                 archive_format: 'zip', | ||||||
|  |               }); | ||||||
|  |               await fs.promises.writeFile(`${process.env.GITHUB_WORKSPACE}/${artifact.name}.zip`, Buffer.from(download.data)); | ||||||
|  |             })); | ||||||
|  |  | ||||||
|  |       - name: unzip artifacts | ||||||
|  |         run: |- | ||||||
|  |           find . -mindepth 1 -maxdepth 1 -type f -name '*.zip' -exec unzip {} -d . ';' | ||||||
|  |           ls -la | ||||||
|  |  | ||||||
|  |       - name: build autogen | ||||||
|  |         run: |- | ||||||
|  |           for name in $(echo $api_json_names) | ||||||
|  |           do | ||||||
|  |             checksum=$(mktemp) | ||||||
|  |             mv $name packages/misskey-js/generator/api.json | ||||||
|  |  | ||||||
|  |             cd packages/misskey-js/generator | ||||||
|  |             pnpm run generate | ||||||
|  |             find built -type f -exec sh -c 'echo $(sed -E "s/^\s+\*\s+generatedAt:.+$//" {} | sha256sum | cut -d" " -f 1) {}' \; > $checksum | ||||||
|  |             cd ../../.. | ||||||
|  |             cp $checksum ${name}_checksum | ||||||
|  |           done | ||||||
|  |  | ||||||
|  |       - name: check update for type definitions | ||||||
|  |         run: diff $(echo -n ${api_json_names} | awk -v RS=" " '{ printf "%s_checksum ", $0 }') | ||||||
|  |  | ||||||
|  |       - name: send message | ||||||
|  |         if: failure() | ||||||
|  |         uses: thollander/actions-comment-pull-request@v2 | ||||||
|  |         with: | ||||||
|  |           comment_tag: check-misskey-js-autogen | ||||||
|  |           message: |- | ||||||
|  |             Thank you for sending us a great Pull Request! 👍 | ||||||
|  |             Please regenerate misskey-js type definitions! 🙏 | ||||||
|  |  | ||||||
|  |             example: | ||||||
|  |             ```sh | ||||||
|  |             pnpm run build-misskey-js-with-types | ||||||
|  |             ``` | ||||||
|  |  | ||||||
|  |       - name: send message | ||||||
|  |         if: success() | ||||||
|  |         uses: thollander/actions-comment-pull-request@v2 | ||||||
|  |         with: | ||||||
|  |           comment_tag: check-misskey-js-autogen | ||||||
|  |           mode: delete | ||||||
|  |           message: "Thank you!" | ||||||
| @@ -28,6 +28,7 @@ | |||||||
| - Enhance: AiScriptを0.17.0に更新 [CHANGELOG](https://github.com/aiscript-dev/aiscript/blob/bb89d132b633a622d3cb0eff0d0cc7e476c0cfdd/CHANGELOG.md) | - Enhance: AiScriptを0.17.0に更新 [CHANGELOG](https://github.com/aiscript-dev/aiscript/blob/bb89d132b633a622d3cb0eff0d0cc7e476c0cfdd/CHANGELOG.md) | ||||||
|   - 配列の範囲外・非整数のインデックスへの代入が完全禁止になるので注意 |   - 配列の範囲外・非整数のインデックスへの代入が完全禁止になるので注意 | ||||||
| - Enhance: 絵文字ピッカー・オートコンプリートで、完全一致した絵文字を優先的に表示するように | - Enhance: 絵文字ピッカー・オートコンプリートで、完全一致した絵文字を優先的に表示するように | ||||||
|  | - Enhance: Playの説明欄にMFMを使えるように | ||||||
| - Fix: ネイティブモードの絵文字がモノクロにならないように | - Fix: ネイティブモードの絵文字がモノクロにならないように | ||||||
| - Fix: v2023.12.0で追加された「モデレーターがユーザーのアイコンもしくはバナー画像を未設定状態にできる機能」が管理画面上で正しく表示されていない問題を修正 | - Fix: v2023.12.0で追加された「モデレーターがユーザーのアイコンもしくはバナー画像を未設定状態にできる機能」が管理画面上で正しく表示されていない問題を修正 | ||||||
| - Fix: AiScriptの`readline`関数が不正な値を返すことがある問題のv2023.12.0時点での修正がPlay以外に適用されていないのを修正 | - Fix: AiScriptの`readline`関数が不正な値を返すことがある問題のv2023.12.0時点での修正がPlay以外に適用されていないのを修正 | ||||||
| @@ -41,6 +42,7 @@ | |||||||
| - Fix: `drive/files/update`でファイル名のバリデーションが機能していない問題を修正 | - Fix: `drive/files/update`でファイル名のバリデーションが機能していない問題を修正 | ||||||
| - Fix: `notes/create`で、`text`が空白文字のみで構成されているか`null`であって、かつ`text`だけであるリクエストに対するレスポンスが400になるように変更 | - Fix: `notes/create`で、`text`が空白文字のみで構成されているか`null`であって、かつ`text`だけであるリクエストに対するレスポンスが400になるように変更 | ||||||
| - Fix: `notes/create`で、`text`が空白文字のみで構成されていてかつリノート、ファイルまたは投票を含んでいるリクエストに対するレスポンスの`text`が`""`から`null`になるように変更 | - Fix: `notes/create`で、`text`が空白文字のみで構成されていてかつリノート、ファイルまたは投票を含んでいるリクエストに対するレスポンスの`text`が`""`から`null`になるように変更 | ||||||
|  | - Fix: ipv4とipv6の両方が利用可能な環境でallowedPrivateNetworksが設定されていた場合プライベートipの検証ができていなかった問題を修正 | ||||||
|  |  | ||||||
| ## 2023.12.2 | ## 2023.12.2 | ||||||
|  |  | ||||||
|   | |||||||
| @@ -145,7 +145,8 @@ export class DownloadService { | |||||||
| 		const parsedIp = ipaddr.parse(ip); | 		const parsedIp = ipaddr.parse(ip); | ||||||
|  |  | ||||||
| 		for (const net of this.config.allowedPrivateNetworks ?? []) { | 		for (const net of this.config.allowedPrivateNetworks ?? []) { | ||||||
| 			if (parsedIp.match(ipaddr.parseCIDR(net))) { | 			const cidr = ipaddr.parseCIDR(net); | ||||||
|  | 			if (cidr[0].kind() === parsedIp.kind() && parsedIp.match(ipaddr.parseCIDR(net))) { | ||||||
| 				return false; | 				return false; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -9,7 +9,9 @@ SPDX-License-Identifier: AGPL-3.0-only | |||||||
| 		<header> | 		<header> | ||||||
| 			<h1 :title="flash.title">{{ flash.title }}</h1> | 			<h1 :title="flash.title">{{ flash.title }}</h1> | ||||||
| 		</header> | 		</header> | ||||||
| 		<p v-if="flash.summary" :title="flash.summary">{{ flash.summary.length > 85 ? flash.summary.slice(0, 85) + '…' : flash.summary }}</p> | 		<p v-if="flash.summary" :title="flash.summary"> | ||||||
|  | 			<Mfm class="summaryMfm" :text="flash.summary" :plain="true" :nowrap="true"/> | ||||||
|  | 		</p> | ||||||
| 		<footer> | 		<footer> | ||||||
| 			<img class="icon" :src="flash.user.avatarUrl"/> | 			<img class="icon" :src="flash.user.avatarUrl"/> | ||||||
| 			<p>{{ userName(flash.user) }}</p> | 			<p>{{ userName(flash.user) }}</p> | ||||||
| @@ -54,6 +56,12 @@ const props = defineProps<{ | |||||||
| 			margin: 0; | 			margin: 0; | ||||||
| 			color: var(--urlPreviewText); | 			color: var(--urlPreviewText); | ||||||
| 			font-size: 0.8em; | 			font-size: 0.8em; | ||||||
|  | 			overflow: clip; | ||||||
|  |  | ||||||
|  | 			> .summaryMfm { | ||||||
|  | 				display: block; | ||||||
|  | 				width: 100%; | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		> footer { | 		> footer { | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ SPDX-License-Identifier: AGPL-3.0-only | |||||||
| 			<MkInput v-model="title"> | 			<MkInput v-model="title"> | ||||||
| 				<template #label>{{ i18n.ts._play.title }}</template> | 				<template #label>{{ i18n.ts._play.title }}</template> | ||||||
| 			</MkInput> | 			</MkInput> | ||||||
| 			<MkTextarea v-model="summary"> | 			<MkTextarea v-model="summary" :mfmAutocomplete="true" :mfmPreview="true"> | ||||||
| 				<template #label>{{ i18n.ts._play.summary }}</template> | 				<template #label>{{ i18n.ts._play.summary }}</template> | ||||||
| 			</MkTextarea> | 			</MkTextarea> | ||||||
| 			<MkButton primary @click="selectPreset">{{ i18n.ts.selectFromPresets }}<i class="ti ti-chevron-down"></i></MkButton> | 			<MkButton primary @click="selectPreset">{{ i18n.ts.selectFromPresets }}<i class="ti ti-chevron-down"></i></MkButton> | ||||||
|   | |||||||
| @@ -25,7 +25,7 @@ SPDX-License-Identifier: AGPL-3.0-only | |||||||
| 					<div v-else :class="$style.ready"> | 					<div v-else :class="$style.ready"> | ||||||
| 						<div class="_panel main"> | 						<div class="_panel main"> | ||||||
| 							<div class="title">{{ flash.title }}</div> | 							<div class="title">{{ flash.title }}</div> | ||||||
| 							<div class="summary">{{ flash.summary }}</div> | 							<div class="summary"><Mfm :text="flash.summary"/></div> | ||||||
| 							<MkButton class="start" gradate rounded large @click="start">Play</MkButton> | 							<MkButton class="start" gradate rounded large @click="start">Play</MkButton> | ||||||
| 							<div class="info"> | 							<div class="info"> | ||||||
| 								<span v-tooltip="i18n.ts.numberOfLikes"><i class="ti ti-heart"></i> {{ flash.likedCount }}</span> | 								<span v-tooltip="i18n.ts.numberOfLikes"><i class="ti ti-heart"></i> {{ flash.likedCount }}</span> | ||||||
|   | |||||||
| @@ -207,9 +207,11 @@ SPDX-License-Identifier: AGPL-3.0-only | |||||||
| 		<div class="_gaps"> | 		<div class="_gaps"> | ||||||
| 			<MkFolder> | 			<MkFolder> | ||||||
| 				<template #label>{{ i18n.ts.additionalEmojiDictionary }}</template> | 				<template #label>{{ i18n.ts.additionalEmojiDictionary }}</template> | ||||||
| 				<div v-for="lang in emojiIndexLangs" class="_buttons"> | 				<div class="_buttons"> | ||||||
| 					<MkButton @click="downloadEmojiIndex(lang)"><i class="ti ti-download"></i> {{ lang }}{{ defaultStore.reactiveState.additionalUnicodeEmojiIndexes.value[lang] ? ` (${ i18n.ts.installed })` : '' }}</MkButton> | 					<template v-for="lang in emojiIndexLangs" :key="lang"> | ||||||
| 					<MkButton v-if="defaultStore.reactiveState.additionalUnicodeEmojiIndexes.value[lang]" danger @click="removeEmojiIndex(lang)"><i class="ti ti-trash"></i> {{ i18n.ts.remove }}</MkButton> | 						<MkButton v-if="defaultStore.reactiveState.additionalUnicodeEmojiIndexes.value[lang]" danger @click="removeEmojiIndex(lang)"><i class="ti ti-trash"></i> {{ i18n.ts.remove }} ({{ getEmojiIndexLangName(lang) }})</MkButton> | ||||||
|  | 						<MkButton v-else @click="downloadEmojiIndex(lang)"><i class="ti ti-download"></i> {{ getEmojiIndexLangName(lang) }}{{ defaultStore.reactiveState.additionalUnicodeEmojiIndexes.value[lang] ? ` (${ i18n.ts.installed })` : '' }}</MkButton> | ||||||
|  | 					</template> | ||||||
| 				</div> | 				</div> | ||||||
| 			</MkFolder> | 			</MkFolder> | ||||||
| 			<FormLink to="/settings/deck">{{ i18n.ts.deck }}</FormLink> | 			<FormLink to="/settings/deck">{{ i18n.ts.deck }}</FormLink> | ||||||
| @@ -341,15 +343,29 @@ watch([ | |||||||
| 	await reloadAsk(); | 	await reloadAsk(); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| const emojiIndexLangs = ['en-US']; | const emojiIndexLangs = ['en-US', 'ja-JP', 'ja-JP_hira'] as const; | ||||||
|  |  | ||||||
| function downloadEmojiIndex(lang: string) { | function getEmojiIndexLangName(targetLang: typeof emojiIndexLangs[number]) { | ||||||
|  | 	if (langs.find(x => x[0] === targetLang)) { | ||||||
|  | 		return langs.find(x => x[0] === targetLang)![1]; | ||||||
|  | 	} else { | ||||||
|  | 		// 絵文字辞書限定の言語定義 | ||||||
|  | 		switch (targetLang) { | ||||||
|  | 			case 'ja-JP_hira': return 'ひらがな'; | ||||||
|  | 			default: return targetLang; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function downloadEmojiIndex(lang: typeof emojiIndexLangs[number]) { | ||||||
| 	async function main() { | 	async function main() { | ||||||
| 		const currentIndexes = defaultStore.state.additionalUnicodeEmojiIndexes; | 		const currentIndexes = defaultStore.state.additionalUnicodeEmojiIndexes; | ||||||
|  |  | ||||||
| 		function download() { | 		function download() { | ||||||
| 			switch (lang) { | 			switch (lang) { | ||||||
| 				case 'en-US': return import('../../unicode-emoji-indexes/en-US.json').then(x => x.default); | 				case 'en-US': return import('../../unicode-emoji-indexes/en-US.json').then(x => x.default); | ||||||
|  | 				case 'ja-JP': return import('../../unicode-emoji-indexes/ja-JP.json').then(x => x.default); | ||||||
|  | 				case 'ja-JP_hira': return import('../../unicode-emoji-indexes/ja-JP_hira.json').then(x => x.default); | ||||||
| 				default: throw new Error('unrecognized lang: ' + lang); | 				default: throw new Error('unrecognized lang: ' + lang); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|   | |||||||
							
								
								
									
										1865
									
								
								packages/frontend/src/unicode-emoji-indexes/ja-JP.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1865
									
								
								packages/frontend/src/unicode-emoji-indexes/ja-JP.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1865
									
								
								packages/frontend/src/unicode-emoji-indexes/ja-JP_hira.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1865
									
								
								packages/frontend/src/unicode-emoji-indexes/ja-JP_hira.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user
	 まっちゃとーにゅ
					まっちゃとーにゅ